Add gdk_gl_context_is_api_allowed() for backends and make them use it.
Finally, have them return the final API as the return value (or 0 on
error).
And then use that api instead of a use_es boolean flag.
Fixes#4221
The term "hdr" is so overloaded, we shouldn't use them anywhere, except
from maybe describing all of this work in blog posts and other marketing
materials.
So do renames:
* hdr => high_depth
* request_hdr => prefers_high_depth
This more accurately describes what is going on.
We have a global GdkGLBackendType now, just set it.
This way, using the variable forces the backend type, and we don't need
special code handling the env vars in the backends.
It also means setting the env var will now "work" on GDK backends that
don't even support that GL backend and simualte another GDK backend
having registered that GL backend already. So you can run
GDK_DEBUG=gl-wgl gtk4-demo
on test what Wayland will do when WGL is in use.
Include the appropriate headers as some function prototypes were moved lately.
Also, re-order the include order of the gdk/*private.h headers alphabetically
in the files that were updated.
Creative people managed to create an X11 display and a Wayland display
at once, thereby getting EGL and GLX involved in a fight to the death
over the ownership of the glFoo() symbolspace.
A way to force such a fight with available tools here is (on Wayland)
running something like:
GTK_INSPECTOR_DISPLAY=:1 GTK_DEBUG=interactive gtk4-demo
Related: xdg-desktop-portal-gnome#5
On Windows, GLES is not that widely available unless one installs wrapper
libraries such as libANGLE, so GLES/EGL support on Windows is used more like
a fallback mode if Desktop OpenGL (WGL) support is inadequate on the system.
Hence, unless one forces WGL or EGL, we will first try to initialize WGL, and
then try to initialize GLES if enabled and if WGL initialization failed, and
then just return whatever the last result we can obtain from these
initialization attempts, since unlike X11 EGL contexts, we do not have
separate modes for WGL except for legacy and non-legacy contexts.
We were setting the WGL pixel format in GdkWin32Display too early, so the code
does not bail out correctly when we retry establishing the WGL context.
Fix this by pushing back setting the WGL pixel format only after it passes the
shader availability check.
Should fix issue #4257.
When we initialize OpenGL, check whether we have OpenGL 2.0 or later; if not,
check whether we have the 'GL_ARB_shader_objects' extension, since we must be
able to support shaders if using OpenGL for GTK.
If we don't support shaders, as some Windows graphics drivers do not support
OpenGL adequately, notably older Intel drivers, reject and destroy the GL
context that we created, and so fallback to the Cairo GSK renderer, so that
things continue to run, albeit with an expected warning message that the GL
context cannot be realized.
Also, when we could not make the created dummy WGL context current during
initialization, make sure that we destroy the dummy WGL context as well.
Fixes issue #4165.
It is basically not used by default and is pretty much broken at this point, so
it's about time to drop it.
Let's focus on fixing the OLE2 DnD protocol.
The dummy Win32 window that we use to capture display change events and
to create dummy WGL contexts was created with CS_OWNDC, so we really do
not need to (and should not) call ReleaseDC() on the HDC that we
obtained from it, so drop these calls.
Since the shaders need to be updated for using with GLES (libANGLE at
least), default to WGL for now. Unfortunately it is not that common for
Windows to have GLES support, in which the easiest way to obtain such
support is via Google's libANGLE.
It turns out that the problem of the WGL window not drawing was due to
the fact that I messed up where I placed SwapBuffers() during the
conversion... doh:|
At the same time, stop storing the HDC in the GdkWin32GLContextWGL, but
instead always create it along the surface we created, so that it is ready
for use for operating with WGL when we are not dealing with "surfaceless"
contexts. If we are dealing with "surfaceless" contexts, just use the
HDC of the dummy window that we created when we created the
Gdk(Win32)Display.
WGL contexts should now be in working order at this point.
This commit attempts to split GdkWin32GLContext into two parts, one for
WGL and the other for EGL (ANGLE), and attempts to simplify things a
bit, by:
* We are already creating a Win32 window to capture display changes,
so we can just use that to act as our dummy window that we use to
find out the pixel format that the system supports for WGL. We also
use it to obtain the dummy legacy WGL context that we will always
require to create our more advanced Core WGL contexts.
* Like what is done in X11, store up the WGL pixel format or the
EGLConfig in our GdkWin32Display.
* Ensure we do not create the dummy WGL context unnecessarily.
In this way, we can successfully create the WGL/EGL contexts, however
there are some issues at this point:
* For WGL, the code successfully initializes and realizes the WGL
Contexts, but for some reason things became invisible. When running
gtk4-demo, this can be verified by seeing the mouse cursor changing
when moved to spots where one can resize the window, although they
were invisible.
* For EGL, the code initializes EGL but could not realize the EGL
context as shaders failed to compile. It seems like the shader issue
is definitely outside the scope of this MR.
Now that we have the display's context to hook into, we can use it to
construct other GL contexts and don't need a GdkSurface vfunc anymore.
This has the added benefit that backends can have different GdkGLContext
classes on the display and get new GLContexts generated from them, so
we get multiple GL backend support per GDK backend for free.
I originally wanted to make this a vfunc on GdkGLContextClass, but
it turns out all the abckends would just call g_object_new() anyway.
Instead of
Display::make_gl_context_current()
we now have
GLContext::clear_current()
GLContext::make_current()
This fits better with the backends (we can actually implement
clearCurrent on macOS now) and makes it easier to implement different GL
backends for backends (like EGL/GLX on X11).
We also pass a surfaceless boolean to make_current() so the calling code
can decide if a surface needs to be bound or not, because the backends
were all doing whatever, which was very counterproductive.
... or more exactly: Only use paint contexts with
gdk_cairo_draw_from_gl().
Instead of paint contexts being the only contexts who call swapBuffer(),
any context can be used for this, when it's used with
begin_frame()/end_frame().
This removes 2 features:
1. We no longer need a big sharing hierarchy. All contexts are now
shared with gdk_display_get_gl_context().
2. There is no longer a difference between attached and non-attached
contexts. All contexts work the same way.