Xpra-org / xpra

Persistent remote applications for X11; screen sharing for X11, MacOS and MSWindows.
https://xpra.org/
GNU General Public License v2.0
1.97k stars 169 forks source link

GL acceleration for client rendering #147

Closed totaam closed 11 years ago

totaam commented 12 years ago

Issue migrated from trac ticket # 147

component: client | priority: major | resolution: fixed | keywords: GL

2012-06-16 07:52:48: antoine created the issue


(remaining) tasks:

  • provide a GL client window alternative to the standard gtk window, so OpenGL can take care of colourspace conversion, done in r922
  • urgent: fix vpx (ahuillet)
  • support all encodings (ie: mmap, jpeg and png)
  • do_expose_event isn't called automatically - fix it
  • fallback to non-GL rendering when PyOpenGL is not installed, or when the GL driver is blacklisted (or not whitelisted)
  • win32 build: we need to document how to build everything from scratch

Changes required from commit r922:

  • whitespace cleanup
  • remove wildcard imports
  • remove unused variables
  • constify GL command string
  • do not use SystemExit
  • why does this crash python??:
    python -c "from OpenGL.GL import glGetString, GL_VERSION; glGetString(GL_VERSION)"
  • remove duplicated window backing code: separate GL (backing) from window code - and re-use backing (super)class if needed. GLWindowBacking is not used??
  • use booleans and not integers (ie: vtxarrays - not used?)
  • use_openGL_CSC is hardcoded, make it a switch? Needs testing too.
  • self.current_mode and self.textures, need documenting more clearly, and initializing in constructor?
  • restore nogil for decompress_image_to_rgb: csc_image_yuv2rgb does not need the gil
  • run automated tests to compare with more scenarios

Contingency plan: we can disable the opengl code if this proves unstable or problematic.

Note:

  • with local connections, it might even be possible for the server to render directly to the client window? (even faster than mmap)
totaam commented 12 years ago

2012-06-16 08:31:09: antoine commented


r924 and r925 deal with:

  • splitting the GL code into separate files: gl_window_backing.py should be used or removed altogether
  • disable loading of GL code by default as this causes crashes, see USE_OPENGL=False in client.py
  • constifying gl-colorspace-conversions MIT licensed code in its own file
  • fix whitespace
  • remove wildcard imports
  • remove unused variables
  • remove use of SystemExit
totaam commented 12 years ago

As for the win32 build, here are some pointers:

totaam commented 12 years ago

r926 fixes vpx for non-gl case

totaam commented 12 years ago

2012-06-16 14:19:38: ahuillet commented


Sorry for not taking care of the cleanup myself, it was on my plans but you beat me to it. As for the python crash, your piece of code doesn't crash in my case - however it's not going to work because you can't issue OpenGL commands outside of a GL context. This means that you can check the GL version before actually having created a GL-enabled widget, which is why I didn't do the check in the constructor.

totaam commented 12 years ago

2012-06-17 14:59:17: antoine commented


  • non-gl fix for vpx, see r926
  • we no longer hold the gil when not needed, see r927
  • version check removed in r928, then re-enabled during early module load but with proper gl_begin/gl_end around it to avoid crashes, see r929. We also check for FragmentProgramARB
  • use_openGL_CSC is now toggled depending on the availability of FragmentProgramARB, in r930 - this will need more thorough testing (toggling it by hand to test these codepaths)

Which leaves (recap):

  • fix vpx (partial patch available)
  • blacklisting or whitelisting of opengl backends
  • win32 build: we need to document how to build everything from scratch
  • separate GL (backing) from GL window code (as per regular non-gl classes) - and re-use backing (super)class. (probably rename GLWindowBacking to GLBacking)
  • "No GL output for mmap", jpeg, png... (should be made easier by item just above)
  • padding issues in #146
  • self.current_mode and self.textures, need documenting more clearly (and constifying?), and initializing in constructor?
  • "FIXME: We use single buffer because double doesn't work, figure out why"
  • run automated tests to compare with more scenarios
  • crash in #150
  • do_expose_event isn't called automatically - fix it
totaam commented 12 years ago

2012-06-17 15:01:20: antoine uploaded file xpra-vpx-gl.patch (8.5 KiB)

fixing vpx to allow it to work with yuv/opengl codepath (work in progress patch)

totaam commented 12 years ago

2012-06-18 09:58:58: ahuillet commented


  • Vpx fixed in r931
  • double buffer isn't actually needed so we can drop this issue
  • current_mode is meant to be initialized to 0 (you don't know if it's YUV or RGB mode at start). textures can't be initialized because you need a GL context to call glGenTextures
totaam commented 12 years ago

2012-06-19 04:59:34: antoine commented


More:

  • x264 fix in r932
  • some docstrings in r933
  • win32 build fix in r934
  • debian/ebuild/setup.py Cython version requirements bumped to 0.16 in r935
  • patches updated to the new offsets in r936
  • packages should now pull opengl bits (if available for this platform), done in r937 (avoid stacktrace by pulling dep we don't need in r940 ...)
  • fixed initialization of current_mode in r938
  • tidy up in r943 and constification in r944
totaam commented 12 years ago

2012-06-22 12:15:48: antoine commented


New recap:

  • blacklisting or whitelisting of opengl backends - not needed?
  • provide a "--no-opengl" switch
  • win32 build: we need to document how to build everything from scratch
  • separate GL (backing) from GL window code
  • "No GL output for mmap", jpeg, png...
  • padding issues in #146
  • crash in #150
  • do_expose_event isn't called automatically
  • use_openGL_CSC = False : test it thoroughly
totaam commented 12 years ago

2012-06-25 12:14:03: antoine uploaded file opengl-vs-gtk-clientcpu.svg (48.9 KiB)

compare cpu usage with opengl and gtk

totaam commented 12 years ago

2012-06-25 12:17:11: antoine uploaded file opengl-vs-gtk-pixelsdecodedpersecond.svg (49.5 KiB)

comparing pixels decoded per second with opengl and gtk

totaam commented 12 years ago

2012-06-25 12:23:16: antoine uploaded file opengl-vs-gtk-fps.svg (36.5 KiB)

comparing FPS with opengl and gtk

totaam commented 12 years ago

2012-06-25 12:26:56: antoine uploaded file opengl-vs-gtk-avgclientlatency.svg (35.8 KiB)

comparing average client UI thread latency with opengl and gtk

totaam commented 12 years ago

2012-06-25 12:29:28: antoine commented


As can be seen here (user cpu + sys cpu): [[Image(https://www.xpra.org/trac/raw-attachment/ticket/147/opengl-vs-gtk-clientcpu.svg)]] The CPU usage is noticeably lower with the opengl backend, which is impressive seeing that it is also pushing more frames: [[Image(https://www.xpra.org/trac/raw-attachment/ticket/147/opengl-vs-gtk-fps.svg)]] (some pathological tests samples were removed)

We decode + paint much faster (pixels per second): [[Image(https://www.xpra.org/trac/raw-attachment/ticket/147/opengl-vs-gtk-pixelsdecodedpersecond.svg)]]

Which in turn reduces the average UI thread latency: [[Image(https://www.xpra.org/trac/raw-attachment/ticket/147/opengl-vs-gtk-avgclientlatency.svg)]]

totaam commented 12 years ago

2012-10-31 07:02:41: antoine commented


r2008 updates the gl code so it compiles/runs again

totaam commented 12 years ago

2012-10-31 07:12:55: antoine commented


r2009 fixes the calls from UI thread so rendering actually works

totaam commented 12 years ago

2012-10-31 08:40:00: antoine commented


r2010 fixes support for all csc modes with x264 decoding

totaam commented 12 years ago

2012-10-31 11:42:11: antoine uploaded file gl-rgb24.patch (8.9 KiB)

better gl patch

totaam commented 12 years ago

2012-10-31 15:26:13: antoine commented


Mostly working as of r2018: we now handle lossless updates too.

New recap of pending items:

  • provide a "--no-opengl" switch: no, will use XPRA_OPENGL env var to control (and make GL the default if possible/stable enough)
  • win32 build: we need to document how to build everything from scratch
  • when we process a lossless update, we lose the ability to process expose events until the next lossless update..
  • somewhere in gtkgl prints out empty log lines - try to get rid of it or get it fixed
  • do we leak memory? "glGenPrograms we call in the YUV420 setup, so we need to do cleanup otherwise next time we call it we're leaking the first"
totaam commented 12 years ago

2012-11-01 08:40:26: antoine commented


Unfortunately, gtkgl is no-go on osx because it relies on the x11 bindings:

In file included from gdkglquery-x11.c:27:
gdkglx.h:22:22: error: gdk/gdkx.h: No such file or directory
gdkglquery-x11.c: In function 'gdk_gl_query_extension':
gdkglquery-x11.c:51: warning: implicit declaration of function 'gdk_x11_get_default_xdisplay'
(...)

The sad thing is that PyOpenGL and PyOpenGL_accelerate do build ok, so all we really need is the glue... one solution would be to bypass gtkgl completely.

totaam commented 12 years ago

2012-11-01 09:03:45: antoine commented


On win32, although there are some really old binaries of gtkglext version 1.0.6 on sourceforge, the latest binary python bindings available are for python 2.3!

So it looks like we will just have to build from source... (which is generally a major PITA on win32)

totaam commented 12 years ago

2012-11-01 11:33:56: antoine commented


this all-in-one installer does have gtkglext, but it is way too old (based on gtk 2.17, etc)

Now, trying with MinGW using these home made instructions:

cd gtkglext-1.2.0/
export PATH=/c/Python27/Lib/site-packages/gtk-2.0/runtime/bin/:$PATH
export PKG_CONFIG_PATH=/c/Python27/Lib/site-packages/gtk-2.0/runtime/lib/pkgconfig/
export PATH=/c/MinGW/bin:$PATH
env CC='gcc' \
    AR=/c/cygwin/bin/ar.exe \
    ./configure --prefix=/c/gtkglext --build=i386-pc-mingw32 --disable-static

fails with:

gtkglwidget.c: In function 'gtk_gl_widget_size_allocate':
gtkglwidget.c:130:3: warning: implicit declaration of function 'GTK_WIDGET_REALIZED'
gtkglwidget.c: In function 'gtk_gl_widget_parent_set':
gtkglwidget.c:177:3: warning: implicit declaration of function 'GTK_WIDGET_TOPLEVEL'
gtkglwidget.c: In function 'gtk_widget_set_gl_capability':
gtkglwidget.c:253:3: warning: implicit declaration of function 'GTK_WIDGET_NO_WINDOW'

/bin/sh ../libtool --mode=link gcc -march=pentium  -g -O2 -Wall -mms-bitfields  \
    -o libgtkglext-win32-1.0.la  -version-info 0:0:0 -export-dynamic -rpath /c/gtkglext/lib \
    -no-undefined -export-symbols gtkglext.def  gtkglversion.lo gtkglinit.lo gtkglwidget.lo \
    ../gdk/libgdkglext-win32-1.0.la -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32 \
    -Lc:/Python27/Lib/site-packages/gtk-2.0/runtime/lib -lgtk-win32-2.0 -lgdk-win32-2.0 \
    -latk-1.0 -lgio-2.0 -lpangowin32-1.0 -lgdi32 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lpango-1.0 \
    -lcairo -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl    
if test "x`/bin/sed 1q gtkglext.def`" = xEXPORTS; then
    cp gtkglext.def .libs/libgtkglext-win32-1.0-0.dll.def;
else
    echo EXPORTS > .libs/libgtkglext-win32-1.0-0.dll.def;
    cat gtkglext.def >> .libs/libgtkglext-win32-1.0-0.dll.def;
fi
gcc -march=pentium -shared .libs/libgtkglext-win32-1.0-0.dll.def  .libs/gtkglversion.o \ 
    .libs/gtkglinit.o .libs/gtkglwidget.o  -Lc:/mingw/bin/../lib/gcc/mingw32/4.5.2/../../..//.libs \
    ../gdk/.libs/libgdkglext-win32-1.0.dll.a -Lc:/Python27/Lib/site-packages/gtk-2.0/runtime/lib \
    -L/mingw/lib -lglu32 -lopengl32 -luser32 -lkernel32 -lgtk-win32-2.0 -lgdk-win32-2.0 \
    -latk-1.0 -lgio-2.0 -lpangowin32-1.0 -lgdi32 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lpango-1.0 \
    -lcairo -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 \
    c:/mingw/bin/../lib/gcc/mingw32/4.5.2/../../..//libintl.dll.a  -march=pentium -mms-bitfields \
    -o .libs/libgtkglext-win32-1.0-0.dll -Wl,--enable-auto-image-base -Xlinker --out-implib \
    -Xlinker .libs/libgtkglext-win32-1.0.dll.a

Creating library file: \
  .libs/libgtkglext-win32-1.0.dll.a.libs/gtkglwidget.o: In function `gtk_gl_widget_size_allocate':
e:\gtkglext-1.2.0\gtk/gtkglwidget.c:130: undefined reference to `GTK_WIDGET_REALIZED'
.libs/gtkglwidget.o: In function `gtk_gl_widget_unrealize':
(...)
totaam commented 12 years ago

2012-11-01 14:03:25: antoine commented


This was solved by replacing:

GTK_WIDGET_REALIZED

with

gtk_widget_get_realized

Makes me think that maybe we ought to try with the latest unreleased source which has those changes already...

Now onto pygtkglext:

export PATH=/c/Python27/Lib/site-packages/gtk-2.0/runtime/bin:$PATH
export PKG_CONFIG_PATH=/c/Python27/Lib/pkgconfig/
export PATH=/c/MinGW/:$PATH

(why the pkgconfig for pygtk and some other bits is one place and gtk in another... beats me) Then you have to comment out the line:

from override import Overrides

And you still get a build error... :

/c/Python/python.exe ./setup.py build
running build
running build_py
running build_ext
building 'gtk.gdkgl._gdkgl' extension
C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\cl.exe /c /nologo /Ox /MD /W3 /GS- \
  /DNDEBUG \
  -DPYGTKGLEXT_MAJOR_VERSION=1 -DPYGTKGLEXT_MINOR_VERSION=1 -DPYGTKGLEXT_MICRO_VERSION=0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/gtkglext-1.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/lib/gtkglext-1.0/include \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/gtk-2.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/lib/gtk-2.0/include \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/pango-1.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/gdk-pixbuf-2.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/glib-2.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/lib/glib-2.0/include \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/cairo \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/freetype2 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/libpng14 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/atk-1.0 \
  -I. -Igtk/gdkgl -Igtk/gtkgl -Ic:/Python27/include/pygtk-2.0 \
  -Ic:/Python27/include/pygtk-2.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/glib-2.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/lib/glib-2.0/include \
  -Ic:\Python27\include -Ic:\Python27\PC \
  /Tcgtk/gdkgl/gdkglmodule.c /Fobuild\temp.win32-2.7\Release\gtk/gdkgl/gdkglmodule.obj
gdkglmodule.c
C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\cl.exe /c /nologo /Ox /MD /W3 /GS- \
  /DNDEBUG \
  -DPYGTKGLEXT_MAJOR_VERSION=1 -DPYGTKGLEXT_MINOR_VERSION=1 -DPYGTKGLEXT_MICRO_VERSION=0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/gtkglext-1.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/lib/gtkglext-1.0/include \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/gtk-2.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/lib/gtk-2.0/include \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/pango-1.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/gdk-pixbuf-2.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/glib-2.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/lib/glib-2.0/include \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/cairo \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/freetype2 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/libpng14 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/atk-1.0 \
  -I. -Igtk/gdkgl -Igtk/gtkgl \
  -Ic:/Python27/include/pygtk-2.0 \
  -Ic:/Python27/include/pygtk-2.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/include/glib-2.0 \
  -Ic:/Python27/lib/site-packages/gtk-2.0/runtime/lib/glib-2.0/include \
  -Ic:\Python27\include \
  -Ic:\Python27\PC \
  /Tcgtk/gdkgl/gdkglext.c /Fobuild\temp.win32-2.7\Release\gtk/gdkgl/gdkglext.obj
gdkglext.c
C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\link.exe /DLL /nologo /INCREMENTAL:NO \
  /LIBPATH:c:/Python27/lib/site-packages/gtk-2.0/runtime/lib \
  /LIBPATH:c:/Python27/lib/site-packages/gtk-2.0/runtime/lib \
  /LIBPATH:c:\Python27\libs \
  /LIBPATH:c:\Python27\PCbuild \
  gtkglext-win32-1.0.lib gdkglext-win32-1.0.lib glu32.lib opengl32.lib user32.lib kernel32.lib \
  gtk-win32-2.0.lib gdk-win32-2.0.lib atk-1.0.lib gio-2.0.lib pangowin32-1.0.lib gdi32.lib \
  pangocairo-1.0.lib gdk_pixbuf-2.0.lib pango-1.0.lib cairo.lib gobject-2.0.lib gmodule-2.0.lib \
  gthread-2.0.lib glib-2.0.lib intl.lib gobject-2.0.lib gthread-2.0.lib glib-2.0.lib intl.lib \
  /EXPORT:init_gdkgl \
  build\temp.win32-2.7\Release\gtk/gdkgl/gdkglmodule.obj \
  build\temp.win32-2.7\Release\gtk/gdkgl/gdkglext.obj\
  /OUT:build\lib.win32-2.7\gtk\gdkgl\_gdkgl.pyd \
  /IMPLIB:build\temp.win32-2.7\Release\gtk/gdkgl\_gdkgl.lib \
  /MANIFESTFILE:build\temp.win32-2.7\Release\gtk/gdkgl\_gdkgl.pyd.manifest
LINK : fatal error LNK1181: cannot open input file 'gtkglext-win32-1.0.lib'
totaam commented 12 years ago

2012-11-01 16:49:39: antoine commented


Next, we try to go back to gtkglext and add --enable-debug, --enable-shared and --enable-static, which then causes more problems (..) so we have to modify gtkglwidget.c:

  • replace GTK_WIDGET_TOPLEVEL by gtk_widget_is_toplevel
  • just comment out the GTK_GL_NOTE ... lines in gtk_gl_widget_style_set
  • replace GTK_WIDGET_NO_WINDOW by gtk_widget_get_has_window FWIW: I'm not sure if the instructions above make any difference, but this is how I got it to build.

And then, we remember to actually follow some of the instructions (doh) and add --compiler="mingw32" to the setup.py command... And then it builds OK.

But that is not the end of our troubles, it doesn't install:

running install
running build
running build_py
running build_ext
running install_lib
Traceback (most recent call last):
  File "./setup.py", line 159, in <module>
    'build_ext': BuildExt })
  File "c:\Python27\lib\distutils\core.py", line 152, in setup
    dist.run_commands()
  File "c:\Python27\lib\distutils\dist.py", line 953, in run_commands
    self.run_command(cmd)
  File "c:\Python27\lib\distutils\dist.py", line 972, in run_command
    cmd_obj.run()
  File "c:\Python27\lib\distutils\command\install.py", line 575, in run
    self.run_command(cmd_name)
  File "c:\Python27\lib\distutils\cmd.py", line 326, in run_command
    self.distribution.run_command(command)
  File "c:\Python27\lib\distutils\dist.py", line 972, in run_command
    cmd_obj.run()
  File "./setup.py", line 61, in run
    self.add_template_option('VERSION', VERSION)
  File "c:\Python27\lib\distutils\cmd.py", line 105, in __getattr__
    raise AttributeError, attr
AttributeError: add_template_option

And judging by postings on the subject, there is no easy way to fix that. So we don't bother and just install manually by copying:

pygtkglext-1.1.0\build\lib.win32-2.7\gtk\*

to

Python27\Lib\site-packages\gtk-2.0\gtk\

We now have gtkgl/gdkgl installed! (albeit without the pkgconfig file, etc)

Next, we have a packaging problem with py2exe not including all the bits we need for PyOpenGL, fortunately the solution is documented here. Unfortunately, those don't work properly, and one can find a multitude of different ways of solving this problem... (1(*), 2, 3, 4, 5) with various levels of non-success: I'm not the only one running around in circles :( We also have to go through the egg unpacking dance for OpenGL_accelerate..


And then I find that some osx support code has been added to gtkglext trunk after the last release... so maybe we can have opengl rendering on osx after all..

totaam commented 12 years ago

2012-11-02 10:22:41: antoine commented


Note: the problems above with py2exe may or may not be real. What is real though is the fact that I cannot use pixmaps with pygtkglext.. (so packaging is a moot point) - even just running the examples I get:

(python.exe:2224): GdkGLExt-WARNING **: cannot select DIB
(python.exe:2224): GdkGLExt-WARNING **: cannot create GdkGLPixmap

I've tried building from trunk ('git://git.gnome.org/gtkglext') and from another tree I found ([https://github.com/tdz/gtkglext.git]) - natively with mingw and cross compiling from Linux. Both fail, the instructions are just rubbish, not up to date, and refer to non-existent files (autogen.sh etc).


I also found a more recent binary version of gtkglext here - but unfortunately this does not help and GL pixmaps still fail.

I also found these instructions - not tried them yet.


I am not the first one to hit this issue:

Will try with VMWare or a real windows PC, unless someone beats me to it.


Here's how (assuming a dev environment with pygtk and mingw installed and working):

  • install PyOpenGL: "C:\Python27\scripts\easy-install.exe PyOpenGL"
  • use this gtkglext installer (or see comment:20 to build from source) and copy the installation dir this creates (by default: C:\GtkGLExt) to pygtk's runtime directory (by default: C:\Python27\Lib\site-packages\gtk-2.0\runtime)
  • build pygtkglext-1.1.0.tar.gz with /c/Python/python.exe ./setup.py build --compiler="mingw32" ('see comment:20 for the overrides error fix') and copy the resulting pygtkglext-1.1.0\build\lib.win32-2.7\gtk\* to Python27\Lib\site-packages\gtk-2.0\gtk\
  • run the pixbuf examples: /c/Python27/python.exe pixmap.py - does it work or not? warnings shown?
totaam commented 12 years ago

2012-11-03 09:49:44: antoine uploaded file gl-frozen-path.patch (2.7 KiB)

if we do manage to get opengl working on win32, this deals with opengl libraries located in the frozen path

totaam commented 11 years ago

2012-12-21 14:48:37: antoine commented


Finally working very well on *nix:

  • see fixes in #150
  • r2332 fixes the last blocker
  • r2333 enables OpenGL by default when available
  • r2331 avoids warnings if we have installed --without-opengl

Only win32 left...

totaam commented 11 years ago

2012-12-22 10:34:29: antoine commented


closing, see #226 for osx and #227 for win32

totaam commented 11 years ago

2012-12-24 16:39:50: antoine commented


re-opening:

  • r2332 breaks radeon and does not work reliably with nouveau driver: nouveau does not support multiple gl contexts at the moment
  • r2336 partially fixes radeon, but we still get screen corruption in video/yuv mode (also true with nvidia)
  • current trunk does not work with nvidia driver at all (rgb broken, yuv buggy/stops)
  • need to test intel, etc and whitelist/blacklist those that do work
  • when we resize the window up, the expose event seems to paint random chunks of memory into the missing space... clip it
  • expose events do not work with nvidia after an rgb update: we set pixel_format to rgb and the render_image shortcuts out (works on radeon for some strange reason)
  • figure out why opengl logs empty lines to the logfile and make it stfu
totaam commented 11 years ago

2012-12-24 16:40:40: antoine uploaded file gl_window_backing.py (10.5 KiB)

work in progress to make it work with nvidia driver.. not too far

totaam commented 11 years ago

2012-12-25 11:45:16: antoine commented


changesets r2342, r2343, r2344, r2345, r2346, r2347, r2350, r2353, r2354, r2355, r2356, r2357 fix a number of bugs listed above and improve error/corner cases. It now works on:

  • radeon (Radeon HD 5450)
  • fglrx (Radeon HD 5450)
  • intel (GM965/GL960 Integrated Graphics Controller)
  • nvidia (GeForce GTS 450) - but with a bug: expose does not work
  • nouveau (GeForce GTS 450) - but with a bug: expose does not work

Summary of remaining issues:

  • occasional weird frame with no apparent cause (looks sort of black&white - seen mostly on intel with glxgears)
  • nvidia/nouveau expose events do not work - it is quite strange that it works for all the others...
  • re-doing the whole fragment program init everytime is wasteful, we should be able to load it up once and glEnable, glDisable it when needed by paint_rgb24 (see example code attached which almost works)
  • occasional destroy_program_variants_cb warning (see r2327) - maybe we do need to call remove_shader on the cleanup path
  • win32 crash: #229
totaam commented 11 years ago

2012-12-27 07:46:49: antoine uploaded file gl_window_backing.2.py (11.6 KiB)

version which creates the fragment program only once and uses glEnable / glDisable

totaam commented 11 years ago

2013-01-02 11:07:01: antoine commented


Got a GL crash with nvidia on Linux:

(gdb) py-bt
#14 Frame 0x2637170, for file /usr/lib/python2.7/site-packages/OpenGL/wrapper.py, line 784, in wrapperCall (args=(<IntConstant at remote 0x1c80320>, 0, 0, 0, 958, 526, <IntConstant at remote 0x188fb40>, <IntConstant at remote 0x1284d20>, '\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\...(truncated)
    result = self.wrappedOperation( *cArguments )
#19 Frame 0x2636500, for file /usr/lib/python2.7/site-packages/OpenGL/latebind.py, line 41, in __call__ (self=<glTexSubImage2D(pyConverterNames=['target', 'level', 'xoffset', 'yoffset', 'width', 'height', 'format', 'type', 'pixels'], pyConverters=[None, None, <function at remote 0x1a58aa0>, <function at remote 0x1a58aa0>, <function at remote 0x1a58aa0>, <function at remote 0x1a58aa0>, None, None, <ImageInputConverter(typeName='type', pixelsIndex=8, pixelsName='pixels', typeIndex=7, rank=3) at remote 0x1a4ee90>], _finalCall=<function at remote 0x2294938>) at remote 0x1a59440>, args=(<IntConstant at remote 0x1c80320>, 0, 0, 0, 958, 526, <IntConstant at remote 0x188fb40>, <IntConstant at remote 0x1284d20>, '\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x...(truncated)
    return self._finalCall( *args, **named )
#29 (frame information optimized out)
#32 Frame 0x7f1f30004e60, for file /usr/lib64/python2.7/site-packages/xpra/gl/gl_window_backing.py, line 193, in do_gl_paint (self=<GLPixmapBacking(textures=<numpy.ndarray at remote 0x24bfeb0>, _last_pixmap_data=(639, 102, 5230, '\x00\n\x10\x00\n\x10\x00\n\x10\x00\n\x10\x00\n\x10\x00\n\x10\x00\n\x10\x00\n\x10\x00\x08\x0e\x00\x08\x0e\x00\x08\x0e\x00\x08\x0e\x00\x08\x0e\x00\x08\x0e\x00\x08\x0e\x00\x08\x0e\x00\x08\x10\x00\x08\x10\x00\x07\x10\x00\x07\x10\x00\x07\x10\x00\x07\x10\x00\x07\x10\x00\x07\x10\x01\t\x12\x01\t\x12\x01\t\x12\x00\x07\x10\x00\x07\x10\x00\x07\x10\x00\x07\x10\x00\x07\x10\x01\t\x12\x00\x07\x10\x00\x08\x0e\x00\x08\x0e\x00\x07\x0e\x00\x07\x0e\x00\x07\x0e\x00\x07\x0e\x00\x06\r\x00\x06\r\x00\x06\r\x00\x06\r\x00\x06\r\x00\x06\r\x00\x06\r\x00\x06\r\x00\x06\r\x00\x05\x0c\x00\x05\x0e\x00\x05\x0e\x00\x05\x0e\x00\x05\x0e\x00\x05\x0e\x00\x06\x0f\x00\x06\x0f\x00\x06\x0f\x00\x06\x0f\x00\x06\x0f\x00\x06\x0f\x00\x06\x0f\x00\x07\x0f\x00\x07\x0f\x00\x05\x11\x00\x05\x11\x00\x05\x11\x00\x06\x12\x00\x06\x12\x00\x06\x12...(truncated)
    self.update_texture_yuv(img_data, x, y, w, h, rowstrides, pixel_format)
#46 (frame information optimized out)
#49 Frame 0x9a3b50, for file /usr/lib64/python2.7/site-packages/xpra/scripts/main.py, line 769, in run_client (parser=<OptionParser(process_default_values=True, allow_interspersed_args=True, _long_opt={'--delay-tray': <Option(_long_opts=['--delay-tray'], help='Waits for the first events before showing the system tray', callback_args=None, callback=None, default=False, nargs=None, choices=None, dest='delay_tray', container=<OptionGroup(_long_opt={...}, title='Client Features Options', parser=<...>, _short_opt={'-d': <Option(_long_opts=['--debug'], help='List of categories to enable debugging for (or "all")', callback_args=None, callback=None, default=None, nargs=1, choices=None, dest='debug', container=<OptionGroup(_long_opt={...}, title='Advanced Options', parser=<...>, _short_opt={...}, option_list=[<Option(_long_opts=['--password-file'], help='The file containing the password required to connect (useful to secure TCP mode)', callback_args=None, callback=None, default=None, nargs=1, choices=None, dest='password_...(truncated)
    return app.run()
#53 Frame 0x818c50, for file /usr/lib64/python2.7/site-packages/xpra/scripts/main.py, line 501, in main (script_file='/usr/bin/xpra', cmdline=['/usr/bin/xpra', 'attach', ':10', '--no-mmap', '--encoding=x264'], bool_default=<function at remote 0x7f1f46dca848>, int_default=<function at remote 0x7f1f46dca938>, float_default=<function at remote 0x7f1f46dca9b0>, string_list=<function at remote 0x7f1f46dcaa28>, supports_server=True, wait_for_x_server=<built-in function wait_for_x_server>, start_str='\t%prog start DISPLAY\n', list_str='\t%prog list\n', upgrade_str='\t%prog upgrade DISPLAY', shadow_str='\t%prog upgrade DISPLAY', note_str='', stop_str='\t%prog stop [DISPLAY]\n', parser=<OptionParser(process_default_values=True, allow_interspersed_args=True, _long_opt={'--delay-tray': <Option(_long_opts=['--delay-tray'], help='Waits for the first events before showing the system tray', callback_args=None, callback=None, default=False, nargs=None, choices=None, dest='delay_tray', container=<OptionGroup(_long_opt={...}, titl...(truncated)
    return run_client(parser, options, args, mode)
#57 Frame 0x818770, for file /usr/bin/xpra, line 6, in <module> ()
    sys.exit(xpra.scripts.main.main(__file__, sys.argv))

Full backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x000000319d7e3e78 in ?? () from /usr/lib64/nvidia/libnvidia-glcore.so.304.64
(gdb) bt
#0  0x000000319d7e3e78 in ?? () from /usr/lib64/nvidia/libnvidia-glcore.so.304.64
#1  0x000000319d492456 in ?? () from /usr/lib64/nvidia/libnvidia-glcore.so.304.64
#2  0x000000319d49c59a in ?? () from /usr/lib64/nvidia/libnvidia-glcore.so.304.64
#3  0x000000319d5913ee in ?? () from /usr/lib64/nvidia/libnvidia-glcore.so.304.64
#4  0x000000319d586737 in ?? () from /usr/lib64/nvidia/libnvidia-glcore.so.304.64
#5  0x000000319d589b98 in ?? () from /usr/lib64/nvidia/libnvidia-glcore.so.304.64
#6  0x000000319d58a107 in ?? () from /usr/lib64/nvidia/libnvidia-glcore.so.304.64
#7  0x0000003564a05ed8 in ffi_call_unix64 () at ../src/x86/unix64.S:75
#8  0x0000003564a058e0 in ffi_call (cif=cif@entry=0x7fff2060e040, fn=fn@entry=0x319baf9120 <glTexSubImage2D>, rvalue=rvalue@entry=0x7fff2060de90, avalue=avalue@entry=0x7fff2060de30)
    at ../src/x86/ffi64.c:486
#9  0x00007f1f48197bf0 in _call_function_pointer (argcount=9, resmem=0x7fff2060de90, restype=<optimized out>, atypes=<optimized out>, avalues=0x7fff2060de30, pProc=
    0x319baf9120 <glTexSubImage2D>, flags=4353) at /usr/src/debug/Python-2.7.3/Modules/_ctypes/callproc.c:827
#10 _ctypes_callproc (pProc=pProc@entry=0x319baf9120 <glTexSubImage2D>, argtuple=argtuple@entry=
    (<IntConstant at remote 0x1c80320>, 0, 0, 0, 958, 526, <IntConstant at remote 0x188fb40>, <IntConstant at remote 0x1284d20>, '\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x...(truncated), flags=4353, argtypes=argtypes@entry=
    (<built-in method from_param of _ctypes.PyCSimpleType object at remote 0x9503c0>, <built-in method from_param of _ctypes.PyCSimpleType object at remote 0x94f110>, <built-in method from_param of _ctypes.PyCSimpleType object at remote 0x94f110>, <built-in method from_param of _ctypes.PyCSimpleType object at remote 0x94f110>, <built-in method from_param of _ctypes.PyCSimpleType object at remote 0x94f110>, <built-in method from_param of _ctypes.PyCSimpleType object at remote 0x94f110>, <built-in method from_param of _ctypes.PyCSimpleType object at remote 0x9503c0>, <built-in method from_param of _ctypes.PyCSimpleType object at remote 0x9503c0>, <instancemethod at remote 0x193aaa0>), restype=None, checker=0x0)
    at /usr/src/debug/Python-2.7.3/Modules/_ctypes/callproc.c:1174
#11 0x00007f1f481913fd in PyCFuncPtr_call (self=<optimized out>, inargs=<optimized out>, kwds=0x0) at /usr/src/debug/Python-2.7.3/Modules/_ctypes/_ctypes.c:3913
#12 0x0000003561e49c0e in PyObject_Call (func=func@entry=
    <CFunctionType(extension=None, deprecated=False, argNames=['target', 'level', 'xoffset', 'yoffset', 'width', 'height', 'format', 'type', 'pixels'], DLL=<CDLL(_FuncPtr=<_ctypes.PyCFuncPtrType at remote 0x125cad0>, glGetString=<_FuncPtr(__name__='glGetString', __doc__='glGetString( constant ) -> Current string value') at remote 0x1949a10>, glXGetCurrentContext=<_FuncPtr(__name__='glXGetCurrentContext') at remote 0xdb0ef0>, _handle=10160672, _name='libGL.so.1', glXGetProcAddressARB=<_FuncPtr(__name__='glXGetProcAddressARB') at remote 0xdb0d50>, glGetError=<_FuncPtr(__name__='glGetError') at remote 0x1286050>) at remote 0x123ac50>, __name__='glTexSubImage2D', __doc__='glTexSubImage2D( GLenum(target), GLint(level), GLint(xoffset), GLint(yoffset), GLsizei(width), GLsizei(height), GLenum(format), GLenum(type), POINTER(GLvoid)(pixels) ) -> None') at remote 0x19481f0>, arg=<optimized out>, kw=kw@entry=0x0)
    at /usr/src/debug/Python-2.7.3/Objects/abstract.c:2529
#13 0x0000003561eda08b in ext_do_call (nk=0, na=<optimized out>, flags=<optimized out>, pp_stack=0x7fff2060e358, func=
    <CFunctionType(extension=None, deprecated=False, argNames=['target', 'level', 'xoffset', 'yoffset', 'width', 'height', 'format', 'type', 'pixels'], DLL=<CDLL(_FuncPtr=<_ctypes.PyCFuncPtrType at remote 0x125cad0>, glGetString=<_FuncPtr(__name__='glGetString', __doc__='glGetString( constant ) -> Current string value') at remote 0x1949a10>, glXGetCurrentContext=<_FuncPtr(__name__='glXGetCurrentContext') at remote 0xdb0ef0>, _handle=10160672, _name='libGL.so.1', glXGetProcAddressARB=<_FuncPtr(__name__='glXGetProcAddressARB') at remote 0xdb0d50>, glGetError=<_FuncPtr(__name__='glGetError') at remote 0x1286050>) at remote 0x123ac50>, __name__='glTexSubImage2D', __doc__='glTexSubImage2D( GLenum(target), GLint(level), GLint(xoffset), GLint(yoffset), GLsizei(width), GLsizei(height), GLenum(format), GLenum(type), POINTER(GLvoid)(pixels) ) -> None') at remote 0x19481f0>) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4411
#14 PyEval_EvalFrameEx (f=f@entry=
    Frame 0x2637170, for file /usr/lib/python2.7/site-packages/OpenGL/wrapper.py, line 784, in wrapperCall (args=(<IntConstant at remote 0x1c80320>, 0, 0, 0, 958, 526, <IntConstant at remote 0x188fb40>, <IntConstant at remote 0x1284d20>, '\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\...(truncated), throwflag=throwflag@entry=0)
    at /usr/src/debug/Python-2.7.3/Python/ceval.c:2779
#15 0x0000003561eddcbf in PyEval_EvalCodeEx (co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x27580f0, argcount=9, kws=kws@entry=0x7f1f5135d068, 
    kwcount=kwcount@entry=0, defs=defs@entry=0x0, defcount=defcount@entry=0, closure=(<cell at remote 0x22956e0>, <cell at remote 0x22957f8>))
    at /usr/src/debug/Python-2.7.3/Python/ceval.c:3330
#16 0x0000003561e6da37 in function_call (func=<function at remote 0x2294938>, arg=
    (<IntConstant at remote 0x1c80320>, 0, 0, 0, 958, 526, <IntConstant at remote 0x188fb40>, <IntConstant at remote 0x1284d20>, '\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x...(truncated), kw={}) at /usr/src/debug/Python-2.7.3/Objects/funcobject.c:526
#17 0x0000003561e49c0e in PyObject_Call (func=func@entry=<function at remote 0x2294938>, arg=<optimized out>, kw=kw@entry={}) at /usr/src/debug/Python-2.7.3/Objects/abstract.c:2529
#18 0x0000003561eda08b in ext_do_call (nk=0, na=<optimized out>, flags=<optimized out>, pp_stack=0x7fff2060e6d8, func=<function at remote 0x2294938>)
    at /usr/src/debug/Python-2.7.3/Python/ceval.c:4411
#19 PyEval_EvalFrameEx (f=f@entry=
    Frame 0x2636500, for file /usr/lib/python2.7/site-packages/OpenGL/latebind.py, line 41, in __call__ (self=<glTexSubImage2D(pyConverterNames=['target', 'level', 'xoffset', 'yoffset', ---Type <return> to continue, or q <return> to quit---
'width', 'height', 'format', 'type', 'pixels'], pyConverters=[None, None, <function at remote 0x1a58aa0>, <function at remote 0x1a58aa0>, <function at remote 0x1a58aa0>, <function at remote 0x1a58aa0>, None, None, <ImageInputConverter(typeName='type', pixelsIndex=8, pixelsName='pixels', typeIndex=7, rank=3) at remote 0x1a4ee90>], _finalCall=<function at remote 0x2294938>) at remote 0x1a59440>, args=(<IntConstant at remote 0x1c80320>, 0, 0, 0, 958, 526, <IntConstant at remote 0x188fb40>, <IntConstant at remote 0x1284d20>, '\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x...(truncated), throwflag=throwflag@entry=0)
    at /usr/src/debug/Python-2.7.3/Python/ceval.c:2779
totaam commented 11 years ago

We still need to pass small region updates as YUV data instead of RGB...

totaam commented 11 years ago

2013-02-19 17:52:46: ahuillet commented


After our private discussions - I believe we should be able to draw to the Pixmap using the "normal" draw commands.

Something like the patch below is the general idea - but it doesn't work.

--- a/src/xpra/gl/gl_window_backing.py
+++ b/src/xpra/gl/gl_window_backing.py
@@ -133,6 +133,10 @@ class GLPixmapBacking(PixmapBacking):
                 self.gl_end(drawable)

     def _do_paint_rgb24(self, img_data, x, y, w, h, rowstride, options, callbacks):
+        gc = self._backing.new_gc()
+        self._backing.draw_rgb_image(gc, x, y, w, h, gdk.RGB_DITHER_NONE, img_data, rowstride)
+        fire_paint_callbacks(callbacks, True)
+        return
         log("do_paint_rgb24(%s bytes, %s, %s, %s, %s, %s, %s, %s)", len(img_data), x, y, w, h, rowstride, options, callbacks)
         ww, wh = self.size
         if x+w>ww or y+h>wh:

EDIT: actually, the following patch seems to do what we expect :

--- a/src/xpra/gl/gl_window_backing.py
+++ b/src/xpra/gl/gl_window_backing.py
@@ -133,6 +133,9 @@ class GLPixmapBacking(PixmapBacking):
                 self.gl_end(drawable)

     def _do_paint_rgb24(self, img_data, x, y, w, h, rowstride, options, callbacks):
+        gc = self.glarea.window.new_gc()
+        self.glarea.window.draw_rgb_image(gc, x, y, w, h, gdk.RGB_DITHER_NONE, img_data, rowstride)
+        return
         log("do_paint_rgb24(%s bytes, %s, %s, %s, %s, %s, %s, %s)", len(img_data), x, y, w, h, rowstride, options, callbacks)
         ww, wh = self.size
         if x+w>ww or y+h>wh:

Will you please test, confirm, and cleanup?

Thanks!

totaam commented 11 years ago

2013-02-25 16:25:58: antoine commented


applied in r2793 - Linux rendering works well enough and may be enabled by default (again!) in 0.9 release, win32 will need (a lot) more testing

totaam commented 11 years ago

2013-02-26 09:59:58: antoine commented


Does not work with more than one window because we re-use the same textures/shader. :(

Testing with nouveau and the following patch:

--- src/xpra/gl/gl_window_backing.py  (revision 2793)
+++ src/xpra/gl/gl_window_backing.py  (working copy)
@@ -85,6 +86,7 @@
             glDisable(GL_FRAGMENT_PROGRAM_ARB)
             if self.textures is None:
                 self.textures = glGenTextures(3)
+                log.info("textures for wid=%s of size %s : %s", self.wid, self.size, self.textures)
             self.gl_setup = True
         return drawable

Then starting two windows, I see with the nouveau driver:

textures for wid=4 of size (529, 303) : [1 2 3]
textures for wid=9 of size (499, 316) : [1 2 3]

So it looks like the texture IDs returned by glGenTextures are the same...

totaam commented 11 years ago

2013-03-12 14:40:52: ahuillet commented


It is expected that the textures IDs will be the same, since we're running in different contexts.

Now it's possible that either Gtk or the driver itself (but my money is against Gtk) is mixing up the contexts somehow, and effectively not giving us different textures for different windows. So what we have to do is the following: call glGenTextures once, at startup, for say 1000 textures, and store the resulting array somewhere. The array will be 1 2 3 4 5 ... 1000, so we can also forget about glGenTextures completely. Then, we need an internal texture broker, that we ask for a free texture ID. That way we'll be using different texture IDs, which may work around the problem.

As long as we're using the same shader - and we are - all the time, I think the texture IDs are the only problem.

totaam commented 11 years ago

2013-03-12 15:22:49: antoine commented


With r2941, it looks pretty good with fglrx, except for this when we close a window (we probably should check the window isn't gone already before or at the very least after):

Traceback (most recent call last):
  File "xpra/gl/gl_window_backing.py", line 169, in do_gl_paint
    self.render_image(x, y, x+w, y+h)
  File "xpra/gl/gl_window_backing.py", line 256, in render_image
    glEnd()
  File "OpenGL/latebind.py", line 61, in __call__
    return self.wrapperFunction( self.baseFunction, *args, **named )
  File "OpenGL/GL/exceptional.py", line 57, in glEnd
    return baseFunction( )
  File "OpenGL/error.py", line 208, in glCheckError
    baseOperation = baseOperation,
GLError: GLError(
  err = 1282,
  description = 'invalid operation',
  baseOperation = glEnd,
  cArguments = ()
)
totaam commented 11 years ago

2013-03-13 07:51:54: ahuillet commented


r2947 fixes GL_INVALID_OPERATION after closing a window - we were deleting the shader in the wrong GL context. r2948 sets FRAGMENT_PROGRAM_ARB to enabled by default as we always use a shader now (since RGB rendering is done via straight gtk) r2949 fixes strange colorplanes behavior or downright crashes due to incorrect CSC 422 texture sizes

totaam commented 11 years ago

closing, follow up in #229