Skip to content

reorganize GDK's GL code

Benjamin Otte requested to merge wip/otte/gleanup into master

Inspired by various issues with the nvidia driver, I took a look at our GL code and encountered lots of madness (as I had expected) that I realized could be simplified quite a bit (I had not expected that).

The work doing that lives here.

What does this branch do:

  1. It moves the fbconfig from the GdkGLContext to the GdkDisplay as there is only ever a single config.

  2. It makes Wayland and X11 code report proper error messages and deletes a bunch of code that is no longer necessary due to (1).

  3. It makes X error checking a lot stricter and insists on using only the XVisual reported by the GL backend. This causes issues with current Mesa on EGL, but fixes weirdness with nvidia.

  4. It redoes X11 initialization to try ideal EGL (no software rendering, no weird features) before GLX before any EGL. This means EGL is not chosen with broken Mesa (see above) and hopefully fixes a bunch of weirdnesses in uncommon setups.

  5. It forces EGL to 1.4 and requires support for surfaceless contexts on X11 and Wayland. This allows removing all the workarounds (in particular the dummy surfaces) that existed for older versions. As this code was basically never run, it was very untested.

  6. It captures the GError from an GL initialization failure and stores it in the GdkDisplay with a public API for retrieval at any point in time. Wayland and X11 now report errors a lot more finegrained (I didn't test that much, my GL works too well).

  7. GdkDisplay now has a GdkGLContext * (* init_gl) (GdkDisplay *self, GError **error) vfunc that backends must implement to support GL. GDK will call this automatically as needed and backends can use that to initialize OpenGL (or fail to).
    The new thing is that it has to return a working GdkGLContext (see below). This context is private and it is allowed to have a NULL surface. (The Wayland and MacOS ones do, the X11 one doesn't.)

  8. This new init GL context is used as the base context and all other contexts use this context as the shared context. This simplifies the inheritance tree of shared contexts but ends up with the same result: All GDK contexts for the same display are shared.
    gdk_display_get_gl_context() returns that context for GDK backends.

  9. Paint contexts are gone. Instead of indirections when drawing stuff, GL contexts now draw directly to the frame inbetween begin/end_draw_frame().

  10. A new function gdk_gl_context_is_shared (context, other) exists that can be used to check if resources can be shared between contexts. This function is used in renderers with GdkGLTexture. gdk_gl_context_get_shared_context() now always returns NULL (see (9)).

  11. The nvidia driver and Mesa disagree about init state. See This mozilla bug for details. A workaround has been added.

  12. On Windows, the EGL and WGL backends have been split into separate source files. GTK prefers using WGL now. This cleanup also amde WGL noticeably faster (at least on my nvidia card).

I'm happy about reviews because I think this code makes sense by now, but I'll continue with this for a while - including testing it on the new nvidia driver once all the reshufflling is done.

Edited by Benjamin Otte

Merge request reports