xpra icon
Bug tracker and wiki

Opened 7 years ago

Closed 7 years ago

Last modified 2 years ago

#227 closed task (fixed)

opengl rendering on win32

Reported by: Antoine Martin Owned by: Antoine Martin
Priority: major Milestone: 0.9
Component: client Version: trunk
Keywords: Cc:

Description (last modified by Antoine Martin)

split from #147 (see also #226 for osx)

There are no official (py)gtkglext win32 builds available from gnome, trying various binary builds always leads to the same problem:

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

See ticket:147#comment:22
The problem is that all of those binary builds are well out of date - and completely undocumented. Not at all helpful for debugging things.


So we need to build from source, either:

  • using mingw32 (alternative instructions in PDF attached to this ticket)
  • cross-compiling using mingw32, this seems more popular - but a major hassle when straying outside the usual/expected dependencies (and we have a few)

ming32 native build
Unless otherwise stated, the configure step generally looks like this:

./configure --prefix=/mingw --build=mingw32

Often with --disable-gtk-doc added if possible.

  • zlib can be built from source (with the caveat from the instructions above about libz.dll.a missing..)
  • pkg-config and glib have a circular dependency which means you are better off installing binaries from gnome (yuk)
  • and then you might as well grab all of them from there: cairo, freetype, expat, gettext, libxml2, fontconfig, pixman, cairo
  • as we will find out later on, there is no point in grabbing libffi (for building glib) since the binary archives are missing the pkg-config file... (and hacking one by hand is just asking for more trouble)
  • then you want to grab: gdk-pixbuf, atk. We can use more gnome binaries for this..
  • then you need gtk-doc to build gtkglext and you cannot find an official one for win32 anywhere, and building from source obviously fails too - oh joy. And so the "recommended" way (judging from some mailing list posts) of dealing with this is to install a fake one - I'm not joking, see gtk-doc-stub. (again totally undocumented, even there)
  • then you get an error telling you that gtk is not installed... sure it is. That's because pango's pkg-config files aren't installed. So you must build pango from source to get them.
  • but when you try to install pango from source, it complains that glib isn't the right version. And it isn't. That's because the binaries are well out of date. So now we have to build glib too, despite using binaries in the first steps.. (oh well, at least we have pkg-config installed now..)
  • and to build glib, we need libffi, and as mentioned above, the binaries are incomplete, so we have to build that from source as well (see How to compile glib using MingW under Windows) - alternatively, we could use those magic environment variables to tell it where to find libffi - I didn't go down that route.
  • and then glib complains about needing "-march=i486" or later, but how? Well, through CFLAGS of course (!):
    export CFLAGS="-march=i686"
    ./configure --prefix=/mingw --build=mingw32 \
            --with-pcre=internal --with-threads=win32 --disable-gtk-doc
    

(which makes me think we should probably build everything with the same CFLAGS, oh well.. next time?)

  • then the build proceeds.. for a while, until you get:
      GEN      gdbus-example-objectmanager-generated.h
    /usr/bin/env: python2.5: No such file or directory
    make[6]: *** [gdbus-example-objectmanager-generated.h] Error 127
    make[6]: Leaving directory `/home/XP_Pro/glib-2.35.3/gio/tests/gdbus-object-mana
    ger-example'
    

So it grabbed the wrong version of Python and not the one we have installed (how could it..), and since Python does not build on MingW, we have to point it to the version we want it to use (and hope for the best when it comes to mixing compilers...):

export PYTHON=C:\Python2.7\Python.exe
./configure (...)
  • then we need cairo to build pango with the features we need, at least there is a build documentation page available
  • and cairo needs pixman and libpng.. (at this point you can be forgiven for thinking that this will never end)
  • building cairo then fails with:
    In file included from c:\mingw\bin\../lib/gcc/mingw32/4.7.2/../../../../include/
    stdio.h:534:0,
                     from cairo-missing.h:36,
                     from strndup.c:31:
    c:\mingw\bin\../lib/gcc/mingw32/4.7.2/../../../../include/sys/types.h:118:18:
            note: previous declaration of 'ssize_t' was here
    make[4]: *** [strndup.lo] Error 1
    

As per this mailing list post (which has a workaround)

  • then we can build pango.

Note: ideally, we would like to have librsvg support, but this would also require building: pangocairo (a cycle!?), gdk-pixbuf and libcroco... meh.

  • then we can finally try to build gtkglext with
    ./configure --prefix=/mingw --build=mingw32 \
            --disable-gtk-doc --with-gdktarget=win32
    

which then fails with:

font-pangoft2.c:14:28: fatal error: pango/pangoft2.h:
        No such file or directory compilation terminated.
make[2]: *** [font_pangoft2-font-pangoft2.o] Error 1

Looks like we do need freetype after all, which must be built before cairo apparently..

  • install freetype, rebuild cairo, rebuild pango, then try again
  • it *should* now build (mostly)... but don't run the examples if you don't want your machine to crash (or maybe it is just virtualbox?).

Rant: why is this such a horrible mess?


ming32 cross build
Useful link: Building GTK apps for MS Windows on Linux

  • install all the required mingw libraries for your distro (gcc and friends) - details are out of scope
  • install the mingw gtk versions (hopefully your distro has them... again, not covered here)
  • build gtkglext (fix things with ranlib when needed then continue - setting a RANLIB env var does not help):
    export PREFIX=/usr/i686-w64-mingw32/sys-root/mingw/
    export TARGET=mingw32
    export PKG_CONFIG_PATH=$PREFIX/$TARGET/lib/pkgconfig
    export PATH=$PREFIX/bin:$PREFIX/$TARGET/bin:/bin:/usr/bin
    export LD_LIBRARY_PATH=$PREFIX/$TARGET/lib
    export LDFLAGS=-L$PREFIX/$TARGET/lib
    export OBJDUMP=/usr/i686-w64-mingw32/bin/objdump
    export CC="/usr/bin/i686-w64-mingw32-gcc -mms-bitfields"
    export CXX="/usr/bin/i686-w64-mingw32-c++ -mms-bitfields"
    export CFLAGS="-O2 -march=i586 -mms-bitfields"
    export CXXFLAGS="-O2 -march=i586 -mms-bitfields"
    autoreconf -iv
    ./configure --host=i686-pc-mingw32 --prefix=$PREFIX/$TARGET
    make
    /usr/i686-w64-mingw32/bin/ranlib ./gdk/.libs/libgdkglext-win32-1.0.a
    make
    /usr/i686-w64-mingw32/bin/ranlib ./gtk/.libs/libgtkglext-win32-1.0.a
    make
    /usr/i686-w64-mingw32/bin/ranlib ./examples/.libs/libdrawshapes.a
    make
    

then we're stuck because there is no way to build python with mingw... although there are instructions for cross compilign python (old python 2.7.2 here), it looks like the patches that will get merged upstream are for python 3.3+) only

And in any case, even with this latest build the pixbuf functions do not seem to work and none of the demos work properly either.. (artifacts, non window refresh, etc)

Dead end.

Attachments (2)

GTKBuildProcess.pdf (337.2 KB) - added by Antoine Martin 7 years ago.
documentation found here: http://cs.geneseo.edu/~baldwin/ivipp/GTKBuildProcess.pdf
opengl-win32.patch (3.2 KB) - added by Antoine Martin 7 years ago.
with this patch, win32 works ok, for x264/vpx at least, but linux crashes..

Download all attachments as: .zip

Change History (14)

Changed 7 years ago by Antoine Martin

Attachment: GTKBuildProcess.pdf added

comment:1 Changed 7 years ago by Antoine Martin

Description: modified (diff)
Status: newaccepted

comment:2 Changed 7 years ago by Antoine Martin

Description: modified (diff)

comment:3 Changed 7 years ago by Antoine Martin

Description: modified (diff)

comment:4 Changed 7 years ago by Antoine Martin

r2361 allows us to package all the OpenGL bits, and fixes the win32 test for GL support (using a temporary window to get a context.. yuk).

Problem is that we still get:

2012-12-25 18:24:53,569 OpenGL Version: 1.1.0
2012-12-25 18:24:53,640 GL Extension GL_ARB_shader_objects unavailable
2012-12-25 18:24:53,660 GL Extension GL_ARB_vertex_array_object unavailable
2012-12-25 18:24:53,670 GL Extension GL_ARB_texture_buffer_object unavailable
2012-12-25 18:24:53,680 GL Extension GL_ARB_framebuffer_object unavailable
2012-12-25 18:24:53,690 GL Extension GL_ARB_map_buffer_range unavailable
2012-12-25 18:24:53,700 GL Extension GL_ARB_copy_buffer unavailable
2012-12-25 18:24:53,700 GL Extension GL_ARB_uniform_buffer_object unavailable
2012-12-25 18:24:53,710 GL Extension GL_ARB_draw_elements_base_vertex unavailable
2012-12-25 18:24:53,710 GL Extension GL_ARB_provoking_vertex unavailable
2012-12-25 18:24:53,720 GL Extension GL_ARB_sync unavailable
2012-12-25 18:24:53,720 GL Extension GL_ARB_texture_multisample unavailable
2012-12-25 18:24:53,730 GL Extension GL_ARB_blend_func_extended unavailable
2012-12-25 18:24:53,730 GL Extension GL_ARB_sampler_objects unavailable
2012-12-25 18:24:53,740 GL Extension GL_ARB_timer_query unavailable
2012-12-25 18:24:53,750 GL Extension GL_ARB_vertex_type_2_10_10_10_rev unavailable
2012-12-25 18:24:53,759 GL Extension GL_ARB_draw_indirect unavailable
2012-12-25 18:24:53,759 GL Extension GL_ARB_gpu_shader_fp64 unavailable
2012-12-25 18:24:53,769 GL Extension GL_ARB_shader_subroutine unavailable
2012-12-25 18:24:53,779 GL Extension GL_ARB_tessellation_shader unavailable
2012-12-25 18:24:53,789 GL Extension GL_ARB_transform_feedback2 unavailable
2012-12-25 18:24:53,789 GL Extension GL_ARB_transform_feedback3 unavailable
2012-12-25 18:24:53,799 GL Extension GL_ARB_ES2_compatibility unavailable
2012-12-25 18:24:53,799 GL Extension GL_ARB_get_program_binary unavailable
2012-12-25 18:24:53,809 GL Extension GL_ARB_separate_shader_objects unavailable
2012-12-25 18:24:53,819 GL Extension GL_ARB_vertex_attrib_64bit unavailable
2012-12-25 18:24:53,819 GL Extension GL_ARB_viewport_array unavailable
2012-12-25 18:24:53,829 GL Extension GL_ARB_base_instance unavailable
2012-12-25 18:24:53,829 GL Extension GL_ARB_transform_feedback_instanced unavailable
2012-12-25 18:24:53,839 GL Extension GL_ARB_internalformat_query unavailable
2012-12-25 18:24:53,849 GL Extension GL_ARB_shader_atomic_counters unavailable
2012-12-25 18:24:53,849 GL Extension GL_ARB_shader_image_load_store unavailable
2012-12-25 18:24:53,859 GL Extension GL_ARB_texture_storage unavailable
2012-12-25 18:24:53,869 GL Extension GL_ARB_clear_buffer_object unavailable
2012-12-25 18:24:53,869 GL Extension GL_ARB_compute_shader unavailable
2012-12-25 18:24:53,869 GL Extension GL_ARB_copy_image unavailable
2012-12-25 18:24:53,901 GL Extension GL_KHR_debug unavailable
2012-12-25 18:24:53,921 GL Extension GL_ARB_framebuffer_no_attachments unavailable
2012-12-25 18:24:53,921 GL Extension GL_ARB_internalformat_query2 unavailable
2012-12-25 18:24:53,921 GL Extension GL_ARB_invalidate_subdata unavailable
2012-12-25 18:24:53,940 GL Extension GL_ARB_multi_draw_indirect unavailable
2012-12-25 18:24:53,950 GL Extension GL_ARB_program_interface_query unavailable
2012-12-25 18:24:53,960 GL Extension GL_ARB_shader_storage_buffer_object unavailable
2012-12-25 18:24:53,960 GL Extension GL_ARB_texture_buffer_range unavailable
2012-12-25 18:24:53,970 GL Extension GL_ARB_texture_storage_multisample unavailable
2012-12-25 18:24:53,970 GL Extension GL_ARB_texture_view unavailable
2012-12-25 18:24:53,980 GL Extension GL_ARB_vertex_attrib_binding unavailable
2012-12-25 18:24:53,980 GL Extension GL_ARB_fragment_program unavailable

2012-12-25 18:24:54,000 Error loading OpenGL support: \
        ** OpenGL initialization error: OpenGL output requires glInitFragmentProgramARB
Traceback (most recent call last):
  File "xpra\client.pyc", line 95, in <module>
  File "xpra\gl\gl_client_window.pyc", line 11, in <module>
  File "xpra\gl\gl_check.pyc", line 76, in check_support
ImportError: ** OpenGL initialization error: OpenGL output requires glInitFragmentProgramARB
** Message: pygobject_register_sinkfunc is deprecated (GstObject)
2012-12-25 18:24:56,674 Attached to tcp:192.168.1.100:10000 (press Control-C to detach)

despite the extension being available according to various tools (ie: GPU Caps Viewer)

And unfortunately this is not a packaging issue as running the code directly from the clean python tree (with latest PyOpenGL version 3.0.2) produces the same error.
Also, this is not a pygtkgl issue either, as this error comes straight from pyOpenGL... Here is the code in question (found in OpenGL.raw.GL.ARB.fragment_program:

EXTENSION_NAME = 'GL_ARB_fragment_program'
(...)
def glInitFragmentProgramARB():
    '''Return boolean indicating whether this extension is available'''
    return extensions.hasGLExtension( EXTENSION_NAME )

And this hasExtension check does:

AVAILABLE_GL_EXTENSIONS[:] = glGetString( GL_EXTENSIONS ).split()
(...)
result = specifier in AVAILABLE_GL_EXTENSIONS

Which is odd, it doesn't do anything fancy in there so you would think it should get the same list that other applications are quite happily getting? Calling glGetString( GL_EXTENSIONS ) returns nothing, so something fishy is going on there.
And no, bypassing this check does not help, it just fails a little later when trying to use the extensions which does not exist..

The docs aren't particularly helpful here.

comment:5 Changed 7 years ago by Antoine Martin

We don't need GL v1.3 as per r2363, the extension we need may still be available when the driver advertises GL v1.1 - so we revert that and also improve error display/handling in r2368.
We now also include OpenGL_accelerate, see r2369


It seems that the easy_install way of installing PyOpenGL leaves out a number of things, including the crucial GLUT DLLs... (you can install them separately, but it's not clear under what name or where..) so use these binary installers instead (or build from source - apparently, not tested that).
The only way I could find what DLLs are needed is to grep the source, and then I found in OpenGL.platform.win32.py:

  • opengl32
  • glu32
  • freeglut%s.%s or glut%s.%s or freeglut
  • gle%s.%s or opengle

with "%s.%s" defined as "size"."vc compiler".

  • size is obtained from platform.architecture()[0].strip( 'bits' ) so it should be 32 or 64
  • the vc compiler value is either vc7, vc9 or vc10 based on some magic sys.hexversion tests (so it should match the version of Visual Studio used for building python).

They are all there now, but it doesn't help. But then again it didn't complain when those weren't installed either...


When I run xpra/gl/gl_check.py I get:

  • on Linux: the full list of extensions (counted 164 with nouveau).
  • on MS Windows via VirtualBox? (with accelerated 3D drivers and dozens of extensions reported by GPU Caps Viewer), I only get: GL_WIN_swap_hint GL_EXT_bgra GL_EXT_paletted_texture
  • on MS Windows via VMWare: identical to virtualbox...

Why doesn't PyOpenGL see more extensions on Windows??

Version 0, edited 7 years ago by Antoine Martin (next)

comment:6 Changed 7 years ago by Antoine Martin

Simply switching the gl context to double-buffered (done as part of r2370) allows windows to get full GL capability, and so we do finally find the extension we need... only to crash hard later :(
(and when I say crash hard, more often than not it will take the whole virtualbox VM with it)

Last edited 7 years ago by Antoine Martin (previous) (diff)

comment:7 Changed 7 years ago by Antoine Martin

I think it causes memory corruption on win32 - see #229

Changed 7 years ago by Antoine Martin

Attachment: opengl-win32.patch added

with this patch, win32 works ok, for x264/vpx at least, but linux crashes..

comment:8 Changed 7 years ago by Antoine Martin

Ignore comment above, the patch does not work :(
It fails to import something which must be packaged differently and reverts to non-opengl rendering.. which has always worked ok.

comment:9 Changed 7 years ago by Antoine Martin

Milestone: 0.80.9

may re-visit this for 0.9 with mingw on Fedora if someone packages gtkglext (maci?)

comment:10 Changed 7 years ago by Antoine Martin

Status: acceptednew

Most of the problems reported in this ticket are due to the context and the use of single vs double buffered, and many of the examples you can google will fail because of this.

All the errors are very misleading.
This ticket should be closed as it is more of an already solved packaging/setup issue.

Anyone reading this looking to solve the same problem, see r2370 and in particular:

display_mode = (gtk.gdkgl.MODE_RGB | gtk.gdkgl.MODE_DEPTH | gtk.gdkgl.MODE_DOUBLE)

And the fallback:

display_mode &= ~gtk.gdkgl.MODE_DOUBLE
Last edited 7 years ago by Antoine Martin (previous) (diff)

comment:11 Changed 7 years ago by Antoine Martin

Resolution: fixed
Status: newclosed

comment:12 Changed 2 years ago by Antoine Martin

In newer versions, we use MSYS2 and these instructions for building (py)gtkglext on ms windows: ticket:678#comment:27.
See also #1569 for python3.

Note: See TracTickets for help on using tickets.