[gtk/wip/otte/gleanup] Split out WGL/EGL stuff and simplify things
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/gleanup] Split out WGL/EGL stuff and simplify things
- Date: Fri, 16 Jul 2021 09:29:21 +0000 (UTC)
commit 17b961f16090d86a261c7e71e467a265ee82b5e8
Author: Chun-wei Fan <fanchunwei src gnome org>
Date: Wed Jul 14 17:46:31 2021 +0800
Split out WGL/EGL stuff and simplify things
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.
squash
gdk/win32/gdkdisplay-win32.c | 79 ++-
gdk/win32/gdkdisplay-win32.h | 11 +-
gdk/win32/gdkglcontext-win32-egl.c | 504 ++++++++++++++++
gdk/win32/gdkglcontext-win32-wgl.c | 738 +++++++++++++++++++++++
gdk/win32/gdkglcontext-win32.c | 1169 +-----------------------------------
gdk/win32/gdkglcontext-win32.h | 45 +-
gdk/win32/gdksurface-win32.c | 6 +-
gdk/win32/gdksurface-win32.h | 6 +-
gdk/win32/meson.build | 2 +
9 files changed, 1369 insertions(+), 1191 deletions(-)
---
diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c
index 31c5f2ff27..c3d001baca 100644
--- a/gdk/win32/gdkdisplay-win32.c
+++ b/gdk/win32/gdkdisplay-win32.c
@@ -481,6 +481,7 @@ register_display_change_notification (GdkDisplay *display)
wclass.lpszClassName = "GdkDisplayChange";
wclass.lpfnWndProc = display_change_window_procedure;
wclass.hInstance = _gdk_app_hmodule;
+ wclass.style = CS_OWNDC;
klass = RegisterClass (&wclass);
if (klass)
@@ -656,6 +657,19 @@ gdk_win32_display_dispose (GObject *object)
if (display_win32->hwnd != NULL)
{
+ if (display_win32->dummy_context_wgl.hglrc != NULL)
+ {
+ wglMakeCurrent (NULL, NULL);
+ wglDeleteContext (display_win32->dummy_context_wgl.hglrc);
+ display_win32->dummy_context_wgl.hglrc = NULL;
+ }
+
+ if (display_win32->dummy_context_wgl.hdc != NULL)
+ {
+ ReleaseDC (display_win32->hwnd, display_win32->dummy_context_wgl.hdc);
+ display_win32->dummy_context_wgl.hdc = NULL;
+ }
+
DestroyWindow (display_win32->hwnd);
display_win32->hwnd = NULL;
}
@@ -1147,6 +1161,68 @@ gdk_win32_display_get_setting (GdkDisplay *display,
return _gdk_win32_get_setting (name, value);
}
+static gboolean
+gdk_win32_display_init_gl_backend (GdkDisplay *display,
+ GError **error)
+{
+#ifdef GDK_WIN32_ENABLE_EGL
+ if (GDK_DISPLAY_DEBUG_CHECK (display, GL_EGL))
+ return gdk_win32_display_init_egl (display, error);
+#endif
+ if (GDK_DISPLAY_DEBUG_CHECK (display, GL_WGL))
+ return gdk_win32_display_init_wgl (display, error);
+
+ /* No env vars set, do the regular GL initialization.
+ *
+ * We try EGL first if supported, but are very picky about what we accept.
+ * If that fails, we try to go with WGL instead.
+ * And if that also fails, we try EGL again, but this time accept anything.
+ *
+ * The idea here is that EGL is the preferred method going forward, but WGL is
+ * the tried and tested method that we know works. So if we detect issues with
+ * EGL, we want to avoid using it in favor of WGL.
+ */
+
+#ifdef GDK_WIN32_ENABLE_EGL
+ if (gdk_win32_display_init_egl (display, error))
+ return TRUE;
+#endif
+ g_clear_error (error);
+
+ if (gdk_win32_display_init_wgl (display, error))
+ return TRUE;
+ g_clear_error (error);
+
+#ifdef GDK_WIN32_ENABLE_EGL
+ return gdk_win32_display_init_egl (display, error);
+#else
+ return FALSE;
+#endif
+}
+
+static GdkGLContext *
+gdk_win32_display_init_gl (GdkDisplay *display,
+ GError **error)
+{
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+ GdkGLContext *gl_context = NULL;
+
+ if (!gdk_win32_display_init_gl_backend (display, error))
+ return NULL;
+
+#ifdef GDK_WIN32_ENABLE_EGL
+ if (display_win32->egl_disp)
+ gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL, "display", display, NULL);
+ else
+#endif
+ if (display_win32->wgl_pixel_format != 0)
+ gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL, "display", display, NULL);
+
+ g_return_val_if_fail (gl_context != NULL, NULL);
+
+ return gl_context;
+}
+
/**
* gdk_win32_display_get_egl_display:
* @display: (type GdkWin32Display): a Win32 display
@@ -1165,7 +1241,7 @@ gdk_win32_display_get_egl_display (GdkDisplay *display)
#ifdef GDK_WIN32_ENABLE_EGL
display_win32 = GDK_WIN32_DISPLAY (display);
- if (display_win32->have_wgl)
+ if (display_win32->wgl_pixel_format != 0)
return NULL;
return display_win32->egl_disp;
@@ -1210,6 +1286,7 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
display_class->get_setting = gdk_win32_display_get_setting;
display_class->set_cursor_theme = gdk_win32_display_set_cursor_theme;
+ display_class->init_gl = gdk_win32_display_init_gl;
_gdk_win32_surfaceing_init ();
}
diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h
index 46a80def2e..e7a027c883 100644
--- a/gdk/win32/gdkdisplay-win32.h
+++ b/gdk/win32/gdkdisplay-win32.h
@@ -106,6 +106,12 @@ typedef struct _GdkWin32KernelCPUFuncs
funcIsWow64Process2 isWow64Process2;
} GdkWin32KernelCPUFuncs;
+typedef struct
+{
+ HDC hdc;
+ HGLRC hglrc;
+} GdkWin32GLDummyContextWGL;
+
struct _GdkWin32Display
{
GdkDisplay display;
@@ -119,15 +125,16 @@ struct _GdkWin32Display
HWND hwnd;
/* WGL/OpenGL Items */
- guint have_wgl : 1;
+ GdkWin32GLDummyContextWGL dummy_context_wgl;
+ int wgl_pixel_format;
guint gl_version;
HWND gl_hwnd;
#ifdef GDK_WIN32_ENABLE_EGL
/* EGL (Angle) Items */
- guint have_egl : 1;
guint egl_version;
EGLDisplay egl_disp;
+ EGLConfig egl_config;
HDC hdc_egl_temp;
#endif
diff --git a/gdk/win32/gdkglcontext-win32-egl.c b/gdk/win32/gdkglcontext-win32-egl.c
new file mode 100644
index 0000000000..9d2df6b499
--- /dev/null
+++ b/gdk/win32/gdkglcontext-win32-egl.c
@@ -0,0 +1,504 @@
+/* GDK - The GIMP Drawing Kit
+ *
+ * gdkglcontext-win32.c: Win32 specific OpenGL wrappers
+ *
+ * Copyright © 2014 Emmanuele Bassi
+ * Copyright © 2014 Alexander Larsson
+ * Copyright © 2014 Chun-wei Fan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gdkprivate-win32.h"
+#include "gdksurface-win32.h"
+#include "gdkglcontext-win32.h"
+#include "gdkdisplay-win32.h"
+
+#include "gdkwin32display.h"
+#include "gdkwin32glcontext.h"
+#include "gdkwin32misc.h"
+#include "gdkwin32screen.h"
+#include "gdkwin32surface.h"
+
+#include "gdkglcontext.h"
+#include "gdksurface.h"
+#include "gdkinternals.h"
+#include "gdkintl.h"
+
+#include <cairo.h>
+#include <epoxy/egl.h>
+
+struct _GdkWin32GLContextEGL
+{
+ GdkWin32GLContext parent_instance;
+
+ /* EGL (Angle) Context Items */
+ EGLContext egl_context;
+ guint do_frame_sync : 1;
+};
+
+typedef struct _GdkWin32GLContextClass GdkWin32GLContextEGLClass;
+
+G_DEFINE_TYPE (GdkWin32GLContextEGL, gdk_win32_gl_context_egl, GDK_TYPE_WIN32_GL_CONTEXT)
+
+static void
+gdk_win32_gl_context_egl_dispose (GObject *gobject)
+{
+ GdkGLContext *context = GDK_GL_CONTEXT (gobject);
+ GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (gobject);
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context));
+ GdkSurface *surface = gdk_gl_context_get_surface (context);
+
+ if (display_win32 != NULL)
+ {
+ if (eglGetCurrentContext () == context_egl->egl_context)
+ eglMakeCurrent(display_win32->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+
+ GDK_NOTE (OPENGL, g_message ("Destroying EGL (ANGLE) context"));
+
+ eglDestroyContext (display_win32->egl_disp,
+ context_egl->egl_context);
+ context_egl->egl_context = EGL_NO_CONTEXT;
+ }
+
+ G_OBJECT_CLASS (gdk_win32_gl_context_egl_parent_class)->dispose (gobject);
+}
+
+static gboolean
+is_egl_force_redraw (GdkSurface *surface)
+{
+ /* We only need to call gdk_window_invalidate_rect () if necessary */
+ if (surface->gl_paint_context != NULL && gdk_gl_context_get_use_es (surface->gl_paint_context))
+ {
+ GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
+
+ return impl->egl_force_redraw_all;
+ }
+ return FALSE;
+}
+
+static void
+reset_egl_force_redraw (GdkSurface *surface)
+{
+ if (surface->gl_paint_context != NULL && gdk_gl_context_get_use_es (surface->gl_paint_context))
+ {
+ GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
+
+ if (impl->egl_force_redraw_all)
+ impl->egl_force_redraw_all = FALSE;
+ }
+}
+
+static void
+gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
+ cairo_region_t *painted)
+{
+ GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
+ GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
+ GdkSurface *surface = gdk_gl_context_get_surface (context);
+ GdkWin32Display *display_win32 = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
+ cairo_rectangle_int_t whole_window;
+ EGLSurface egl_surface;
+
+ GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_egl_parent_class)->end_frame (draw_context, painted);
+
+ gdk_gl_context_make_current (context);
+ whole_window =
+ (GdkRectangle) { 0, 0,
+ gdk_surface_get_width (surface),
+ gdk_surface_get_height (surface)
+ };
+
+ egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, FALSE);
+
+ if (is_egl_force_redraw (surface))
+ {
+ GdkRectangle rect = {0, 0, gdk_surface_get_width (surface), gdk_surface_get_height (surface)};
+
+ /* We need to do gdk_window_invalidate_rect() so that we don't get glitches after maximizing or
+ * restoring or using aerosnap
+ */
+ gdk_surface_invalidate_rect (surface, &rect);
+ reset_egl_force_redraw (surface);
+ }
+
+ eglSwapBuffers (display_win32->egl_disp, egl_surface);
+}
+
+#ifndef EGL_PLATFORM_ANGLE_ANGLE
+#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
+#endif
+
+#ifndef EGL_PLATFORM_ANGLE_TYPE_ANGLE
+#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
+#endif
+
+#ifndef EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE
+#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
+#endif
+
+static EGLDisplay
+gdk_win32_get_egl_display (GdkWin32Display *display)
+{
+ EGLDisplay disp;
+
+ if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
+ {
+ PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = (void *) eglGetProcAddress
("eglGetPlatformDisplayEXT");
+ if (getPlatformDisplay)
+ {
+ EGLint disp_attr[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_NONE};
+
+ disp = getPlatformDisplay (EGL_PLATFORM_ANGLE_ANGLE, display->hdc_egl_temp, disp_attr);
+
+ if (disp != EGL_NO_DISPLAY)
+ return disp;
+ }
+ }
+
+ return eglGetDisplay (display->hdc_egl_temp);
+}
+
+#define MAX_EGL_ATTRS 30
+
+static gboolean
+find_eglconfig_for_window (GdkWin32Display *display,
+ EGLConfig *egl_config_out,
+ EGLint *min_swap_interval_out,
+ GError **error)
+{
+ EGLint attrs[MAX_EGL_ATTRS];
+ EGLint count;
+ EGLConfig *configs, chosen_config;
+
+ int i = 0;
+
+ EGLDisplay egl_disp = display->egl_disp;
+
+ attrs[i++] = EGL_CONFORMANT;
+ attrs[i++] = EGL_OPENGL_ES2_BIT;
+ attrs[i++] = EGL_SURFACE_TYPE;
+ attrs[i++] = EGL_WINDOW_BIT;
+
+ attrs[i++] = EGL_COLOR_BUFFER_TYPE;
+ attrs[i++] = EGL_RGB_BUFFER;
+
+ attrs[i++] = EGL_RED_SIZE;
+ attrs[i++] = 1;
+ attrs[i++] = EGL_GREEN_SIZE;
+ attrs[i++] = 1;
+ attrs[i++] = EGL_BLUE_SIZE;
+ attrs[i++] = 1;
+ attrs[i++] = EGL_ALPHA_SIZE;
+ attrs[i++] = 1;
+
+ attrs[i++] = EGL_NONE;
+ g_assert (i < MAX_EGL_ATTRS);
+
+ if (!eglChooseConfig (display->egl_disp, attrs, NULL, 0, &count) || count < 1)
+ {
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_UNSUPPORTED_FORMAT,
+ _("No available configurations for the given pixel format"));
+ return FALSE;
+ }
+
+ configs = g_new (EGLConfig, count);
+
+ if (!eglChooseConfig (display->egl_disp, attrs, configs, count, &count) || count < 1)
+ {
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_UNSUPPORTED_FORMAT,
+ _("No available configurations for the given pixel format"));
+ return FALSE;
+ }
+
+ /* Pick first valid configuration i guess? */
+ chosen_config = configs[0];
+
+ if (!eglGetConfigAttrib (display->egl_disp, chosen_config,
+ EGL_MIN_SWAP_INTERVAL, min_swap_interval_out))
+ {
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ "Could not retrieve the minimum swap interval");
+ g_free (configs);
+ return FALSE;
+ }
+
+ if (egl_config_out != NULL)
+ *egl_config_out = chosen_config;
+
+ g_free (configs);
+
+ return TRUE;
+}
+
+gboolean
+gdk_win32_display_init_egl (GdkDisplay *display,
+ GError **error)
+{
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+ int best_idx = 0;
+ EGLDisplay egl_disp;
+
+ if (display_win32->egl_disp != EGL_NO_DISPLAY)
+ return TRUE;
+
+ egl_disp = gdk_win32_get_egl_display (display_win32);
+
+ if (egl_disp == EGL_NO_DISPLAY)
+ return FALSE;
+
+ if (!eglInitialize (egl_disp, NULL, NULL))
+ {
+ eglTerminate (egl_disp);
+ egl_disp = EGL_NO_DISPLAY;
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ _("No GL implementation is available"));
+ return FALSE;
+ }
+
+ display_win32->egl_disp = egl_disp;
+ display_win32->egl_version = epoxy_egl_version (egl_disp);
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+
+ display_win32->hasEglSurfacelessContext =
+ epoxy_has_egl_extension (egl_disp, "EGL_KHR_surfaceless_context");
+
+ GDK_NOTE (OPENGL,
+ g_print ("EGL API version %d.%d found\n"
+ " - Vendor: %s\n"
+ " - Checked extensions:\n"
+ "\t* EGL_KHR_surfaceless_context: %s\n",
+ display_win32->egl_version / 10,
+ display_win32->egl_version % 10,
+ eglQueryString (display_win32->egl_disp, EGL_VENDOR),
+ display_win32->hasEglSurfacelessContext ? "yes" : "no"));
+
+ return find_eglconfig_for_window (display_win32, &display_win32->egl_config,
+ &display_win32->egl_min_swap_interval, error);
+}
+
+#define N_EGL_ATTRS 16
+
+static EGLContext
+create_egl_context (EGLDisplay display,
+ EGLConfig config,
+ GdkGLContext *share,
+ int flags,
+ int major,
+ int minor,
+ gboolean *is_legacy)
+{
+ EGLContext ctx;
+ EGLint context_attribs[N_EGL_ATTRS];
+ int i = 0;
+
+ /* ANGLE does not support the GL_OES_vertex_array_object extension, so we need to use ES3 directly */
+ context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
+ context_attribs[i++] = 3;
+
+ /* Specify the flags */
+ context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
+ context_attribs[i++] = flags;
+
+ context_attribs[i++] = EGL_NONE;
+ g_assert (i < N_EGL_ATTRS);
+
+ ctx = eglCreateContext (display,
+ config,
+ share != NULL ? GDK_WIN32_GL_CONTEXT_EGL (share)->egl_context
+ : EGL_NO_CONTEXT,
+ context_attribs);
+
+ if (ctx != EGL_NO_CONTEXT)
+ GDK_NOTE (OPENGL, g_message ("Created EGL context[%p]", ctx));
+
+ return ctx;
+}
+
+static gboolean
+gdk_win32_gl_context_egl_realize (GdkGLContext *context,
+ GError **error)
+{
+ GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
+
+ gboolean debug_bit, compat_bit, legacy_bit;
+ gboolean use_es = FALSE;
+ EGLContext egl_context;
+ EGLContext ctx;
+
+ /* request flags and specific versions for core (3.2+) WGL context */
+ int flags = 0;
+ int major = 0;
+ int minor = 0;
+
+ GdkSurface *surface = gdk_gl_context_get_surface (context);
+ GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
+ GdkDisplay *display = gdk_gl_context_get_display (context);
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+ GdkGLContext *share = gdk_display_get_gl_context (display);
+
+ gdk_gl_context_get_required_version (context, &major, &minor);
+ debug_bit = gdk_gl_context_get_debug_enabled (context);
+ compat_bit = gdk_gl_context_get_forward_compatible (context);
+
+ /*
+ * A legacy context cannot be shared with core profile ones, so this means we
+ * must stick to a legacy context if the shared context is a legacy context
+ */
+
+ /* if GDK_GL_LEGACY is set, we default to a legacy context */
+ legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ?
+ TRUE :
+ share != NULL && gdk_gl_context_is_legacy (share);
+
+ use_es = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
+ (share != NULL && gdk_gl_context_get_use_es (share));
+
+ if (debug_bit)
+ flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
+ if (compat_bit)
+ flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
+
+ GDK_NOTE (OPENGL, g_message ("Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s)",
+ major, minor,
+ debug_bit ? "yes" : "no",
+ compat_bit ? "yes" : "no",
+ legacy_bit ? "yes" : "no"));
+
+ ctx = create_egl_context (display_win32->egl_disp,
+ display_win32->egl_config,
+ share,
+ flags,
+ major,
+ minor,
+ &legacy_bit);
+
+ if (ctx == EGL_NO_CONTEXT)
+ {
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ _("Unable to create a GL context"));
+ return FALSE;
+ }
+
+ GDK_NOTE (OPENGL, g_print ("Created EGL context[%p]\n", ctx));
+
+ context_egl->egl_context = ctx;
+
+ /* We are using GLES here */
+ gdk_gl_context_set_use_es (context, TRUE);
+
+ /* Ensure that any other context is created with a legacy bit set */
+ gdk_gl_context_set_is_legacy (context, legacy_bit);
+
+ return TRUE;
+}
+
+static gboolean
+gdk_win32_gl_context_egl_clear_current (GdkGLContext *context)
+{
+ GdkDisplay *display = gdk_gl_context_get_display (context);
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+
+ if (display_win32->egl_disp != EGL_NO_DISPLAY)
+ return eglMakeCurrent (display_win32->egl_disp,
+ EGL_NO_SURFACE,
+ EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ else
+ return TRUE;
+}
+
+static gboolean
+gdk_win32_gl_context_egl_make_current (GdkGLContext *context,
+ gboolean surfaceless)
+{
+ GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
+ GdkDisplay *display = gdk_gl_context_get_display (context);
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+ GdkSurface *surface;
+
+ gboolean do_frame_sync = FALSE;
+
+ EGLSurface egl_surface;
+
+ surface = gdk_gl_context_get_surface (context);
+
+ if (!surfaceless)
+ egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, FALSE);
+ else
+ {
+ if (display_win32->hasEglSurfacelessContext)
+ egl_surface = EGL_NO_SURFACE;
+ else
+ egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, TRUE);
+ }
+
+ if (!eglMakeCurrent (display_win32->egl_disp,
+ egl_surface,
+ egl_surface,
+ context_egl->egl_context))
+ return FALSE;
+
+ if (display_win32->egl_min_swap_interval == 0)
+ eglSwapInterval (display_win32->egl_disp, 0);
+ else
+ g_debug ("Can't disable GL swap interval");
+
+ return TRUE;
+}
+
+static void
+gdk_win32_gl_context_egl_begin_frame (GdkDrawContext *draw_context,
+ cairo_region_t *update_area)
+{
+ GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
+ GdkSurface *surface;
+
+ surface = gdk_gl_context_get_surface (context);
+
+ gdk_win32_surface_handle_queued_move_resize (draw_context);
+
+ GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_egl_parent_class)->begin_frame (draw_context, update_area);
+}
+
+static void
+gdk_win32_gl_context_egl_class_init (GdkWin32GLContextClass *klass)
+{
+ GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS(klass);
+ GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS(klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ context_class->realize = gdk_win32_gl_context_egl_realize;
+ context_class->make_current = gdk_win32_gl_context_egl_make_current;
+ context_class->clear_current = gdk_win32_gl_context_egl_clear_current;
+
+ draw_context_class->begin_frame = gdk_win32_gl_context_egl_begin_frame;
+ draw_context_class->end_frame = gdk_win32_gl_context_egl_end_frame;
+
+ gobject_class->dispose = gdk_win32_gl_context_egl_dispose;
+}
+
+static void
+gdk_win32_gl_context_egl_init (GdkWin32GLContextEGL *egl_context)
+{
+}
diff --git a/gdk/win32/gdkglcontext-win32-wgl.c b/gdk/win32/gdkglcontext-win32-wgl.c
new file mode 100644
index 0000000000..4a248f3c4d
--- /dev/null
+++ b/gdk/win32/gdkglcontext-win32-wgl.c
@@ -0,0 +1,738 @@
+/* GDK - The GIMP Drawing Kit
+ *
+ * gdkglcontext-win32.c: Win32 specific OpenGL wrappers
+ *
+ * Copyright © 2014 Emmanuele Bassi
+ * Copyright © 2014 Alexander Larsson
+ * Copyright © 2014 Chun-wei Fan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gdkprivate-win32.h"
+#include "gdksurface-win32.h"
+#include "gdkglcontext-win32.h"
+#include "gdkdisplay-win32.h"
+
+#include "gdkwin32display.h"
+#include "gdkwin32glcontext.h"
+#include "gdkwin32misc.h"
+#include "gdkwin32screen.h"
+#include "gdkwin32surface.h"
+
+#include "gdkglcontext.h"
+#include "gdkprofilerprivate.h"
+#include "gdkinternals.h"
+#include "gdkintl.h"
+#include "gdksurface.h"
+
+#include <cairo.h>
+#include <epoxy/wgl.h>
+
+struct _GdkWin32GLContextWGL
+{
+ GdkWin32GLContext parent_instance;
+
+ HWND wgl_hwnd;
+ HDC wgl_hdc;
+ HGLRC wgl_context;
+ guint do_frame_sync : 1;
+};
+
+typedef struct _GdkWin32GLContextClass GdkWin32GLContextWGLClass;
+
+G_DEFINE_TYPE (GdkWin32GLContextWGL, gdk_win32_gl_context_wgl, GDK_TYPE_WIN32_GL_CONTEXT)
+
+static void
+gdk_win32_gl_context_wgl_dispose (GObject *gobject)
+{
+ GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (gobject);
+
+ if (context_wgl->wgl_context != NULL)
+ {
+ if (wglGetCurrentContext () == context_wgl->wgl_context)
+ wglMakeCurrent (NULL, NULL);
+
+ GDK_NOTE (OPENGL, g_print ("Destroying WGL context\n"));
+
+ wglDeleteContext (context_wgl->wgl_context);
+ context_wgl->wgl_context = NULL;
+
+ ReleaseDC (context_wgl->wgl_hwnd, context_wgl->wgl_hdc);
+ }
+
+ G_OBJECT_CLASS (gdk_win32_gl_context_wgl_parent_class)->dispose (gobject);
+}
+
+static void
+gdk_win32_gl_context_wgl_end_frame (GdkDrawContext *draw_context,
+ cairo_region_t *painted)
+{
+ GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
+ GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (context);
+ GdkSurface *surface = gdk_gl_context_get_surface (context);
+ GdkWin32Display *display = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
+ cairo_rectangle_int_t whole_window;
+
+ GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_wgl_parent_class)->end_frame (draw_context, painted);
+
+ gdk_gl_context_make_current (context);
+ whole_window = (GdkRectangle) { 0, 0, gdk_surface_get_width (surface), gdk_surface_get_height (surface) };
+
+ gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "win32", "swap buffers");
+
+ gboolean can_wait = display->hasWglOMLSyncControl;
+
+ if (context_wgl->do_frame_sync)
+ {
+ glFinish ();
+
+ if (can_wait)
+ {
+ gint64 ust, msc, sbc;
+
+ wglGetSyncValuesOML (context_wgl->wgl_hdc, &ust, &msc, &sbc);
+ wglWaitForMscOML (context_wgl->wgl_hdc,
+ 0,
+ 2,
+ (msc + 1) % 2,
+ &ust, &msc, &sbc);
+ }
+
+ SwapBuffers (context_wgl->wgl_hdc);
+ }
+}
+
+static void
+gdk_win32_gl_context_wgl_begin_frame (GdkDrawContext *draw_context,
+ cairo_region_t *update_area)
+{
+ GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
+ GdkSurface *surface;
+
+ surface = gdk_gl_context_get_surface (context);
+
+ gdk_win32_surface_handle_queued_move_resize (draw_context);
+
+ GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_wgl_parent_class)->begin_frame (draw_context, update_area);
+}
+
+static int
+gdk_init_dummy_wgl_context (GdkWin32Display *display_win32);
+
+#define PIXEL_ATTRIBUTES 17
+
+static int
+get_wgl_pfd (HDC hdc,
+ PIXELFORMATDESCRIPTOR *pfd,
+ GdkWin32Display *display_win32)
+{
+ int best_pf = 0;
+
+ pfd->nSize = sizeof (PIXELFORMATDESCRIPTOR);
+
+ if (display_win32 != NULL && display_win32->hasWglARBPixelFormat)
+ {
+ UINT num_formats;
+ int colorbits = GetDeviceCaps (hdc, BITSPIXEL);
+ int i = 0;
+ int pixelAttribs[PIXEL_ATTRIBUTES];
+
+ /* Save up the HDC and HGLRC that we are currently using, to restore back to it when we are done here
*/
+ HDC hdc_current = wglGetCurrentDC ();
+ HGLRC hglrc_current = wglGetCurrentContext ();
+
+ /* Update PIXEL_ATTRIBUTES above if any groups are added here! */
+ pixelAttribs[i] = WGL_DRAW_TO_WINDOW_ARB;
+ pixelAttribs[i++] = GL_TRUE;
+
+ pixelAttribs[i++] = WGL_SUPPORT_OPENGL_ARB;
+ pixelAttribs[i++] = GL_TRUE;
+
+ pixelAttribs[i++] = WGL_DOUBLE_BUFFER_ARB;
+ pixelAttribs[i++] = GL_TRUE;
+
+ pixelAttribs[i++] = WGL_ACCELERATION_ARB;
+ pixelAttribs[i++] = WGL_FULL_ACCELERATION_ARB;
+
+ pixelAttribs[i++] = WGL_PIXEL_TYPE_ARB;
+ pixelAttribs[i++] = WGL_TYPE_RGBA_ARB;
+
+ pixelAttribs[i++] = WGL_COLOR_BITS_ARB;
+ pixelAttribs[i++] = colorbits;
+
+ /* end of "Update PIXEL_ATTRIBUTES above if any groups are added here!" */
+
+ if (display_win32->hasWglARBmultisample)
+ {
+ pixelAttribs[i++] = WGL_SAMPLE_BUFFERS_ARB;
+ pixelAttribs[i++] = 1;
+
+ pixelAttribs[i++] = WGL_SAMPLES_ARB;
+ pixelAttribs[i++] = 8;
+ }
+
+ pixelAttribs[i++] = 0; /* end of pixelAttribs */
+ best_pf = gdk_init_dummy_wgl_context (display_win32);
+
+ if (!wglMakeCurrent (display_win32->dummy_context_wgl.hdc,
+ display_win32->dummy_context_wgl.hglrc))
+ {
+ wglMakeCurrent (hdc_current, hglrc_current);
+ return 0;
+ }
+
+ wglChoosePixelFormatARB (hdc,
+ pixelAttribs,
+ NULL,
+ 1,
+ &best_pf,
+ &num_formats);
+
+ /* Go back to the HDC that we were using, since we are done with the dummy HDC and GL Context */
+ wglMakeCurrent (hdc_current, hglrc_current);
+ }
+ else
+ {
+ pfd->nVersion = 1;
+ pfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
+ pfd->iPixelType = PFD_TYPE_RGBA;
+ pfd->cColorBits = GetDeviceCaps (hdc, BITSPIXEL);
+ pfd->cAlphaBits = 8;
+ pfd->dwLayerMask = PFD_MAIN_PLANE;
+
+ best_pf = ChoosePixelFormat (hdc, pfd);
+ }
+
+ return best_pf;
+}
+
+/* in WGL, for many OpenGL items, we need a dummy WGL context, so create
+ * one and cache it for later use
+ */
+static int
+gdk_init_dummy_wgl_context (GdkWin32Display *display_win32)
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ gboolean set_pixel_format_result = FALSE;
+ int best_idx = 0;
+
+ if (display_win32->dummy_context_wgl.hdc == NULL)
+ display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
+
+ memset (&pfd, 0, sizeof (PIXELFORMATDESCRIPTOR));
+
+ best_idx = get_wgl_pfd (display_win32->dummy_context_wgl.hdc, &pfd, NULL);
+
+ if (best_idx != 0)
+ set_pixel_format_result = SetPixelFormat (display_win32->dummy_context_wgl.hdc,
+ best_idx,
+ &pfd);
+
+ if (best_idx == 0 || !set_pixel_format_result)
+ return 0;
+
+ display_win32->dummy_context_wgl.hglrc =
+ wglCreateContext (display_win32->dummy_context_wgl.hdc);
+
+ if (display_win32->dummy_context_wgl.hglrc == NULL)
+ return 0;
+
+ return best_idx;
+}
+
+gboolean
+gdk_win32_display_init_wgl (GdkDisplay *display,
+ GError **error)
+{
+ int best_idx = 0;
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+ HDC hdc;
+
+ if (display_win32->wgl_pixel_format != 0)
+ return TRUE;
+
+ /* acquire and cache dummy Window (HWND & HDC) and
+ * dummy GL Context, it is used to query functions
+ * and used for other stuff as well
+ */
+ best_idx = gdk_init_dummy_wgl_context (display_win32);
+ hdc = display_win32->dummy_context_wgl.hdc;
+
+ if (best_idx == 0 ||
+ !wglMakeCurrent (hdc, display_win32->dummy_context_wgl.hglrc))
+ {
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ _("No GL implementation is available"));
+
+ return FALSE;
+ }
+
+ display_win32->wgl_pixel_format = best_idx;
+ display_win32->gl_version = epoxy_gl_version ();
+
+ display_win32->hasWglARBCreateContext =
+ epoxy_has_wgl_extension (hdc, "WGL_ARB_create_context");
+ display_win32->hasWglEXTSwapControl =
+ epoxy_has_wgl_extension (hdc, "WGL_EXT_swap_control");
+ display_win32->hasWglOMLSyncControl =
+ epoxy_has_wgl_extension (hdc, "WGL_OML_sync_control");
+ display_win32->hasWglARBPixelFormat =
+ epoxy_has_wgl_extension (hdc, "WGL_ARB_pixel_format");
+ display_win32->hasWglARBmultisample =
+ epoxy_has_wgl_extension (hdc, "WGL_ARB_multisample");
+
+ GDK_NOTE (OPENGL,
+ g_print ("WGL API version %d.%d found\n"
+ " - Vendor: %s\n"
+ " - Checked extensions:\n"
+ "\t* WGL_ARB_pixel_format: %s\n"
+ "\t* WGL_ARB_create_context: %s\n"
+ "\t* WGL_EXT_swap_control: %s\n"
+ "\t* WGL_OML_sync_control: %s\n"
+ "\t* WGL_ARB_multisample: %s\n",
+ display_win32->gl_version / 10,
+ display_win32->gl_version % 10,
+ glGetString (GL_VENDOR),
+ display_win32->hasWglARBPixelFormat ? "yes" : "no",
+ display_win32->hasWglARBCreateContext ? "yes" : "no",
+ display_win32->hasWglEXTSwapControl ? "yes" : "no",
+ display_win32->hasWglOMLSyncControl ? "yes" : "no",
+ display_win32->hasWglARBmultisample ? "yes" : "no"));
+
+ wglMakeCurrent (NULL, NULL);
+
+ return TRUE;
+}
+
+/* Setup the legacy context after creating it */
+static gboolean
+ensure_legacy_wgl_context (HDC hdc,
+ HGLRC hglrc_legacy,
+ GdkGLContext *share)
+{
+ GdkWin32GLContextWGL *context_wgl;
+
+ if (!wglMakeCurrent (hdc, hglrc_legacy))
+ return FALSE;
+
+ if (share != NULL)
+ {
+ context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
+
+ return wglShareLists (hglrc_legacy, context_wgl->wgl_context);
+ }
+
+ return TRUE;
+}
+
+static HGLRC
+create_wgl_context_with_attribs (HDC hdc,
+ HGLRC hglrc_base,
+ GdkGLContext *share,
+ int flags,
+ int major,
+ int minor,
+ gboolean *is_legacy)
+{
+ HGLRC hglrc;
+ GdkWin32GLContextWGL *context_wgl;
+
+ /* if we have wglCreateContextAttribsARB(), create a
+ * context with the compatibility profile if a legacy
+ * context is requested, or when we go into fallback mode
+ */
+ int profile = *is_legacy ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :
+ WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+
+ int attribs[] = {
+ WGL_CONTEXT_PROFILE_MASK_ARB, profile,
+ WGL_CONTEXT_MAJOR_VERSION_ARB, *is_legacy ? 3 : major,
+ WGL_CONTEXT_MINOR_VERSION_ARB, *is_legacy ? 0 : minor,
+ WGL_CONTEXT_FLAGS_ARB, flags,
+ 0
+ };
+
+ if (share != NULL)
+ context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
+
+ hglrc = wglCreateContextAttribsARB (hdc,
+ share != NULL ? context_wgl->wgl_context : NULL,
+ attribs);
+
+ return hglrc;
+}
+
+static HGLRC
+create_wgl_context (HDC hdc,
+ GdkGLContext *share,
+ int flags,
+ int major,
+ int minor,
+ gboolean *is_legacy,
+ gboolean hasWglARBCreateContext)
+{
+ /* We need a legacy context for *all* cases */
+ HGLRC hglrc_base = wglCreateContext (hdc);
+ gboolean success = TRUE;
+
+ /* Save up the HDC and HGLRC that we are currently using, to restore back to it when we are done here */
+ HDC hdc_current = wglGetCurrentDC ();
+ HGLRC hglrc_current = wglGetCurrentContext ();
+
+ /* if we have no wglCreateContextAttribsARB(), return the legacy context when all is set */
+ if (*is_legacy && !hasWglARBCreateContext)
+ {
+ if (ensure_legacy_wgl_context (hdc, hglrc_base, share))
+ {
+ wglMakeCurrent (hdc_current, hglrc_current);
+ return hglrc_base;
+ }
+
+ success = FALSE;
+ goto gl_fail;
+ }
+ else
+ {
+ HGLRC hglrc = NULL;
+
+ if (!wglMakeCurrent (hdc, hglrc_base))
+ {
+ success = FALSE;
+ goto gl_fail;
+ }
+
+ /*
+ * We need a Core GL 4.1 context in order to use the GL support in
+ * the GStreamer media widget backend, but wglCreateContextAttribsARB()
+ * may only give us the GL context version that we ask for here, and
+ * nothing more. So, if we are asking for a pre-GL 4.1 context,
+ * try to ask for a 4.1 context explicitly first. If that is not supported,
+ * then we fall back to whatever version that we were asking for (or, even a
+ * legacy context if that fails), at a price of not able to have GL support
+ * for the media GStreamer backend.
+ */
+ if (major < 4 || (major == 4 && minor < 1))
+ hglrc = create_wgl_context_with_attribs (hdc,
+ hglrc_base,
+ share,
+ flags,
+ 4,
+ 1,
+ is_legacy);
+
+ if (hglrc == NULL)
+ hglrc = create_wgl_context_with_attribs (hdc,
+ hglrc_base,
+ share,
+ flags,
+ major,
+ minor,
+ is_legacy);
+
+ /* return the legacy context we have if it could be setup properly, in case the 3.0+ context creation
failed */
+ if (hglrc == NULL)
+ {
+ if (!(*is_legacy))
+ {
+ /* If we aren't using a legacy context in the beginning, try again with a compatibility
profile 3.0 context */
+ hglrc = create_wgl_context_with_attribs (hdc,
+ hglrc_base,
+ share,
+ flags,
+ 0, 0,
+ is_legacy);
+
+ *is_legacy = TRUE;
+ }
+
+ if (hglrc == NULL)
+ {
+ if (!ensure_legacy_wgl_context (hdc, hglrc_base, share))
+ success = FALSE;
+ }
+
+ if (success)
+ GDK_NOTE (OPENGL, g_print ("Using legacy context as fallback\n"));
+ }
+
+gl_fail:
+
+ if (!success)
+ {
+ wglMakeCurrent (NULL, NULL);
+ wglDeleteContext (hglrc_base);
+ return NULL;
+ }
+
+ wglMakeCurrent (hdc_current, hglrc_current);
+
+ if (hglrc != NULL)
+ {
+ wglDeleteContext (hglrc_base);
+ return hglrc;
+ }
+
+ return hglrc_base;
+ }
+}
+
+static gboolean
+set_wgl_pixformat_for_hdc (HDC hdc,
+ int *best_idx,
+ GdkWin32Display *display_win32)
+{
+ gboolean already_checked = TRUE;
+ *best_idx = GetPixelFormat (hdc);
+
+ /* one is only allowed to call SetPixelFormat(), and so ChoosePixelFormat()
+ * one single time per window HDC
+ */
+ if (*best_idx == 0)
+ {
+ PIXELFORMATDESCRIPTOR pfd;
+ gboolean set_pixel_format_result = FALSE;
+
+ GDK_NOTE (OPENGL, g_print ("requesting pixel format...\n"));
+ already_checked = FALSE;
+ *best_idx = get_wgl_pfd (hdc, &pfd, display_win32);
+
+ if (*best_idx != 0)
+ set_pixel_format_result = SetPixelFormat (hdc, *best_idx, &pfd);
+
+ /* ChoosePixelFormat() or SetPixelFormat() failed, bail out */
+ if (*best_idx == 0 || !set_pixel_format_result)
+ return FALSE;
+ }
+
+ GDK_NOTE (OPENGL, g_print ("%s""requested and set pixel format: %d\n", already_checked ? "already " : "",
*best_idx));
+
+ return TRUE;
+}
+
+static gboolean
+gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
+ GError **error)
+{
+ GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (context);
+
+ gboolean debug_bit, compat_bit, legacy_bit;
+
+ /* request flags and specific versions for core (3.2+) WGL context */
+ int flags = 0;
+ int major = 0;
+ int minor = 0;
+ HGLRC hglrc;
+ int pixel_format;
+ HDC hdc;
+ HWND hwnd;
+
+ GdkSurface *surface = gdk_gl_context_get_surface (context);
+ GdkDisplay *display = gdk_gl_context_get_display (context);
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+ GdkGLContext *share = gdk_display_get_gl_context (display);
+
+ gdk_gl_context_get_required_version (context, &major, &minor);
+ debug_bit = gdk_gl_context_get_debug_enabled (context);
+ compat_bit = gdk_gl_context_get_forward_compatible (context);
+
+ if (surface != NULL)
+ {
+ hwnd = GDK_SURFACE_HWND (surface);
+ context_wgl->wgl_hdc = hdc = GetDC (hwnd);
+ }
+ else
+ {
+ hwnd = display_win32->hwnd;
+ hdc = display_win32->dummy_context_wgl.hdc;
+ }
+
+ /*
+ * A legacy context cannot be shared with core profile ones, so this means we
+ * must stick to a legacy context if the shared context is a legacy context
+ */
+ legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ?
+ TRUE :
+ share != NULL && gdk_gl_context_is_legacy (share);
+
+ if (!set_wgl_pixformat_for_hdc (hdc,
+ &pixel_format,
+ display_win32))
+ {
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_UNSUPPORTED_FORMAT,
+ _("No available configurations for the given pixel format"));
+
+ return FALSE;
+ }
+
+ /* if there isn't wglCreateContextAttribsARB() on WGL, use a legacy context */
+ if (!legacy_bit)
+ legacy_bit = !display_win32->hasWglARBCreateContext;
+ if (debug_bit)
+ flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
+ if (compat_bit)
+ flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+
+ GDK_NOTE (OPENGL,
+ g_print ("Creating %s WGL context (version:%d.%d, debug:%s, forward:%s, legacy: %s)\n",
+ compat_bit ? "core" : "compat",
+ major,
+ minor,
+ debug_bit ? "yes" : "no",
+ compat_bit ? "yes" : "no",
+ legacy_bit ? "yes" : "no"));
+
+ hglrc = create_wgl_context (hdc,
+ share,
+ flags,
+ major,
+ minor,
+ &legacy_bit,
+ display_win32->hasWglARBCreateContext);
+
+ if (hglrc == NULL)
+ {
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ _("Unable to create a GL context"));
+ return FALSE;
+ }
+
+ GDK_NOTE (OPENGL,
+ g_print ("Created WGL context[%p], pixel_format=%d\n",
+ hglrc,
+ pixel_format));
+
+ context_wgl->wgl_context = hglrc;
+
+ /* No GLES, WGL does not support using EGL contexts */
+ gdk_gl_context_set_use_es (context, FALSE);
+
+ /* Ensure that any other context is created with a legacy bit set */
+ gdk_gl_context_set_is_legacy (context, legacy_bit);
+
+ return TRUE;
+}
+
+static gboolean
+gdk_win32_gl_context_wgl_clear_current (GdkGLContext *context)
+{
+ wglMakeCurrent (NULL, NULL);
+ return TRUE;
+}
+
+static gboolean
+gdk_win32_gl_context_wgl_make_current (GdkGLContext *context,
+ gboolean surfaceless)
+{
+ GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (context);
+ GdkDisplay *display = gdk_gl_context_get_display (context);
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+ GdkSurface *surface;
+ HDC hdc;
+
+ if (surfaceless)
+ hdc = display_win32->dummy_context_wgl.hdc;
+ else
+ hdc = context_wgl->wgl_hdc;
+
+ if (!wglMakeCurrent (hdc, context_wgl->wgl_context))
+ return FALSE;
+
+ if (!surfaceless && display_win32->hasWglEXTSwapControl)
+ {
+ gboolean do_frame_sync = FALSE;
+ GdkSurface *surface = gdk_gl_context_get_surface (context);
+
+ /* If there is compositing there is no particular need to delay
+ * the swap when drawing on the offscreen, rendering to the screen
+ * happens later anyway, and its up to the compositor to sync that
+ * to the vblank. */
+ do_frame_sync = ! gdk_display_is_composited (display);
+
+ if (do_frame_sync != context_wgl->do_frame_sync)
+ {
+ context_wgl->do_frame_sync = do_frame_sync;
+
+ wglSwapIntervalEXT (do_frame_sync ? 1 : 0);
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+gdk_win32_gl_context_wgl_class_init (GdkWin32GLContextWGLClass *klass)
+{
+ GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
+ GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ context_class->realize = gdk_win32_gl_context_wgl_realize;
+ context_class->make_current = gdk_win32_gl_context_wgl_make_current;
+ context_class->clear_current = gdk_win32_gl_context_wgl_clear_current;
+
+ draw_context_class->begin_frame = gdk_win32_gl_context_wgl_begin_frame;
+ draw_context_class->end_frame = gdk_win32_gl_context_wgl_end_frame;
+ gobject_class->dispose = gdk_win32_gl_context_wgl_dispose;
+}
+
+static void
+gdk_win32_gl_context_wgl_init (GdkWin32GLContextWGL *wgl_context)
+{
+}
+
+void gdk_win32_gl_context_wgl_bind_surface (GdkWin32GLContextWGL *wgl_context,
+ GdkWin32Surface *impl)
+{
+ wgl_context->wgl_hwnd = impl->handle;
+ wgl_context->wgl_hdc = GetDC (impl->handle);
+}
+
+/**
+ * gdk_win32_display_get_wgl_version:
+ * @display: a `GdkDisplay`
+ * @major: (out): return location for the WGL major version
+ * @minor: (out): return location for the WGL minor version
+ *
+ * Retrieves the version of the WGL implementation.
+ *
+ * Returns: %TRUE if WGL is available
+ */
+gboolean
+gdk_win32_display_get_wgl_version (GdkDisplay *display,
+ int *major,
+ int *minor)
+{
+ GdkWin32Display *display_win32;
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+
+ if (!GDK_IS_WIN32_DISPLAY (display))
+ return FALSE;
+
+ display_win32 = GDK_WIN32_DISPLAY (display);
+ if (display_win32->wgl_pixel_format == 0)
+ return FALSE;
+
+ if (major != NULL)
+ *major = display_win32->gl_version / 10;
+ if (minor != NULL)
+ *minor = display_win32->gl_version % 10;
+
+ return TRUE;
+}
diff --git a/gdk/win32/gdkglcontext-win32.c b/gdk/win32/gdkglcontext-win32.c
index 351ae37491..dea1a8d4fc 100644
--- a/gdk/win32/gdkglcontext-win32.c
+++ b/gdk/win32/gdkglcontext-win32.c
@@ -45,1181 +45,14 @@
# include <epoxy/egl.h>
#endif
-G_DEFINE_TYPE (GdkWin32GLContext, gdk_win32_gl_context, GDK_TYPE_GL_CONTEXT)
-
-static void
-_gdk_win32_gl_context_dispose (GObject *gobject)
-{
- GdkGLContext *context = GDK_GL_CONTEXT (gobject);
- GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (gobject);
- GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context));
- GdkSurface *surface = gdk_gl_context_get_surface (context);
-
- if (display_win32 != NULL)
- {
- if (display_win32->have_wgl)
- {
- if (wglGetCurrentContext () == context_win32->hglrc)
- wglMakeCurrent (NULL, NULL);
-
- GDK_NOTE (OPENGL, g_print ("Destroying WGL context\n"));
-
- wglDeleteContext (context_win32->hglrc);
- context_win32->hglrc = NULL;
-
- ReleaseDC (display_win32->gl_hwnd, context_win32->gl_hdc);
- }
-
-#ifdef GDK_WIN32_ENABLE_EGL
- else if (display_win32->have_egl)
- {
- if (eglGetCurrentContext () == context_win32->egl_context)
- eglMakeCurrent(display_win32->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
-
- GDK_NOTE (OPENGL, g_message ("Destroying EGL (ANGLE) context"));
-
- eglDestroyContext (display_win32->egl_disp,
- context_win32->egl_context);
- context_win32->egl_context = EGL_NO_CONTEXT;
-
- ReleaseDC (display_win32->gl_hwnd, context_win32->gl_hdc);
- }
-#endif
- }
-
- G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
-}
-
-#ifdef GDK_WIN32_ENABLE_EGL
-static gboolean
-_get_is_egl_force_redraw (GdkSurface *surface)
-{
- /* We only need to call gdk_window_invalidate_rect () if necessary */
- if (surface->gl_paint_context != NULL && gdk_gl_context_get_use_es (surface->gl_paint_context))
- {
- GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
-
- return impl->egl_force_redraw_all;
- }
- return FALSE;
-}
-
-static void
-_reset_egl_force_redraw (GdkSurface *surface)
-{
- if (surface->gl_paint_context != NULL && gdk_gl_context_get_use_es (surface->gl_paint_context))
- {
- GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
-
- if (impl->egl_force_redraw_all)
- impl->egl_force_redraw_all = FALSE;
- }
-}
-#endif
-
-static void
-gdk_win32_gl_context_end_frame (GdkDrawContext *draw_context,
- cairo_region_t *painted)
-{
- GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
- GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
- GdkSurface *surface = gdk_gl_context_get_surface (context);
- GdkWin32Display *display = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
- cairo_rectangle_int_t whole_window;
-
- GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_parent_class)->end_frame (draw_context, painted);
-
- gdk_gl_context_make_current (context);
- whole_window = (GdkRectangle) { 0, 0, gdk_surface_get_width (surface), gdk_surface_get_height (surface) };
-
- if (!gdk_gl_context_get_use_es (context))
- {
- gboolean can_wait = display->hasWglOMLSyncControl;
-
- if (context_win32->do_frame_sync)
- {
- glFinish ();
-
- if (can_wait)
- {
- gint64 ust, msc, sbc;
-
- wglGetSyncValuesOML (context_win32->gl_hdc, &ust, &msc, &sbc);
- wglWaitForMscOML (context_win32->gl_hdc,
- 0,
- 2,
- (msc + 1) % 2,
- &ust, &msc, &sbc);
- }
- }
-
- SwapBuffers (context_win32->gl_hdc);
- }
-#ifdef GDK_WIN32_ENABLE_EGL
- else
- {
- EGLSurface egl_surface = _gdk_win32_surface_get_egl_surface (surface, context_win32->egl_config,
FALSE);
- gboolean force_egl_redraw_all = _get_is_egl_force_redraw (surface);
-
- if (force_egl_redraw_all)
- {
- GdkRectangle rect = {0, 0, gdk_surface_get_width (surface), gdk_surface_get_height (surface)};
-
- /* We need to do gdk_window_invalidate_rect() so that we don't get glitches after maximizing or
- * restoring or using aerosnap
- */
- gdk_surface_invalidate_rect (surface, &rect);
- _reset_egl_force_redraw (surface);
- }
-
- eglSwapBuffers (display->egl_disp, egl_surface);
- }
-#endif
-}
-
-static void
-gdk_win32_gl_context_begin_frame (GdkDrawContext *draw_context,
- cairo_region_t *update_area)
-{
- GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
- GdkSurface *surface;
-
- surface = gdk_gl_context_get_surface (context);
-
- gdk_win32_surface_handle_queued_move_resize (draw_context);
-
- GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_parent_class)->begin_frame (draw_context, update_area);
-}
-
-typedef struct
-{
- ATOM wc_atom;
- HWND hwnd;
- HDC hdc;
- HGLRC hglrc;
- gboolean inited;
-} GdkWGLDummy;
-
-static void
-_destroy_dummy_gl_context (GdkWGLDummy dummy)
-{
- if (dummy.hglrc != NULL)
- {
- wglDeleteContext (dummy.hglrc);
- dummy.hglrc = NULL;
- }
- if (dummy.hdc != NULL)
- {
- DeleteDC (dummy.hdc);
- dummy.hdc = NULL;
- }
- if (dummy.hwnd != NULL)
- {
- DestroyWindow (dummy.hwnd);
- dummy.hwnd = NULL;
- }
- if (dummy.wc_atom != 0)
- {
- UnregisterClass (MAKEINTATOM (dummy.wc_atom), GetModuleHandle (NULL));
- dummy.wc_atom = 0;
- }
- dummy.inited = FALSE;
-}
-
-/* Yup, we need to create a dummy window for the dummy WGL context */
-static void
-_get_dummy_window_hwnd (GdkWGLDummy *dummy)
-{
- WNDCLASSEX dummy_wc;
-
- memset (&dummy_wc, 0, sizeof (WNDCLASSEX));
-
- dummy_wc.cbSize = sizeof( WNDCLASSEX );
- dummy_wc.style = CS_OWNDC;
- dummy_wc.lpfnWndProc = (WNDPROC) DefWindowProc;
- dummy_wc.cbClsExtra = 0;
- dummy_wc.cbWndExtra = 0;
- dummy_wc.hInstance = GetModuleHandle( NULL );
- dummy_wc.hIcon = 0;
- dummy_wc.hCursor = NULL;
- dummy_wc.hbrBackground = 0;
- dummy_wc.lpszMenuName = 0;
- dummy_wc.lpszClassName = "dummy";
- dummy_wc.hIconSm = 0;
-
- dummy->wc_atom = RegisterClassEx (&dummy_wc);
-
- dummy->hwnd =
- CreateWindowEx (WS_EX_APPWINDOW,
- MAKEINTATOM (dummy->wc_atom),
- "",
- WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
- 0,
- 0,
- 0,
- 0,
- NULL,
- NULL,
- GetModuleHandle (NULL),
- NULL);
-}
-
-static int
-_gdk_init_dummy_context (GdkWGLDummy *dummy);
-
-#define PIXEL_ATTRIBUTES 17
-
-static int
-_get_wgl_pfd (HDC hdc,
- PIXELFORMATDESCRIPTOR *pfd,
- GdkWin32Display *display)
-{
- int best_pf = 0;
-
- pfd->nSize = sizeof (PIXELFORMATDESCRIPTOR);
-
- if (display != NULL && display->hasWglARBPixelFormat)
- {
- GdkWGLDummy dummy;
- UINT num_formats;
- int colorbits = GetDeviceCaps (hdc, BITSPIXEL);
- guint extra_fields = 1;
- int i = 0;
- int pixelAttribs[PIXEL_ATTRIBUTES];
-
- /* Save up the HDC and HGLRC that we are currently using, to restore back to it when we are done here
*/
- HDC hdc_current = wglGetCurrentDC ();
- HGLRC hglrc_current = wglGetCurrentContext ();
-
- if (display->hasWglARBmultisample)
- {
- /* 2 pairs of values needed for multisampling/AA support */
- extra_fields += 2 * 2;
- }
-
- /* Update PIXEL_ATTRIBUTES above if any groups are added here! */
- /* one group contains a value pair for both pixelAttribs and pixelAttribsNoAlpha */
- pixelAttribs[i] = WGL_DRAW_TO_WINDOW_ARB;
- pixelAttribs[i++] = GL_TRUE;
-
- pixelAttribs[i++] = WGL_SUPPORT_OPENGL_ARB;
- pixelAttribs[i++] = GL_TRUE;
-
- pixelAttribs[i++] = WGL_DOUBLE_BUFFER_ARB;
- pixelAttribs[i++] = GL_TRUE;
-
- pixelAttribs[i++] = WGL_ACCELERATION_ARB;
- pixelAttribs[i++] = WGL_FULL_ACCELERATION_ARB;
-
- pixelAttribs[i++] = WGL_PIXEL_TYPE_ARB;
- pixelAttribs[i++] = WGL_TYPE_RGBA_ARB;
-
- pixelAttribs[i++] = WGL_COLOR_BITS_ARB;
- pixelAttribs[i++] = colorbits;
-
- /* end of "Update PIXEL_ATTRIBUTES above if any groups are added here!" */
-
- if (display->hasWglARBmultisample)
- {
- pixelAttribs[i++] = WGL_SAMPLE_BUFFERS_ARB;
- pixelAttribs[i++] = 1;
-
- pixelAttribs[i++] = WGL_SAMPLES_ARB;
- pixelAttribs[i++] = 8;
- }
-
- pixelAttribs[i++] = 0; /* end of pixelAttribs */
-
- memset (&dummy, 0, sizeof (GdkWGLDummy));
-
- /* acquire and cache dummy Window (HWND & HDC) and
- * dummy GL Context, we need it for wglChoosePixelFormatARB()
- */
- best_pf = _gdk_init_dummy_context (&dummy);
-
- if (best_pf == 0 || !wglMakeCurrent (dummy.hdc, dummy.hglrc))
- {
- wglMakeCurrent (hdc_current, hglrc_current);
- return 0;
- }
-
- wglChoosePixelFormatARB (hdc,
- pixelAttribs,
- NULL,
- 1,
- &best_pf,
- &num_formats);
-
- /* Go back to the HDC that we were using, since we are done with the dummy HDC and GL Context */
- wglMakeCurrent (hdc_current, hglrc_current);
- _destroy_dummy_gl_context (dummy);
- }
- else
- {
- pfd->nVersion = 1;
- pfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
- pfd->iPixelType = PFD_TYPE_RGBA;
- pfd->cColorBits = GetDeviceCaps (hdc, BITSPIXEL);
- pfd->cAlphaBits = 8;
- pfd->dwLayerMask = PFD_MAIN_PLANE;
-
- best_pf = ChoosePixelFormat (hdc, pfd);
- }
-
- return best_pf;
-}
-
-/* in WGL, for many OpenGL items, we need a dummy WGL context, so create
- * one and cache it for later use
- */
-static int
-_gdk_init_dummy_context (GdkWGLDummy *dummy)
-{
- PIXELFORMATDESCRIPTOR pfd;
- gboolean set_pixel_format_result = FALSE;
- int best_idx = 0;
-
- _get_dummy_window_hwnd (dummy);
-
- dummy->hdc = GetDC (dummy->hwnd);
- memset (&pfd, 0, sizeof (PIXELFORMATDESCRIPTOR));
-
- best_idx = _get_wgl_pfd (dummy->hdc, &pfd, NULL);
-
- if (best_idx != 0)
- set_pixel_format_result = SetPixelFormat (dummy->hdc,
- best_idx,
- &pfd);
-
- if (best_idx == 0 || !set_pixel_format_result)
- return 0;
-
- dummy->hglrc = wglCreateContext (dummy->hdc);
- if (dummy->hglrc == NULL)
- return 0;
-
- dummy->inited = TRUE;
-
- return best_idx;
-}
-
-#ifdef GDK_WIN32_ENABLE_EGL
-
-#ifndef EGL_PLATFORM_ANGLE_ANGLE
-#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
-#endif
-
-#ifndef EGL_PLATFORM_ANGLE_TYPE_ANGLE
-#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
-#endif
-
-#ifndef EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE
-#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
-#endif
-
-static EGLDisplay
-_gdk_win32_get_egl_display (GdkWin32Display *display)
-{
- EGLDisplay disp;
-
- if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
- {
- PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = (void *) eglGetProcAddress
("eglGetPlatformDisplayEXT");
- if (getPlatformDisplay)
- {
- EGLint disp_attr[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_NONE};
-
- disp = getPlatformDisplay (EGL_PLATFORM_ANGLE_ANGLE, display->hdc_egl_temp, disp_attr);
-
- if (disp != EGL_NO_DISPLAY)
- return disp;
- }
- }
- return eglGetDisplay (display->hdc_egl_temp);
-}
-#endif
-
-static gboolean
-_gdk_win32_display_init_gl (GdkDisplay *display)
-{
- GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
- int best_idx = 0;
-
- gboolean disable_wgl = FALSE;
-
-#ifdef GDK_WIN32_ENABLE_EGL
- EGLDisplay egl_disp;
-
- disable_wgl = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
- display_win32->running_on_arm64;
-#endif
-
- if (display_win32->have_wgl
-#ifdef GDK_WIN32_ENABLE_EGL
- || display_win32->have_egl
-#endif
- )
- return TRUE;
-
- if (!disable_wgl)
- {
- GdkWGLDummy dummy;
- memset (&dummy, 0, sizeof (GdkWGLDummy));
-
- /* acquire and cache dummy Window (HWND & HDC) and
- * dummy GL Context, it is used to query functions
- * and used for other stuff as well
- */
- best_idx = _gdk_init_dummy_context (&dummy);
-
- if (best_idx == 0 || !wglMakeCurrent (dummy.hdc, dummy.hglrc))
- return FALSE;
-
- display_win32->have_wgl = TRUE;
- display_win32->gl_version = epoxy_gl_version ();
-
- display_win32->hasWglARBCreateContext =
- epoxy_has_wgl_extension (dummy.hdc, "WGL_ARB_create_context");
- display_win32->hasWglEXTSwapControl =
- epoxy_has_wgl_extension (dummy.hdc, "WGL_EXT_swap_control");
- display_win32->hasWglOMLSyncControl =
- epoxy_has_wgl_extension (dummy.hdc, "WGL_OML_sync_control");
- display_win32->hasWglARBPixelFormat =
- epoxy_has_wgl_extension (dummy.hdc, "WGL_ARB_pixel_format");
- display_win32->hasWglARBmultisample =
- epoxy_has_wgl_extension (dummy.hdc, "WGL_ARB_multisample");
-
- GDK_NOTE (OPENGL,
- g_print ("WGL API version %d.%d found\n"
- " - Vendor: %s\n"
- " - Checked extensions:\n"
- "\t* WGL_ARB_pixel_format: %s\n"
- "\t* WGL_ARB_create_context: %s\n"
- "\t* WGL_EXT_swap_control: %s\n"
- "\t* WGL_OML_sync_control: %s\n"
- "\t* WGL_ARB_multisample: %s\n",
- display_win32->gl_version / 10,
- display_win32->gl_version % 10,
- glGetString (GL_VENDOR),
- display_win32->hasWglARBPixelFormat ? "yes" : "no",
- display_win32->hasWglARBCreateContext ? "yes" : "no",
- display_win32->hasWglEXTSwapControl ? "yes" : "no",
- display_win32->hasWglOMLSyncControl ? "yes" : "no",
- display_win32->hasWglARBmultisample ? "yes" : "no"));
-
- wglMakeCurrent (NULL, NULL);
- _destroy_dummy_gl_context (dummy);
- }
-#ifdef GDK_WIN32_ENABLE_EGL
- else
- {
- egl_disp = _gdk_win32_get_egl_display (display_win32);
-
- if (egl_disp == EGL_NO_DISPLAY || !eglInitialize (egl_disp, NULL, NULL))
- {
- if (egl_disp != EGL_NO_DISPLAY)
- {
- eglTerminate (egl_disp);
- egl_disp = EGL_NO_DISPLAY;
- }
-
- return FALSE;
- }
-
-
- display_win32->egl_disp = egl_disp;
- display_win32->have_egl = TRUE;
- display_win32->egl_version = epoxy_egl_version (egl_disp);
-
- eglBindAPI(EGL_OPENGL_ES_API);
-
- display_win32->hasEglSurfacelessContext =
- epoxy_has_egl_extension (egl_disp, "EGL_KHR_surfaceless_context");
-
- GDK_NOTE (OPENGL,
- g_print ("EGL API version %d.%d found\n"
- " - Vendor: %s\n"
- " - Checked extensions:\n"
- "\t* EGL_KHR_surfaceless_context: %s\n",
- display_win32->egl_version / 10,
- display_win32->egl_version % 10,
- eglQueryString (display_win32->egl_disp, EGL_VENDOR),
- display_win32->hasEglSurfacelessContext ? "yes" : "no"));
- }
-#endif
-
- return TRUE;
-}
-
-/* Setup the legacy context after creating it */
-static gboolean
-_ensure_legacy_gl_context (HDC hdc,
- HGLRC hglrc_legacy,
- GdkGLContext *share)
-{
- GdkWin32GLContext *context_win32;
-
- if (!wglMakeCurrent (hdc, hglrc_legacy))
- return FALSE;
-
- if (share != NULL)
- {
- context_win32 = GDK_WIN32_GL_CONTEXT (share);
-
- return wglShareLists (hglrc_legacy, context_win32->hglrc);
- }
-
- return TRUE;
-}
-
-static HGLRC
-_create_gl_context_with_attribs (HDC hdc,
- HGLRC hglrc_base,
- GdkGLContext *share,
- int flags,
- int major,
- int minor,
- gboolean *is_legacy)
-{
- HGLRC hglrc;
- GdkWin32GLContext *context_win32;
-
- /* if we have wglCreateContextAttribsARB(), create a
- * context with the compatibility profile if a legacy
- * context is requested, or when we go into fallback mode
- */
- int profile = *is_legacy ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :
- WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
-
- int attribs[] = {
- WGL_CONTEXT_PROFILE_MASK_ARB, profile,
- WGL_CONTEXT_MAJOR_VERSION_ARB, *is_legacy ? 3 : major,
- WGL_CONTEXT_MINOR_VERSION_ARB, *is_legacy ? 0 : minor,
- WGL_CONTEXT_FLAGS_ARB, flags,
- 0
- };
-
- if (share != NULL)
- context_win32 = GDK_WIN32_GL_CONTEXT (share);
-
- hglrc = wglCreateContextAttribsARB (hdc,
- share != NULL ? context_win32->hglrc : NULL,
- attribs);
-
- return hglrc;
-}
-
-static HGLRC
-_create_gl_context (HDC hdc,
- GdkGLContext *share,
- int flags,
- int major,
- int minor,
- gboolean *is_legacy,
- gboolean hasWglARBCreateContext)
-{
- /* We need a legacy context for *all* cases */
- HGLRC hglrc_base = wglCreateContext (hdc);
- gboolean success = TRUE;
-
- /* Save up the HDC and HGLRC that we are currently using, to restore back to it when we are done here */
- HDC hdc_current = wglGetCurrentDC ();
- HGLRC hglrc_current = wglGetCurrentContext ();
-
- /* if we have no wglCreateContextAttribsARB(), return the legacy context when all is set */
- if (*is_legacy && !hasWglARBCreateContext)
- {
- if (_ensure_legacy_gl_context (hdc, hglrc_base, share))
- {
- wglMakeCurrent (hdc_current, hglrc_current);
- return hglrc_base;
- }
-
- success = FALSE;
- goto gl_fail;
- }
- else
- {
- HGLRC hglrc = NULL;
-
- if (!wglMakeCurrent (hdc, hglrc_base))
- {
- success = FALSE;
- goto gl_fail;
- }
-
- /*
- * We need a Core GL 4.1 context in order to use the GL support in
- * the GStreamer media widget backend, but wglCreateContextAttribsARB()
- * may only give us the GL context version that we ask for here, and
- * nothing more. So, if we are asking for a pre-GL 4.1 context,
- * try to ask for a 4.1 context explicitly first. If that is not supported,
- * then we fall back to whatever version that we were asking for (or, even a
- * legacy context if that fails), at a price of not able to have GL support
- * for the media GStreamer backend.
- */
- if (major < 4 || (major == 4 && minor < 1))
- hglrc = _create_gl_context_with_attribs (hdc,
- hglrc_base,
- share,
- flags,
- 4,
- 1,
- is_legacy);
-
- if (hglrc == NULL)
- hglrc = _create_gl_context_with_attribs (hdc,
- hglrc_base,
- share,
- flags,
- major,
- minor,
- is_legacy);
-
- /* return the legacy context we have if it could be setup properly, in case the 3.0+ context creation
failed */
- if (hglrc == NULL)
- {
- if (!(*is_legacy))
- {
- /* If we aren't using a legacy context in the beginning, try again with a compatibility
profile 3.0 context */
- hglrc = _create_gl_context_with_attribs (hdc,
- hglrc_base,
- share,
- flags,
- 0, 0,
- is_legacy);
-
- *is_legacy = TRUE;
- }
-
- if (hglrc == NULL)
- {
- if (!_ensure_legacy_gl_context (hdc, hglrc_base, share))
- success = FALSE;
- }
-
- if (success)
- GDK_NOTE (OPENGL, g_print ("Using legacy context as fallback\n"));
- }
-
-gl_fail:
-
- if (!success)
- {
- wglMakeCurrent (NULL, NULL);
- wglDeleteContext (hglrc_base);
- return NULL;
- }
-
- wglMakeCurrent (hdc_current, hglrc_current);
-
- if (hglrc != NULL)
- {
- wglDeleteContext (hglrc_base);
- return hglrc;
- }
-
- return hglrc_base;
- }
-}
-
-static gboolean
-_set_pixformat_for_hdc (HDC hdc,
- int *best_idx,
- GdkWin32Display *display)
-{
- gboolean already_checked = TRUE;
- *best_idx = GetPixelFormat (hdc);
-
- /* one is only allowed to call SetPixelFormat(), and so ChoosePixelFormat()
- * one single time per window HDC
- */
- if (*best_idx == 0)
- {
- PIXELFORMATDESCRIPTOR pfd;
- gboolean set_pixel_format_result = FALSE;
-
- GDK_NOTE (OPENGL, g_print ("requesting pixel format...\n"));
- already_checked = FALSE;
- *best_idx = _get_wgl_pfd (hdc, &pfd, display);
-
- if (*best_idx != 0)
- set_pixel_format_result = SetPixelFormat (hdc, *best_idx, &pfd);
-
- /* ChoosePixelFormat() or SetPixelFormat() failed, bail out */
- if (*best_idx == 0 || !set_pixel_format_result)
- return FALSE;
- }
-
- GDK_NOTE (OPENGL, g_print ("%s""requested and set pixel format: %d\n", already_checked ? "already " : "",
*best_idx));
-
- return TRUE;
-}
-
-#ifdef GDK_WIN32_ENABLE_EGL
-
-#define MAX_EGL_ATTRS 30
-
-static gboolean
-find_eglconfig_for_window (GdkWin32Display *display,
- EGLConfig *egl_config_out,
- EGLint *min_swap_interval_out,
- GError **error)
-{
- EGLint attrs[MAX_EGL_ATTRS];
- EGLint count;
- EGLConfig *configs, chosen_config;
-
- int i = 0;
-
- EGLDisplay egl_disp = display->egl_disp;
-
- attrs[i++] = EGL_CONFORMANT;
- attrs[i++] = EGL_OPENGL_ES2_BIT;
- attrs[i++] = EGL_SURFACE_TYPE;
- attrs[i++] = EGL_WINDOW_BIT;
-
- attrs[i++] = EGL_COLOR_BUFFER_TYPE;
- attrs[i++] = EGL_RGB_BUFFER;
-
- attrs[i++] = EGL_RED_SIZE;
- attrs[i++] = 1;
- attrs[i++] = EGL_GREEN_SIZE;
- attrs[i++] = 1;
- attrs[i++] = EGL_BLUE_SIZE;
- attrs[i++] = 1;
- attrs[i++] = EGL_ALPHA_SIZE;
- attrs[i++] = 1;
-
- attrs[i++] = EGL_NONE;
- g_assert (i < MAX_EGL_ATTRS);
-
- if (!eglChooseConfig (display->egl_disp, attrs, NULL, 0, &count) || count < 1)
- {
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_UNSUPPORTED_FORMAT,
- _("No available configurations for the given pixel format"));
- return FALSE;
- }
-
- configs = g_new (EGLConfig, count);
-
- if (!eglChooseConfig (display->egl_disp, attrs, configs, count, &count) || count < 1)
- {
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_UNSUPPORTED_FORMAT,
- _("No available configurations for the given pixel format"));
- return FALSE;
- }
-
- /* Pick first valid configuration i guess? */
- chosen_config = configs[0];
-
- if (!eglGetConfigAttrib (display->egl_disp, chosen_config,
- EGL_MIN_SWAP_INTERVAL, min_swap_interval_out))
- {
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_NOT_AVAILABLE,
- "Could not retrieve the minimum swap interval");
- g_free (configs);
- return FALSE;
- }
-
- if (egl_config_out != NULL)
- *egl_config_out = chosen_config;
-
- g_free (configs);
-
- return TRUE;
-}
-
-#define N_EGL_ATTRS 16
-
-static EGLContext
-_create_egl_context (EGLDisplay display,
- EGLConfig config,
- GdkGLContext *share,
- int flags,
- int major,
- int minor,
- gboolean *is_legacy)
-{
- EGLContext ctx;
- EGLint context_attribs[N_EGL_ATTRS];
- int i = 0;
-
- /* ANGLE does not support the GL_OES_vertex_array_object extension, so we need to use ES3 directly */
- context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
- context_attribs[i++] = 3;
-
- /* Specify the flags */
- context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
- context_attribs[i++] = flags;
-
- context_attribs[i++] = EGL_NONE;
- g_assert (i < N_EGL_ATTRS);
-
- ctx = eglCreateContext (display,
- config,
- share != NULL ? GDK_WIN32_GL_CONTEXT (share)->egl_context
- : EGL_NO_CONTEXT,
- context_attribs);
-
- if (ctx != EGL_NO_CONTEXT)
- GDK_NOTE (OPENGL, g_message ("Created EGL context[%p]", ctx));
-
- return ctx;
-}
-#endif /* GDK_WIN32_ENABLE_EGL */
-
-static gboolean
-gdk_win32_gl_context_realize (GdkGLContext *context,
- GError **error)
-{
- GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
-
- gboolean debug_bit, compat_bit, legacy_bit;
- gboolean use_es = FALSE;
-
- /* request flags and specific versions for core (3.2+) WGL context */
- int flags = 0;
- int major = 0;
- int minor = 0;
-
- GdkSurface *surface = gdk_gl_context_get_surface (context);
- GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
- GdkDisplay *display = gdk_surface_get_display (surface);
- GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
- GdkGLContext *share = gdk_display_get_gl_context (display);
-
- gdk_gl_context_get_required_version (context, &major, &minor);
- debug_bit = gdk_gl_context_get_debug_enabled (context);
- compat_bit = gdk_gl_context_get_forward_compatible (context);
-
- /*
- * A legacy context cannot be shared with core profile ones, so this means we
- * must stick to a legacy context if the shared context is a legacy context
- */
- if (share != NULL && gdk_gl_context_is_legacy (share))
- legacy_bit = TRUE;
-
- /* if GDK_GL_LEGACY is set, we default to a legacy context */
- legacy_bit = g_getenv ("GDK_GL_LEGACY") != NULL;
-
- use_es = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
- (share != NULL && gdk_gl_context_get_use_es (share));
-
- if (win32_display->have_wgl || !use_es)
- {
- /* These are the real WGL context items that we will want to use later */
- HGLRC hglrc;
- int pixel_format;
-
- if (!_set_pixformat_for_hdc (context_win32->gl_hdc,
- &pixel_format,
- win32_display))
- {
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_UNSUPPORTED_FORMAT,
- _("No available configurations for the given pixel format"));
-
- return FALSE;
- }
-
- /* if there isn't wglCreateContextAttribsARB() on WGL, use a legacy context */
- if (!legacy_bit)
- legacy_bit = !win32_display->hasWglARBCreateContext;
- if (debug_bit)
- flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
- if (compat_bit)
- flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
-
- GDK_NOTE (OPENGL,
- g_print ("Creating %s WGL context (version:%d.%d, debug:%s, forward:%s, legacy: %s)\n",
- compat_bit ? "core" : "compat",
- major,
- minor,
- debug_bit ? "yes" : "no",
- compat_bit ? "yes" : "no",
- legacy_bit ? "yes" : "no"));
-
- hglrc = _create_gl_context (context_win32->gl_hdc,
- share,
- flags,
- major,
- minor,
- &legacy_bit,
- win32_display->hasWglARBCreateContext);
-
- if (hglrc == NULL)
- {
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_NOT_AVAILABLE,
- _("Unable to create a GL context"));
- return FALSE;
- }
-
- GDK_NOTE (OPENGL,
- g_print ("Created WGL context[%p], pixel_format=%d\n",
- hglrc,
- pixel_format));
-
- context_win32->hglrc = hglrc;
- }
-
-#ifdef GDK_WIN32_ENABLE_EGL
- else
- {
- EGLContext egl_context;
- EGLContext ctx;
-
- if (debug_bit)
- flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
- if (compat_bit)
- flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
-
- GDK_NOTE (OPENGL, g_message ("Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s)",
- major, minor,
- debug_bit ? "yes" : "no",
- compat_bit ? "yes" : "no",
- legacy_bit ? "yes" : "no"));
-
- ctx = _create_egl_context (win32_display->egl_disp,
- context_win32->egl_config,
- share,
- flags,
- major,
- minor,
- &legacy_bit);
-
- if (ctx == EGL_NO_CONTEXT)
- {
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_NOT_AVAILABLE,
- _("Unable to create a GL context"));
- return FALSE;
- }
-
- GDK_NOTE (OPENGL,
- g_print ("Created EGL context[%p]\n",
- ctx));
-
- context_win32->egl_context = ctx;
- use_es = TRUE;
- }
-#endif
-
- /* set whether we are using GLES */
- gdk_gl_context_set_use_es (context, use_es);
-
- /* Ensure that any other context is created with a legacy bit set */
- gdk_gl_context_set_is_legacy (context, legacy_bit);
-
- return TRUE;
-}
-
-static gboolean
-gdk_win32_gl_context_clear_current (GdkGLContext *context)
-{
- GdkDisplay *display = gdk_gl_context_get_display (context);
- GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
-
-#ifdef GDK_WIN32_ENABLE_EGL
- if (display_win32->egl_disp != EGL_NO_DISPLAY)
- return eglMakeCurrent (display_win32->egl_disp,
- EGL_NO_SURFACE,
- EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
- else
-#endif
- return wglMakeCurrent (NULL, NULL);
-}
-
-static gboolean
-gdk_win32_gl_context_make_current (GdkGLContext *context,
- gboolean surfaceless)
-{
- GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
- GdkDisplay *display = gdk_gl_context_get_display (context);
- GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
- GdkSurface *surface;
-
- gboolean do_frame_sync = FALSE;
-
- if (!gdk_gl_context_get_use_es (context))
- {
- if (!wglMakeCurrent (context_win32->gl_hdc, context_win32->hglrc))
- return FALSE;
-
- if (!surfaceless && display_win32->hasWglEXTSwapControl)
- {
- surface = gdk_gl_context_get_surface (context);
-
- /* If there is compositing there is no particular need to delay
- * the swap when drawing on the offscreen, rendering to the screen
- * happens later anyway, and its up to the compositor to sync that
- * to the vblank. */
- display = gdk_surface_get_display (surface);
- do_frame_sync = ! gdk_display_is_composited (display);
-
- if (do_frame_sync != context_win32->do_frame_sync)
- {
- context_win32->do_frame_sync = do_frame_sync;
-
- if (do_frame_sync)
- wglSwapIntervalEXT (1);
- else
- wglSwapIntervalEXT (0);
- }
- }
- }
-
-#ifdef GDK_WIN32_ENABLE_EGL
- else
- {
- EGLSurface egl_surface;
-
- surface = gdk_gl_context_get_surface (context);
-
- if (!surfaceless)
- egl_surface = _gdk_win32_surface_get_egl_surface (surface, context_win32->egl_config, FALSE);
- else
- {
- if (display_win32->hasEglSurfacelessContext)
- egl_surface = EGL_NO_SURFACE;
- else
- egl_surface = _gdk_win32_surface_get_egl_surface (surface, context_win32->egl_config, TRUE);
- }
-
- if (!eglMakeCurrent (display_win32->egl_disp,
- egl_surface,
- egl_surface,
- context_win32->egl_context))
- return FALSE;
-
- if (display_win32->egl_min_swap_interval == 0)
- eglSwapInterval (display_win32->egl_disp, 0);
- else
- g_debug ("Can't disable GL swap interval");
- }
-#endif
-
- return TRUE;
-}
+G_DEFINE_ABSTRACT_TYPE (GdkWin32GLContext, gdk_win32_gl_context, GDK_TYPE_GL_CONTEXT)
static void
gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass)
{
- GdkGLContextClass *gl_context_class = GDK_GL_CONTEXT_CLASS(klass);
- GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS(klass);
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gl_context_class->realize = gdk_win32_gl_context_realize;
-
- draw_context_class->begin_frame = gdk_win32_gl_context_begin_frame;
- draw_context_class->end_frame = gdk_win32_gl_context_end_frame;
-
- gobject_class->dispose = _gdk_win32_gl_context_dispose;
}
static void
gdk_win32_gl_context_init (GdkWin32GLContext *self)
{
}
-
-#if 0
-GdkGLContext *
-_gdk_win32_surface_create_gl_context (GdkSurface *surface,
- GError **error)
-{
- GdkDisplay *display = gdk_surface_get_display (surface);
- GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
- GdkWin32GLContext *context = NULL;
-
- /* Acquire and store up the Windows-specific HWND and HDC */
-/* HWND hwnd;*/
- HDC hdc;
-
-#ifdef GDK_WIN32_ENABLE_EGL
- EGLContext egl_context;
- EGLConfig config;
-#endif
-
- display_win32->gl_hwnd = GDK_SURFACE_HWND (surface);
- hdc = GetDC (display_win32->gl_hwnd);
-
-#ifdef GDK_WIN32_ENABLE_EGL
- /* display_win32->hdc_egl_temp should *not* be destroyed here! It is destroyed at dispose()! */
- display_win32->hdc_egl_temp = hdc;
-#endif
-
- if (!_gdk_win32_display_init_gl (display))
- {
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_NOT_AVAILABLE,
- _("No GL implementation is available"));
- return NULL;
- }
-
-#if 0
- if (display_win32->have_wgl)
- {
- hwnd = GDK_SURFACE_HWND (surface);
- hdc = GetDC (hwnd);
-
- display_win32->gl_hwnd = hwnd;
- }
-#endif
-
-#ifdef GDK_WIN32_ENABLE_EGL
- if (display_win32->have_egl && !find_eglconfig_for_window (display_win32, &config,
- &display_win32->egl_min_swap_interval, error))
- return NULL;
-#endif
-
- context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT,
- "surface", surface,
- NULL);
-
- context->gl_hdc = hdc;
-
-#ifdef GDK_WIN32_ENABLE_EGL
- if (display_win32->have_egl)
- context->egl_config = config;
-#endif
-
- return GDK_GL_CONTEXT (context);
-}
-#endif
-
-/**
- * gdk_win32_display_get_wgl_version:
- * @display: a `GdkDisplay`
- * @major: (out): return location for the WGL major version
- * @minor: (out): return location for the WGL minor version
- *
- * Retrieves the version of the WGL implementation.
- *
- * Returns: %TRUE if WGL is available
- */
-gboolean
-gdk_win32_display_get_wgl_version (GdkDisplay *display,
- int *major,
- int *minor)
-{
- g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
-
- if (!GDK_IS_WIN32_DISPLAY (display))
- return FALSE;
-
- if (!_gdk_win32_display_init_gl (display))
- return FALSE;
-
- if (major != NULL)
- *major = GDK_WIN32_DISPLAY (display)->gl_version / 10;
- if (minor != NULL)
- *minor = GDK_WIN32_DISPLAY (display)->gl_version % 10;
-
- return TRUE;
-}
diff --git a/gdk/win32/gdkglcontext-win32.h b/gdk/win32/gdkglcontext-win32.h
index b13fb04913..f8ba71159f 100644
--- a/gdk/win32/gdkglcontext-win32.h
+++ b/gdk/win32/gdkglcontext-win32.h
@@ -35,23 +35,13 @@
G_BEGIN_DECLS
+#define GDK_WIN32_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GDK_TYPE_WIN32_GL_CONTEXT, GdkWin32GLContextClass))
+#define GDK_WIN32_GL_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GDK_TYPE_WIN32_GL_CONTEXT, GdkWin32GLContextClass))
+#define GDK_WIN32_IS_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GDK_TYPE_WIN32_GL_CONTEXT))
+
struct _GdkWin32GLContext
{
GdkGLContext parent_instance;
-
- /* WGL Context Items */
- HGLRC hglrc;
- HDC gl_hdc;
- guint need_alpha_bits : 1;
-
- /* other items */
- guint do_frame_sync : 1;
-
-#ifdef GDK_WIN32_ENABLE_EGL
- /* EGL (Angle) Context Items */
- EGLContext egl_context;
- EGLConfig egl_config;
-#endif
};
struct _GdkWin32GLContextClass
@@ -59,6 +49,33 @@ struct _GdkWin32GLContextClass
GdkGLContextClass parent_class;
};
+/* WGL */
+#define GDK_TYPE_WIN32_GL_CONTEXT_WGL (gdk_win32_gl_context_wgl_get_type())
+#define GDK_WIN32_GL_CONTEXT_WGL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_WIN32_GL_CONTEXT_WGL,
GdkWin32GLContextWGL))
+#define GDK_IS_WIN32_GL_CONTEXT_WGL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WIN32_GL_CONTEXT_WGL))
+
+typedef struct _GdkWin32GLContextWGL GdkWin32GLContextWGL;
+
+gboolean gdk_win32_display_init_wgl (GdkDisplay *display,
+ GError **error);
+void gdk_win32_gl_context_wgl_bind_surface (GdkWin32GLContextWGL *ctx,
+ GdkWin32Surface *win32_surface);
+
+GType gdk_win32_gl_context_wgl_get_type (void) G_GNUC_CONST;
+
+/* EGL */
+#define GDK_TYPE_WIN32_GL_CONTEXT_EGL (gdk_win32_gl_context_egl_get_type())
+#define GDK_WIN32_GL_CONTEXT_EGL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_WIN32_GL_CONTEXT_EGL,
GdkWin32GLContextEGL))
+#define GDK_IS_WIN32_GL_CONTEXT_EGL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WIN32_GL_CONTEXT_EGL))
+
+typedef struct _GdkWin32GLContextEGL GdkWin32GLContextEGL;
+
+gboolean gdk_win32_display_init_egl (GdkDisplay *display,
+ GError **error);
+void gdk_win32_surface_destroy_egl_surface (GdkWin32Surface *self);
+
+GType gdk_win32_gl_context_egl_get_type (void) G_GNUC_CONST;
+
void
_gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface);
diff --git a/gdk/win32/gdksurface-win32.c b/gdk/win32/gdksurface-win32.c
index 85c0053a14..49c96ab237 100644
--- a/gdk/win32/gdksurface-win32.c
+++ b/gdk/win32/gdksurface-win32.c
@@ -5044,9 +5044,9 @@ gdk_win32_drag_surface_iface_init (GdkDragSurfaceInterface *iface)
#ifdef GDK_WIN32_ENABLE_EGL
EGLSurface
-_gdk_win32_surface_get_egl_surface (GdkSurface *surface,
- EGLConfig config,
- gboolean is_dummy)
+gdk_win32_surface_get_egl_surface (GdkSurface *surface,
+ EGLConfig config,
+ gboolean is_dummy)
{
GdkWin32Display *display = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface));
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
diff --git a/gdk/win32/gdksurface-win32.h b/gdk/win32/gdksurface-win32.h
index 5f85c50373..6ac1d6a059 100644
--- a/gdk/win32/gdksurface-win32.h
+++ b/gdk/win32/gdksurface-win32.h
@@ -379,9 +379,9 @@ RECT
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context);
#ifdef GDK_WIN32_ENABLE_EGL
-EGLSurface _gdk_win32_surface_get_egl_surface (GdkSurface *surface,
- EGLConfig config,
- gboolean is_dummy);
+EGLSurface gdk_win32_surface_get_egl_surface (GdkSurface *surface,
+ EGLConfig config,
+ gboolean is_dummy);
#endif
G_END_DECLS
diff --git a/gdk/win32/meson.build b/gdk/win32/meson.build
index 6f57d5a4cd..1f4c9d6e9f 100644
--- a/gdk/win32/meson.build
+++ b/gdk/win32/meson.build
@@ -13,6 +13,7 @@ gdk_win32_sources = files([
'gdkdrop-win32.c',
'gdkevents-win32.c',
'gdkglcontext-win32.c',
+ 'gdkglcontext-win32-wgl.c',
'gdkglobals-win32.c',
'gdkhdataoutputstream-win32.c',
'gdkkeys-win32.c',
@@ -47,6 +48,7 @@ GDK_WIN32_EGL_CFLAGS = []
if win32_has_egl
GDK_WIN32_EGL_CFLAGS = ['-DGDK_WIN32_ENABLE_EGL']
+ gdk_win32_sources += ['gdkglcontext-win32-egl.c']
endif
gdk_win32_deps = [ # FIXME
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]