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.
This is for adding a EGL-based renderer which is done via the ANGLE
project, which translate EGL calls to Direct3D 9/11. This is done as a
possible solution to issue #105, especially for cases where the needed
full GL extensions to map OpenGL to Direct3D is unavailable or
unreliable, or when the OpenGL implementation from the graphics drivers
are problematic.
To enable this, do the following:
-Build ANGLE and ensure the ANGLE libEGL.dll and libGLESv2.dll are
available. A sufficiently-recent ANGLE is needed for things to
work correctly--note that the copy of ANGLE that is included in
qtbase-5.10.1 is sufficient. ANGLE is licensed under a BSD 3-clause
license.
-Build libepoxy on Windows with EGL support enabled.
-Currently, prior to running GTK+ programs, the GDK_DEBUG envvar needs
to be set with gl-gles as at least one of the flags.
Known issues:
-Only OpenGL ES 3 is supported, ANGLE's ES 2 does not support the needed
extensions, notably GL_OES_vertex_array_object, but its ES 3 support is
sufficient.
-There is no autodetection or fallback mechanism to enable using
EGL/Angle automatically yet. There are no plans to do this in this
commit.
Rename all *window.[ch] source files.
This is an automatic operation, done by the following commands:
for i in $(git ls-files gdk | grep window); do
git mv $i $(echo $i | sed s/window/surface/);
git sed -f g $(basename $i) $(basename $i | sed s/window/surface/) ;
done
git checkout NEWS* po-properties po
This renames the GdkWindow class and related classes (impl, backend
subclasses) to surface. Additionally it renames related types:
GdkWindowAttr, GdkWindowPaint, GdkWindowWindowClass, GdkWindowType,
GdkWindowTypeHint, GdkWindowHints, GdkWindowState, GdkWindowEdge
This is an automatic conversion using the below commands:
git sed -f g GdkWindowWindowClass GdkSurfaceSurfaceClass
git sed -f g GdkWindow GdkSurface
git sed -f g "gdk_window\([ _\(\),;]\|$\)" "gdk_surface\1" # Avoid hitting gdk_windowing
git sed -f g "GDK_WINDOW\([ _\(]\|$\)" "GDK_SURFACE\1" # Avoid hitting GDK_WINDOWING
git sed "GDK_\([A-Z]*\)IS_WINDOW\([_ (]\|$\)" "GDK_\1IS_SURFACE\2"
git sed GDK_TYPE_WINDOW GDK_TYPE_SURFACE
git sed -f g GdkPointerWindowInfo GdkPointerSurfaceInfo
git sed -f g "BROADWAY_WINDOW" "BROADWAY_SURFACE"
git sed -f g "broadway_window" "broadway_surface"
git sed -f g "BroadwayWindow" "BroadwaySurface"
git sed -f g "WAYLAND_WINDOW" "WAYLAND_SURFACE"
git sed -f g "wayland_window" "wayland_surface"
git sed -f g "WaylandWindow" "WaylandSurface"
git sed -f g "X11_WINDOW" "X11_SURFACE"
git sed -f g "x11_window" "x11_surface"
git sed -f g "X11Window" "X11Surface"
git sed -f g "WIN32_WINDOW" "WIN32_SURFACE"
git sed -f g "win32_window" "win32_surface"
git sed -f g "Win32Window" "Win32Surface"
git sed -f g "QUARTZ_WINDOW" "QUARTZ_SURFACE"
git sed -f g "quartz_window" "quartz_surface"
git sed -f g "QuartzWindow" "QuartzSurface"
git checkout NEWS* po-properties
No visible changes as GL rendering is disabled at the moment.
What was done:
1. Move window->invalidate_for_new_frame to glcontext->begin_frame
This moves the code to where it is used (the GLContext) and prepares it
for being called where it is used when actually beginning to draw the
frame.
2. Get rid of buffer-age usage
We want to let the application render directly to the backbuffer.
Because of that, we cannot make any assumptions about the contents the
application renders outside the clip area.
In particular GskGLRenderer renders random stuff there but not actual
contents.
3. Pass the actual GL context
Previously, we passed the shared context to end_frame, now we pass the
actual GL context that the application uses for rendering. This is so
that the vfuncs could prepare the actual contexts for rendering (they
don't currently).
4. Simplify the code
The previous code set up the final drawing method in begin_frame.
Instead, we now just ensure the clip area is something we can render
and decide on the actual method in end_frame.
This is both more robust (we can change the clip area in between if we
want to) and less code.
Now that we have a two-stages GL context creation sequence, we can move
the profile to a pre-realize option, like the debug and forward
compatibility bits, or the GL version to use.
Like what is being done in the X11 and Wayland backends, create the
GdkWin32GLContext in 2 steps, where we only create the actual WGL context
in _gdk_win32_gl_context_realize().
https://bugzilla.gnome.org/show_bug.cgi?id=741946
This adds support for OpenGL to the GDK Windows backend using the WGL API
calls, which enables programs that uses the GTK+ GLArea widgets to work on
Windows as well.
This also adds a simple utility function to query for the version of OpenGL
that is supported by the Windows system, like the one provided by the X11
backend.
Many thanks to Alex (and Emmanuele, who started the OpenGL integration in
GTK+) who offered advice and help along the way, as well as the X11 and
Wayland backend for this work to refer to and to model upon.
https://bugzilla.gnome.org/show_bug.cgi?id=740795