[gtk/win32-gl-reorg-3: 9/11] GDK-Win32: Reorganize gdkgdlcontext-win32.c
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/win32-gl-reorg-3: 9/11] GDK-Win32: Reorganize gdkgdlcontext-win32.c
- Date: Mon, 23 Aug 2021 09:33:39 +0000 (UTC)
commit 404ec81d67a7480c8721743e7a1a2df39df19c5b
Author: Chun-wei Fan <fanchunwei src gnome org>
Date: Wed Aug 18 18:47:15 2021 +0800
GDK-Win32: Reorganize gdkgdlcontext-win32.c
Group the WGL-specific code and GLES-specific code together, so that we
can reduce the number of #ifdef ... in the code, to make the code more
readable and easily maintained. This will pave the way to add a
fallback mode to use libANGLE (OpenGL/ES) in case the Desktop OpenGL
support is inadequte, if OpenGL/ES support is enabled in the build.
This is somewhat based on the updates that were done in GTK master, so
we are using one subclass for WGL-based GdkGLContexts, and another for
GLES-based GdkGLContexts.
Also remove the underscores in many of the functions in
gdkglcontext-win32.*.
Clean up the code a bit as a result.
gdk/win32/gdkdisplay-win32.c | 2 +-
gdk/win32/gdkdisplay-win32.h | 31 +-
gdk/win32/gdkevents-win32.c | 4 +-
gdk/win32/gdkglcontext-win32.c | 1494 ++++++++++++++++++++++------------------
gdk/win32/gdkglcontext-win32.h | 59 +-
gdk/win32/gdkwindow-win32.c | 12 +-
6 files changed, 853 insertions(+), 749 deletions(-)
---
diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c
index c2b572b402..2598c8ccd7 100644
--- a/gdk/win32/gdkdisplay-win32.c
+++ b/gdk/win32/gdkdisplay-win32.c
@@ -1299,7 +1299,7 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
display_class->convert_selection = _gdk_win32_display_convert_selection;
display_class->text_property_to_utf8_list = _gdk_win32_display_text_property_to_utf8_list;
display_class->utf8_to_string_target = _gdk_win32_display_utf8_to_string_target;
- display_class->make_gl_context_current = _gdk_win32_display_make_gl_context_current;
+ display_class->make_gl_context_current = gdk_win32_display_make_gl_context_current;
display_class->get_n_monitors = gdk_win32_display_get_n_monitors;
display_class->get_monitor = gdk_win32_display_get_monitor;
diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h
index 67201582ed..7a7e898ff8 100644
--- a/gdk/win32/gdkdisplay-win32.h
+++ b/gdk/win32/gdkdisplay-win32.h
@@ -33,6 +33,15 @@ typedef enum _GdkWin32ProcessDpiAwareness {
PROCESS_PER_MONITOR_DPI_AWARE = 2
} GdkWin32ProcessDpiAwareness;
+/* Define values for GL type used */
+typedef enum _GdkWin32GLContextType
+{
+ GDK_WIN32_GL_PENDING,
+ GDK_WIN32_GL_NONE,
+ GDK_WIN32_GL_WGL,
+ GDK_WIN32_GL_EGL
+} GdkWin32GLContextType;
+
/* APIs from shcore.dll */
typedef HRESULT (WINAPI *funcSetProcessDpiAwareness) (GdkWin32ProcessDpiAwareness value);
typedef HRESULT (WINAPI *funcGetProcessDpiAwareness) (HANDLE handle,
@@ -81,20 +90,11 @@ struct _GdkWin32Display
HWND hwnd;
HWND clipboard_hwnd;
- /* WGL/OpenGL Items */
- guint have_wgl : 1;
+ /* OpenGL Items */
+ GdkWin32GLContextType gl_type;
guint gl_version;
-#ifdef GDK_WIN32_ENABLE_EGL
- /* EGL (Angle) Items */
- guint have_egl : 1;
- guint egl_version;
- EGLDisplay egl_disp;
- HDC hdc_egl_temp;
-#endif
-
- GPtrArray *monitors;
-
+ /* WGL Items */
guint hasWglARBCreateContext : 1;
guint hasWglEXTSwapControl : 1;
guint hasWglOMLSyncControl : 1;
@@ -104,12 +104,19 @@ struct _GdkWin32Display
/* compensate around Intel OpenGL driver issues on blitting, see issue #3487 */
guint needIntelGLWorkaround : 1;
+ /* EGL (Angle) Items */
+ HDC hdc_egl_temp;
+
#ifdef GDK_WIN32_ENABLE_EGL
+ EGLDisplay egl_disp;
+ EGLConfig egl_config;
guint hasEglKHRCreateContext : 1;
guint hasEglSurfacelessContext : 1;
EGLint egl_min_swap_interval;
#endif
+ GPtrArray *monitors;
+
/* HiDPI Items */
guint have_at_least_win81 : 1;
GdkWin32ProcessDpiAwareness dpi_aware_type;
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index a7cc3e2394..84ea9792f3 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -3348,7 +3348,7 @@ gdk_event_translate (MSG *msg,
do_show_window (window, msg->wParam == SC_MINIMIZE ? TRUE : FALSE);
if (msg->wParam == SC_RESTORE)
- _gdk_win32_window_invalidate_egl_framebuffer (window);
+ gdk_win32_window_invalidate_egl_framebuffer (window);
break;
case SC_MAXIMIZE:
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
@@ -3436,7 +3436,7 @@ gdk_event_translate (MSG *msg,
{
MINMAXINFO our_mmi;
- _gdk_win32_window_invalidate_egl_framebuffer (window);
+ gdk_win32_window_invalidate_egl_framebuffer (window);
if (_gdk_win32_window_fill_min_max_info (window, &our_mmi))
{
diff --git a/gdk/win32/gdkglcontext-win32.c b/gdk/win32/gdkglcontext-win32.c
index 24d2b6facd..86ce9ad75b 100644
--- a/gdk/win32/gdkglcontext-win32.c
+++ b/gdk/win32/gdkglcontext-win32.c
@@ -45,51 +45,34 @@
# 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)
+struct _GdkWin32GLContext
{
- 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));
- GdkWindow *window = gdk_gl_context_get_window (context);
- GdkWindowImplWin32 *impl = NULL;
+ GdkGLContext parent_instance;
- if (context_win32->hglrc != NULL)
- {
- if (wglGetCurrentContext () == context_win32->hglrc)
- wglMakeCurrent (NULL, NULL);
+ HDC gl_hdc;
+ guint need_alpha_bits : 1;
+ guint is_attached : 1;
+ guint do_frame_sync : 1;
+ guint do_blit_swap : 1;
+};
- GDK_NOTE (OPENGL, g_print ("Destroying WGL context\n"));
+struct _GdkWin32GLContextClass
+{
+ GdkGLContextClass parent_class;
+};
- wglDeleteContext (context_win32->hglrc);
- context_win32->hglrc = NULL;
+G_DEFINE_TYPE (GdkWin32GLContext, gdk_win32_gl_context, GDK_TYPE_GL_CONTEXT)
- ReleaseDC (GDK_WINDOW_HWND (window), context_win32->gl_hdc);
- }
+static void
+gdk_win32_gl_context_cleanup (GdkGLContext *context)
+{
+ GdkWindow *window = gdk_gl_context_get_window (context);
-#ifdef GDK_WIN32_ENABLE_EGL
- if (context_win32->egl_context != EGL_NO_CONTEXT)
+ if (window != NULL)
{
- 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;
-
- impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+ GdkWindowImplWin32 *impl = NULL;
- ReleaseDC (GDK_WINDOW_HWND (window), context_win32->gl_hdc);
- }
-#endif
-
- if (window != NULL && window->impl != NULL)
- {
+ ReleaseDC (GDK_WINDOW_HWND (window), GDK_WIN32_GL_CONTEXT(context)->gl_hdc);
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
if (impl->suppress_layered > 0)
@@ -101,25 +84,6 @@ _gdk_win32_gl_context_dispose (GObject *gobject)
if (impl->suppress_layered == 0)
_gdk_win32_window_update_style_bits (window);
}
-
- G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
-}
-
-static void
-gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass)
-{
- GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- context_class->end_frame = _gdk_win32_gl_context_end_frame;
- context_class->realize = _gdk_win32_gl_context_realize;
-
- gobject_class->dispose = _gdk_win32_gl_context_dispose;
-}
-
-static void
-gdk_win32_gl_context_init (GdkWin32GLContext *self)
-{
}
static void
@@ -154,142 +118,22 @@ gdk_gl_blit_region (GdkWindow *window,
}
}
-static gboolean
-_get_is_egl_force_redraw (GdkWindow *window)
-{
- /* We only need to call gdk_window_invalidate_rect () if necessary */
-#ifdef GDK_WIN32_ENABLE_EGL
- if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
- {
- GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
-
- return impl->egl_force_redraw_all;
- }
-#endif
- return FALSE;
-}
-
-static void
-_reset_egl_force_redraw (GdkWindow *window)
-{
-#ifdef GDK_WIN32_ENABLE_EGL
- if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
- {
- GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
-
- if (impl->egl_force_redraw_all)
- impl->egl_force_redraw_all = FALSE;
- }
-#endif
-}
-
-void
-_gdk_win32_gl_context_end_frame (GdkGLContext *context,
- cairo_region_t *painted,
- cairo_region_t *damage)
-{
- GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
- GdkWindow *window = gdk_gl_context_get_window (context);
- GdkWin32Display *display = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
-
- gdk_gl_context_make_current (context);
-
- 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);
- }
- }
-
- if (context_win32->do_blit_swap)
- {
- glDrawBuffer(GL_FRONT);
- glReadBuffer(GL_BACK);
- gdk_gl_blit_region (window, painted, display->needIntelGLWorkaround);
- glDrawBuffer(GL_BACK);
- glFlush();
-
- if (gdk_gl_context_has_frame_terminator (context))
- glFrameTerminatorGREMEDY ();
- }
- else
- SwapBuffers (context_win32->gl_hdc);
- }
-
-#ifdef GDK_WIN32_ENABLE_EGL
- else
- {
- EGLSurface egl_surface = _gdk_win32_window_get_egl_surface (window, context_win32->egl_config, FALSE);
- gboolean force_egl_redraw_all = _get_is_egl_force_redraw (window);
-
- if (context_win32->do_blit_swap && !force_egl_redraw_all)
- gdk_gl_blit_region (window, painted, FALSE);
- else if (force_egl_redraw_all)
- {
- GdkRectangle rect = {0, 0, gdk_window_get_width (window), gdk_window_get_height (window)};
-
- /* We need to do gdk_window_invalidate_rect() so that we don't get glitches after maximizing or
- * restoring or using aerosnap
- */
- gdk_window_invalidate_rect (window, &rect, TRUE);
- _reset_egl_force_redraw (window);
- }
-
- eglSwapBuffers (display->egl_disp, egl_surface);
- }
-#endif
-}
-
-void
-_gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
- cairo_region_t *update_area)
+/* Section on WGL usage */
+struct _GdkWin32GLContextWGL
{
- cairo_rectangle_int_t window_rect;
- gboolean invalidate_all = FALSE;
- GdkWin32GLContext *context_win32;
- cairo_rectangle_int_t whole_window = { 0, 0, gdk_window_get_width (window), gdk_window_get_height (window)
};
-
- /* Minimal update is ok if we're not drawing with gl */
- if (window->gl_paint_context == NULL)
- return;
+ GdkWin32GLContext parent_instance;
- context_win32 = GDK_WIN32_GL_CONTEXT (window->gl_paint_context);
- context_win32->do_blit_swap = FALSE;
+ HGLRC wgl_context;
+};
- if (gdk_gl_context_has_framebuffer_blit (window->gl_paint_context) &&
- cairo_region_contains_rectangle (update_area, &whole_window) != CAIRO_REGION_OVERLAP_IN)
- {
- context_win32->do_blit_swap = TRUE;
- }
- else
- invalidate_all = TRUE;
+typedef struct _GdkWin32GLContextClass GdkWin32GLContextWGLClass;
+typedef struct _GdkWin32GLContextWGL GdkWin32GLContextWGL;
- if (invalidate_all)
- {
- window_rect.x = 0;
- window_rect.y = 0;
- window_rect.width = gdk_window_get_width (window);
- window_rect.height = gdk_window_get_height (window);
+G_DEFINE_TYPE (GdkWin32GLContextWGL, gdk_win32_gl_context_wgl, GDK_TYPE_WIN32_GL_CONTEXT)
- /* If nothing else is known, repaint everything so that the back
- buffer is fully up-to-date for the swapbuffer */
- cairo_region_union_rectangle (update_area, &window_rect);
- }
-}
+#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
{
@@ -301,7 +145,7 @@ typedef struct
} GdkWGLDummy;
static void
-_destroy_dummy_gl_context (GdkWGLDummy dummy)
+destroy_dummy_gl_context (GdkWGLDummy dummy)
{
if (dummy.hglrc != NULL)
{
@@ -328,7 +172,7 @@ _destroy_dummy_gl_context (GdkWGLDummy dummy)
/* Yup, we need to create a dummy window for the dummy WGL context */
static void
-_get_dummy_window_hwnd (GdkWGLDummy *dummy)
+get_dummy_window_hwnd (GdkWGLDummy *dummy)
{
WNDCLASSEX dummy_wc;
@@ -365,16 +209,16 @@ _get_dummy_window_hwnd (GdkWGLDummy *dummy)
}
static gint
-_gdk_init_dummy_context (GdkWGLDummy *dummy,
+gdk_init_dummy_context (GdkWGLDummy *dummy,
const gboolean need_alpha_bits);
#define PIXEL_ATTRIBUTES 19
static gint
-_get_wgl_pfd (HDC hdc,
- const gboolean need_alpha_bits,
- PIXELFORMATDESCRIPTOR *pfd,
- GdkWin32Display *display)
+get_wgl_pfd (HDC hdc,
+ const gboolean need_alpha_bits,
+ PIXELFORMATDESCRIPTOR *pfd,
+ GdkWin32Display *display)
{
gint best_pf = 0;
@@ -444,7 +288,7 @@ _get_wgl_pfd (HDC hdc,
/* acquire and cache dummy Window (HWND & HDC) and
* dummy GL Context, we need it for wglChoosePixelFormatARB()
*/
- best_pf = _gdk_init_dummy_context (&dummy, need_alpha_bits);
+ best_pf = gdk_init_dummy_context (&dummy, need_alpha_bits);
if (best_pf == 0 || !wglMakeCurrent (dummy.hdc, dummy.hglrc))
{
@@ -481,7 +325,7 @@ _get_wgl_pfd (HDC hdc,
/* 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);
+ destroy_dummy_gl_context (dummy);
}
else
{
@@ -512,19 +356,19 @@ _get_wgl_pfd (HDC hdc,
* one and cache it for later use
*/
static gint
-_gdk_init_dummy_context (GdkWGLDummy *dummy,
+gdk_init_dummy_context (GdkWGLDummy *dummy,
const gboolean need_alpha_bits)
{
PIXELFORMATDESCRIPTOR pfd;
gboolean set_pixel_format_result = FALSE;
gint best_idx = 0;
- _get_dummy_window_hwnd (dummy);
+ get_dummy_window_hwnd (dummy);
dummy->hdc = GetDC (dummy->hwnd);
memset (&pfd, 0, sizeof (PIXELFORMATDESCRIPTOR));
- best_idx = _get_wgl_pfd (dummy->hdc, need_alpha_bits, &pfd, NULL);
+ best_idx = get_wgl_pfd (dummy->hdc, need_alpha_bits, &pfd, NULL);
if (best_idx != 0)
set_pixel_format_result = SetPixelFormat (dummy->hdc,
@@ -543,183 +387,157 @@ _gdk_init_dummy_context (GdkWGLDummy *dummy,
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)
+static void
+gdk_win32_gl_context_dispose_wgl (GObject *gobject)
{
- EGLDisplay disp;
- gboolean success = FALSE;
+ GdkGLContext *context = GDK_GL_CONTEXT (gobject);
+ GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (context);
- if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
+ if (context_wgl->wgl_context != NULL)
{
- PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = (void *) eglGetProcAddress
("eglGetPlatformDisplayEXT");
- if (getPlatformDisplay)
- {
- EGLint disp_attr[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_NONE};
+ GdkWindow *window = gdk_gl_context_get_window (context);
- disp = getPlatformDisplay (EGL_PLATFORM_ANGLE_ANGLE, display->hdc_egl_temp, disp_attr);
+ if (wglGetCurrentContext () == context_wgl->wgl_context)
+ wglMakeCurrent (NULL, NULL);
- if (disp != EGL_NO_DISPLAY)
- return disp;
- }
+ GDK_NOTE (OPENGL, g_print ("Destroying WGL context\n"));
+
+ wglDeleteContext (context_wgl->wgl_context);
+ context_wgl->wgl_context = NULL;
+
+ gdk_win32_gl_context_cleanup (context);
}
- return eglGetDisplay (display->hdc_egl_temp);
+
+ G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
}
-#endif
-static gboolean
-_gdk_win32_display_init_gl (GdkDisplay *display,
- const gboolean need_alpha_bits)
+static void
+gdk_win32_gl_context_end_frame_wgl (GdkGLContext *context,
+ cairo_region_t *painted,
+ cairo_region_t *damage)
{
- GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
- gint best_idx = 0;
- gboolean disable_wgl = FALSE;
-
-#ifdef GDK_WIN32_ENABLE_EGL
- disable_wgl = ((_gdk_gl_flags & GDK_GL_GLES) != 0) ||
- display_win32->running_on_arm64;
-#endif
+ GdkWin32Display *display_win32 = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
+ GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
- if (display_win32->have_wgl
-#ifdef GDK_WIN32_ENABLE_EGL
- || display_win32->have_egl
-#endif
- )
- return TRUE;
+ gdk_gl_context_make_current (context);
- if (!disable_wgl)
+ if (context_win32->do_frame_sync)
{
- /* acquire and cache dummy Window (HWND & HDC) and
- * dummy GL Context, it is used to query functions
- * and used for other stuff as well
- */
- GdkWGLDummy dummy;
- memset (&dummy, 0, sizeof (GdkWGLDummy));
-
- best_idx = _gdk_init_dummy_context (&dummy, need_alpha_bits);
-
- 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");
- display_win32->needIntelGLWorkaround =
- (g_ascii_strcasecmp (glGetString (GL_VENDOR), "intel") == 0);
+ glFinish ();
- GDK_NOTE (OPENGL,
- g_print ("WGL API version %d.%d found\n"
- " - Vendor: %s\n"
- " - Intel OpenGL workaround: %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->needIntelGLWorkaround ? "yes" : "no",
- 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);
+ if (display_win32->hasWglOMLSyncControl)
+ {
+ 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);
+ }
}
-#ifdef GDK_WIN32_ENABLE_EGL
- else
+ if (context_win32->do_blit_swap)
{
- EGLDisplay 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;
- }
+ GdkWindow *window = gdk_gl_context_get_window (context);
- return FALSE;
- }
+ glDrawBuffer(GL_FRONT);
+ glReadBuffer(GL_BACK);
+ gdk_gl_blit_region (window, painted, display_win32->needIntelGLWorkaround);
+ glDrawBuffer(GL_BACK);
+ glFlush();
- display_win32->egl_disp = egl_disp;
- display_win32->have_egl = TRUE;
- display_win32->egl_version = epoxy_egl_version (egl_disp);
+ if (gdk_gl_context_has_frame_terminator (context))
+ glFrameTerminatorGREMEDY ();
+ }
+ else
+ SwapBuffers (context_win32->gl_hdc);
+}
- eglBindAPI(EGL_OPENGL_ES_API);
+static void
+gdk_win32_display_init_wgl (GdkWin32Display *display_win32,
+ const gboolean need_alpha_bits)
+{
+ /* acquire and cache dummy Window (HWND & HDC) and
+ * dummy GL Context, it is used to query functions
+ * and used for other stuff as well
+ */
+ GdkWGLDummy dummy;
+ gint best_idx = 0;
- display_win32->hasEglSurfacelessContext =
- epoxy_has_egl_extension (egl_disp, "EGL_KHR_surfaceless_context");
+ memset (&dummy, 0, sizeof (GdkWGLDummy));
+ best_idx = gdk_init_dummy_context (&dummy, need_alpha_bits);
- 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"));
+ if (best_idx == 0 || !wglMakeCurrent (dummy.hdc, dummy.hglrc))
+ {
+ display_win32->gl_type = GDK_WIN32_GL_NONE;
+ return;
}
-#endif
- return 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");
+ display_win32->needIntelGLWorkaround =
+ (g_ascii_strcasecmp (glGetString (GL_VENDOR), "intel") == 0);
+
+ GDK_NOTE (OPENGL,
+ g_print ("WGL API version %d.%d found\n"
+ " - Vendor: %s\n"
+ " - Intel OpenGL workaround: %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->needIntelGLWorkaround ? "yes" : "no",
+ 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);
+
+ display_win32->gl_type = GDK_WIN32_GL_WGL;
}
-/* Setup the legacy context after creating it */
+/* Setup the legacy WGL context after creating it */
static gboolean
-_ensure_legacy_gl_context (HDC hdc,
+ensure_legacy_wgl_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);
+ GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
- return wglShareLists (hglrc_legacy, context_win32->hglrc);
+ return wglShareLists (hglrc_legacy, context_wgl->wgl_context);
}
return TRUE;
}
static HGLRC
-_create_gl_context_with_attribs (HDC hdc,
+create_wgl_context_with_attribs (HDC hdc,
HGLRC hglrc_base,
GdkGLContext *share,
int flags,
@@ -728,7 +546,7 @@ _create_gl_context_with_attribs (HDC hdc,
gboolean *is_legacy)
{
HGLRC hglrc;
- GdkWin32GLContext *context_win32;
+ GdkWin32GLContextWGL *context_wgl;
/* if we have wglCreateContextAttribsARB(), create a
* context with the compatibility profile if a legacy
@@ -746,17 +564,17 @@ _create_gl_context_with_attribs (HDC hdc,
};
if (share != NULL)
- context_win32 = GDK_WIN32_GL_CONTEXT (share);
+ context_wgl= GDK_WIN32_GL_CONTEXT_WGL (share);
hglrc = wglCreateContextAttribsARB (hdc,
- share != NULL ? context_win32->hglrc : NULL,
+ share != NULL ? context_wgl->wgl_context : NULL,
attribs);
return hglrc;
}
static HGLRC
-_create_gl_context (HDC hdc,
+create_wgl_context (HDC hdc,
GdkGLContext *share,
int flags,
int major,
@@ -764,7 +582,7 @@ _create_gl_context (HDC hdc,
gboolean *is_legacy,
gboolean hasWglARBCreateContext)
{
- /* We need a legacy context for *all* cases */
+ /* We need a legacy WGL context for *all* cases */
HGLRC hglrc_base = wglCreateContext (hdc);
gboolean success = TRUE;
@@ -775,7 +593,7 @@ _create_gl_context (HDC hdc,
/* 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))
+ if (ensure_legacy_wgl_context (hdc, hglrc_base, share))
{
wglMakeCurrent (hdc_current, hglrc_current);
return hglrc_base;
@@ -794,7 +612,7 @@ _create_gl_context (HDC hdc,
goto gl_fail;
}
- hglrc = _create_gl_context_with_attribs (hdc,
+ hglrc = create_wgl_context_with_attribs (hdc,
hglrc_base,
share,
flags,
@@ -808,7 +626,7 @@ _create_gl_context (HDC hdc,
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 = create_wgl_context_with_attribs (hdc,
hglrc_base,
share,
flags,
@@ -820,7 +638,7 @@ _create_gl_context (HDC hdc,
if (hglrc == NULL)
{
- if (!_ensure_legacy_gl_context (hdc, hglrc_base, share))
+ if (!ensure_legacy_wgl_context (hdc, hglrc_base, share))
success = FALSE;
}
@@ -850,10 +668,10 @@ gl_fail:
}
static gboolean
-_set_pixformat_for_hdc (HDC hdc,
- gint *best_idx,
- const gboolean need_alpha_bits,
- GdkWin32Display *display)
+set_pixformat_for_hdc (HDC hdc,
+ gint *best_idx,
+ const gboolean need_alpha_bits,
+ GdkWin32Display *display)
{
gboolean already_checked = TRUE;
*best_idx = GetPixelFormat (hdc);
@@ -868,7 +686,7 @@ _set_pixformat_for_hdc (HDC hdc,
GDK_NOTE (OPENGL, g_print ("requesting pixel format...\n"));
already_checked = FALSE;
- *best_idx = _get_wgl_pfd (hdc, need_alpha_bits, &pfd, display);
+ *best_idx = get_wgl_pfd (hdc, need_alpha_bits, &pfd, display);
if (*best_idx != 0)
set_pixel_format_result = SetPixelFormat (hdc, *best_idx, &pfd);
@@ -883,44 +701,392 @@ _set_pixformat_for_hdc (HDC hdc,
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,
- gboolean need_alpha_bits,
- GError **error)
+gdk_win32_gl_context_realize_wgl (GdkGLContext *context,
+ GError **error)
{
- EGLint attrs[MAX_EGL_ATTRS];
- EGLint count;
- EGLConfig *configs, chosen_config;
-
- int i = 0;
-
- EGLDisplay egl_disp = display->egl_disp;
+ GdkGLContext *share = gdk_gl_context_get_shared_context (context);
+ GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
+ GdkWindow *window = gdk_gl_context_get_window (context);
+ GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_window_get_display (window));
- attrs[i++] = EGL_CONFORMANT;
- attrs[i++] = EGL_OPENGL_ES2_BIT;
- attrs[i++] = EGL_SURFACE_TYPE;
- attrs[i++] = EGL_WINDOW_BIT;
+ /* These are the real WGL context items that we will want to use later */
+ gboolean debug_bit, compat_bit;
+ gboolean legacy_bit = FALSE;
+ HGLRC hglrc;
+ gint pixel_format;
- attrs[i++] = EGL_COLOR_BUFFER_TYPE;
- attrs[i++] = EGL_RGB_BUFFER;
+ /* request flags and specific versions for core (3.2+) WGL context */
+ gint flags = 0;
+ gint major = 0;
+ gint minor = 0;
- attrs[i++] = EGL_RED_SIZE;
- attrs[i++] = 1;
- attrs[i++] = EGL_GREEN_SIZE;
- attrs[i++] = 1;
- attrs[i++] = EGL_BLUE_SIZE;
- attrs[i++] = 1;
+ /*
+ * A legacy context cannot be shared with core profile ones, this means we
+ * must stick to a legacy context if the shared context is a legacy context. We
+ * also use a legacy context if we use GDK_GL=legacy or if we do not have
+ * the WGL_ARB_create_context extension
+ */
+ if ((_gdk_gl_flags & GDK_GL_LEGACY) != 0 ||
+ !display_win32->hasWglARBCreateContext ||
+ share != NULL && gdk_gl_context_is_legacy (share))
+ legacy_bit = TRUE;
- if (need_alpha_bits)
+ 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 (!set_pixformat_for_hdc (context_win32->gl_hdc,
+ &pixel_format,
+ context_win32->need_alpha_bits,
+ display_win32))
{
- attrs[i++] = EGL_ALPHA_SIZE;
- attrs[i++] = 1;
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_UNSUPPORTED_FORMAT,
+ _("No available configurations for the given pixel format"));
+
+ return FALSE;
+ }
+
+ 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 (context_win32->gl_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));
+
+ GDK_WIN32_GL_CONTEXT_WGL (context)->wgl_context = hglrc;
+
+ /* set whether we are using GLES */
+ gdk_gl_context_set_use_es (context, FALSE);
+
+ /* OpenGL does not work with WS_EX_LAYERED enabled, so we need to
+ * disable WS_EX_LAYERED when we acquire a valid HGLRC
+ */
+ impl->suppress_layered++;
+
+ /* if this is the first time a GL context is acquired for the window,
+ * disable layered windows by triggering update_style_bits()
+ */
+ if (impl->suppress_layered == 1)
+ _gdk_win32_window_update_style_bits (window);
+
+ /* 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_display_make_wgl_context_current (GdkDisplay *display,
+ GdkGLContext *context)
+{
+ GdkWin32GLContext *context_win32;
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+ GdkWindow *window;
+
+ if (context == NULL)
+ {
+ wglMakeCurrent(NULL, NULL);
+
+ return TRUE;
+ }
+
+ context_win32 = GDK_WIN32_GL_CONTEXT (context);
+ window = gdk_gl_context_get_window (context);
+
+ if (!wglMakeCurrent (context_win32->gl_hdc, GDK_WIN32_GL_CONTEXT_WGL (context)->wgl_context))
+ {
+ GDK_NOTE (OPENGL,
+ g_print ("Making WGL context current failed\n"));
+ return FALSE;
+ }
+
+ if (context_win32->is_attached)
+ {
+ if (display_win32->hasWglEXTSwapControl)
+ {
+ /* 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. */
+ gboolean do_frame_sync = !gdk_screen_is_composited (gdk_window_get_screen (window));
+
+ 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);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+gdk_win32_gl_context_wgl_class_init (GdkWin32GLContextWGLClass *klass)
+{
+ GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ context_class->end_frame = gdk_win32_gl_context_end_frame_wgl;
+ context_class->realize = gdk_win32_gl_context_realize_wgl;
+
+ gobject_class->dispose = gdk_win32_gl_context_dispose_wgl;
+}
+
+static void
+gdk_win32_gl_context_wgl_init (GdkWin32GLContextWGL *wgl_context)
+{
+}
+
+/* End section on WGL support */
+/* Section on EGL/libANGLE support */
+#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
+
+struct _GdkWin32GLContextEGL
+{
+ GdkWin32GLContext parent_instance;
+
+ EGLContext egl_context;
+};
+
+#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 _GdkWin32GLContextClass GdkWin32GLContextEGLClass;
+typedef struct _GdkWin32GLContextEGL GdkWin32GLContextEGL;
+
+G_DEFINE_TYPE (GdkWin32GLContextEGL, gdk_win32_gl_context_egl, GDK_TYPE_WIN32_GL_CONTEXT)
+
+static EGLDisplay
+gdk_win32_get_egl_display (GdkWin32Display *display)
+{
+ EGLDisplay disp;
+ gboolean success = FALSE;
+
+ 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);
+}
+
+static void
+gdk_win32_gl_context_dispose_egl (GObject *gobject)
+{
+ GdkGLContext *context = GDK_GL_CONTEXT (gobject);
+ GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
+
+ if (context_egl->egl_context != EGL_NO_CONTEXT)
+ {
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context));
+
+ 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;
+
+ gdk_win32_gl_context_cleanup (context);
+ }
+
+ G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
+}
+
+static gboolean
+get_is_egl_force_redraw (GdkWindow *window)
+{
+ /* We only need to call gdk_window_invalidate_rect () if necessary */
+ if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
+ {
+ GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+ return impl->egl_force_redraw_all;
+ }
+
+ return FALSE;
+}
+
+static void
+reset_egl_force_redraw (GdkWindow *window)
+{
+ if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
+ {
+ GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+ if (impl->egl_force_redraw_all)
+ impl->egl_force_redraw_all = FALSE;
+ }
+}
+
+static void
+gdk_win32_gl_context_end_frame_egl (GdkGLContext *context,
+ cairo_region_t *painted,
+ cairo_region_t *damage)
+{
+ GdkWindow *window = gdk_gl_context_get_window (context);
+ GdkWin32Display *display_win32 = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
+ GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
+
+ EGLSurface egl_surface = _gdk_win32_window_get_egl_surface (window, display_win32->egl_config, FALSE);
+ gboolean force_egl_redraw_all = get_is_egl_force_redraw (window);
+
+ gdk_gl_context_make_current (context);
+
+ if (context_win32->do_blit_swap && !force_egl_redraw_all)
+ gdk_gl_blit_region (window, painted, FALSE);
+ else if (force_egl_redraw_all)
+ {
+ GdkRectangle rect = {0, 0, gdk_window_get_width (window), gdk_window_get_height (window)};
+
+ /* We need to do gdk_window_invalidate_rect() so that we don't get glitches after maximizing or
+ * restoring or using aerosnap
+ */
+ gdk_window_invalidate_rect (window, &rect, TRUE);
+ reset_egl_force_redraw (window);
+ }
+
+ eglSwapBuffers (display_win32->egl_disp, egl_surface);
+}
+
+static void
+gdk_win32_display_init_egl (GdkWin32Display *display_win32)
+{
+ EGLDisplay 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;
+ }
+
+ display_win32->gl_type = GDK_WIN32_GL_NONE;
+ return;
+ }
+
+ display_win32->egl_disp = egl_disp;
+ display_win32->gl_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->gl_version / 10,
+ display_win32->gl_version % 10,
+ eglQueryString (display_win32->egl_disp, EGL_VENDOR),
+ display_win32->hasEglSurfacelessContext ? "yes" : "no"));
+
+ display_win32->gl_type = GDK_WIN32_GL_EGL;
+}
+
+#define MAX_EGL_ATTRS 30
+
+static gboolean
+find_eglconfig_for_window (GdkWin32Display *display_win32,
+ gboolean need_alpha_bits,
+ GError **error)
+{
+ EGLint attrs[MAX_EGL_ATTRS];
+ EGLint count;
+ EGLConfig *configs, chosen_config;
+
+ int i = 0;
+
+ EGLDisplay egl_disp;
+
+ if (display_win32->egl_min_swap_interval != 0 &&
+ display_win32->egl_config != NULL)
+ return TRUE;
+
+ egl_disp = display_win32->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;
+
+ if (need_alpha_bits)
+ {
+ attrs[i++] = EGL_ALPHA_SIZE;
+ attrs[i++] = 1;
}
else
{
@@ -931,7 +1097,7 @@ find_eglconfig_for_window (GdkWin32Display *display,
attrs[i++] = EGL_NONE;
g_assert (i < MAX_EGL_ATTRS);
- if (!eglChooseConfig (display->egl_disp, attrs, NULL, 0, &count) || count < 1)
+ if (!eglChooseConfig (display_win32->egl_disp, attrs, NULL, 0, &count) || count < 1)
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
@@ -941,7 +1107,7 @@ find_eglconfig_for_window (GdkWin32Display *display,
configs = g_new (EGLConfig, count);
- if (!eglChooseConfig (display->egl_disp, attrs, configs, count, &count) || count < 1)
+ if (!eglChooseConfig (display_win32->egl_disp, attrs, configs, count, &count) || count < 1)
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
@@ -952,8 +1118,8 @@ find_eglconfig_for_window (GdkWin32Display *display,
/* 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))
+ if (!eglGetConfigAttrib (display_win32->egl_disp, chosen_config,
+ EGL_MIN_SWAP_INTERVAL, &display_win32->egl_min_swap_interval))
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
@@ -962,8 +1128,7 @@ find_eglconfig_for_window (GdkWin32Display *display,
return FALSE;
}
- if (egl_config_out != NULL)
- *egl_config_out = chosen_config;
+ display_win32->egl_config = chosen_config;
g_free (configs);
@@ -973,21 +1138,26 @@ find_eglconfig_for_window (GdkWin32Display *display,
#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)
+create_egl_context (EGLDisplay display,
+ EGLConfig config,
+ GdkGLContext *share,
+ int flags,
+ int major,
+ int minor)
{
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;
+ /*
+ * ANGLE does not support the GL_OES_vertex_array_object extension, so we need to use ES3 directly
+ * if we do not request for ES3 or later
+ */
+ if (major < 3)
+ {
+ context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
+ context_attribs[i++] = 3;
+ }
/* Specify the flags */
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
@@ -998,161 +1168,71 @@ _create_egl_context (EGLDisplay display,
ctx = eglCreateContext (display,
config,
- share != NULL ? GDK_WIN32_GL_CONTEXT (share)->egl_context
+ 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;
}
-#endif /* GDK_WIN32_ENABLE_EGL */
-gboolean
-_gdk_win32_gl_context_realize (GdkGLContext *context,
- GError **error)
+static gboolean
+gdk_win32_gl_context_realize_egl (GdkGLContext *context,
+ GError **error)
{
GdkGLContext *share = gdk_gl_context_get_shared_context (context);
GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
+ GdkWindow *window = gdk_gl_context_get_window (context);
+ GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_window_get_display (window));
- /* These are the real WGL/EGL context items that we will want to use later */
- gboolean debug_bit, compat_bit, legacy_bit;
-
- /* These are the real WGL context items that we will want to use later */
- HGLRC hglrc;
- gint pixel_format;
- gboolean use_es = FALSE;
+ /* These are the real EGL context items that we will want to use later */
+ EGLContext ctx;
+ gboolean debug_bit, compat_bit;
+ gboolean legacy_bit = FALSE;
- /* request flags and specific versions for core (3.2+) WGL context */
+ /* request flags and specific versions for EGL context */
gint flags = 0;
gint major = 0;
gint minor = 0;
-#ifdef GDK_WIN32_ENABLE_EGL
- EGLContext egl_context;
-#endif
-
- GdkWindow *window = gdk_gl_context_get_window (context);
- GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
- GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (gdk_window_get_display (window));
-
- /*
- * 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_flags & GDK_GL_LEGACY) != 0 ||
- share != NULL && gdk_gl_context_is_legacy (share))
- legacy_bit = TRUE;
-
- if ((_gdk_gl_flags & GDK_GL_GLES) != 0 ||
- (share != NULL && gdk_gl_context_get_use_es (share)))
- use_es = TRUE;
-
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 (win32_display->have_wgl)
- {
- if (!_set_pixformat_for_hdc (context_win32->gl_hdc,
- &pixel_format,
- context_win32->need_alpha_bits,
- win32_display))
- {
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_UNSUPPORTED_FORMAT,
- _("No available configurations for the given pixel format"));
+ if (debug_bit)
+ flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
+ if (compat_bit)
+ flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
- return FALSE;
- }
+ 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"));
- /* if there isn't wglCreateContextAttribsARB(), or if GDK_GL_LEGACY is set, we default to a legacy
context */
- legacy_bit = !win32_display->hasWglARBCreateContext ||
- g_getenv ("GDK_GL_LEGACY") != NULL;
+ ctx = create_egl_context (display_win32->egl_disp,
+ display_win32->egl_config,
+ share,
+ flags,
+ major,
+ minor);
- 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
- if (win32_display->have_egl)
+ if (ctx == EGL_NO_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));
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ _("Unable to create a GL context"));
- context_win32->egl_context = ctx;
- use_es = TRUE;
+ return FALSE;
}
-#endif
+ GDK_NOTE (OPENGL,
+ g_print ("Created EGL context[%p]\n",
+ ctx));
+
+ GDK_WIN32_GL_CONTEXT_EGL (context)->egl_context = ctx;
+
/* set whether we are using GLES */
- gdk_gl_context_set_use_es(context, use_es);
+ gdk_gl_context_set_use_es (context, TRUE);
/* OpenGL does not work with WS_EX_LAYERED enabled, so we need to
* disable WS_EX_LAYERED when we acquire a valid HGLRC
@@ -1171,161 +1251,242 @@ _gdk_win32_gl_context_realize (GdkGLContext *context,
return TRUE;
}
-GdkGLContext *
-_gdk_win32_window_create_gl_context (GdkWindow *window,
- gboolean attached,
- GdkGLContext *share,
- GError **error)
+void
+gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window)
{
- GdkDisplay *display = gdk_window_get_display (window);
- GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_window_get_display (window));
- GdkWin32GLContext *context = NULL;
- GdkVisual *visual = gdk_window_get_visual (window);
+/* If we are using ANGLE, we need to force redraw of the whole Window and its child windows
+ * as we need to re-acquire the EGL surfaces that we rendered to upload to Cairo explicitly,
+ * using gdk_window_invalidate_rect (), when we maximize or restore or use aerosnap
+ */
+ if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
+ {
+ GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
- gboolean need_alpha_bits = (visual == gdk_screen_get_rgba_visual (gdk_display_get_default_screen
(display)));
+ impl->egl_force_redraw_all = TRUE;
+ }
+}
- /* Acquire and store up the Windows-specific HWND and HDC */
- HDC hdc;
+static gboolean
+gdk_win32_display_make_egl_context_current (GdkDisplay *display,
+ GdkGLContext *context)
+{
+ GdkWin32GLContext *context_win32;
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+ GdkWindow *window;
+ EGLSurface egl_surface;
-#ifdef GDK_WIN32_ENABLE_EGL
- EGLContext egl_context;
- EGLConfig config;
-#endif
+ if (context == NULL)
+ {
+ eglMakeCurrent (display_win32->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- hdc = GetDC (GDK_WINDOW_HWND (window));
+ return TRUE;
+ }
-#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
+ context_win32 = GDK_WIN32_GL_CONTEXT (context);
+ window = gdk_gl_context_get_window (context);
- if (!_gdk_win32_display_init_gl (display, need_alpha_bits))
+ if (context_win32->is_attached || !display_win32->hasEglSurfacelessContext)
+ egl_surface = _gdk_win32_window_get_egl_surface (window,
+ display_win32->egl_config,
+ !context_win32->is_attached);
+ else
+ egl_surface = EGL_NO_SURFACE;
+
+ if (!eglMakeCurrent (display_win32->egl_disp,
+ egl_surface,
+ egl_surface,
+ GDK_WIN32_GL_CONTEXT_EGL (context)->egl_context))
{
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_NOT_AVAILABLE,
- _("No GL implementation is available"));
- return NULL;
+ g_warning ("eglMakeCurrent failed");
+ return FALSE;
}
-#ifdef GDK_WIN32_ENABLE_EGL
- if (display_win32->have_egl && !find_eglconfig_for_window (display_win32, &config,
- &display_win32->egl_min_swap_interval, need_alpha_bits,
- error))
- return NULL;
-#endif
+ if (display_win32->egl_min_swap_interval == 0)
+ eglSwapInterval (display_win32->egl_disp, 0);
+ else
+ g_debug ("Can't disable GL swap interval");
- context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT,
- "display", display,
- "window", window,
- "shared-context", share,
- NULL);
+ return TRUE;
+}
- context->need_alpha_bits = need_alpha_bits;
- context->gl_hdc = hdc;
+static void
+gdk_win32_gl_context_egl_class_init (GdkWin32GLContextEGLClass *klass)
+{
+ GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-#ifdef GDK_WIN32_ENABLE_EGL
- if (display_win32->have_egl)
- context->egl_config = config;
-#endif
+ context_class->end_frame = gdk_win32_gl_context_end_frame_egl;
+ context_class->realize = gdk_win32_gl_context_realize_egl;
- context->is_attached = attached;
+ gobject_class->dispose = gdk_win32_gl_context_dispose_egl;
+}
- return GDK_GL_CONTEXT (context);
+static void
+gdk_win32_gl_context_egl_init (GdkWin32GLContextEGL *egl_context)
+{
}
+#else /* GDK_WIN32_ENABLE_EGL */
+/* define EGL stuff as no-op macros or functions if it is not enabled */
-gboolean
-_gdk_win32_display_make_gl_context_current (GdkDisplay *display,
- GdkGLContext *context)
+#define gdk_win32_display_init_egl(disp) disp->gl_type = GDK_WIN32_GL_NONE
+#define gdk_win32_display_make_egl_context_current(disp,ctx) FALSE
+
+void
+gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window)
+{
+}
+
+static gboolean
+find_eglconfig_for_window (GdkWin32Display *display_win32,
+ gboolean need_alpha_bits,
+ GError **error)
+{
+ return FALSE;
+}
+#endif /* !GDK_WIN32_ENABLE_EGL */
+
+static void
+gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass)
+{
+ GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+}
+
+static void
+gdk_win32_gl_context_init (GdkWin32GLContext *self)
+{
+}
+
+void
+gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
+ cairo_region_t *update_area)
{
+ cairo_rectangle_int_t window_rect;
+ gboolean invalidate_all = FALSE;
GdkWin32GLContext *context_win32;
- GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
- GdkWindow *window;
- GdkScreen *screen;
+ cairo_rectangle_int_t whole_window = { 0, 0, gdk_window_get_width (window), gdk_window_get_height (window)
};
-#if GDK_WIN32_ENABLE_EGL
- EGLSurface egl_surface;
-#endif
+ /* Minimal update is ok if we're not drawing with gl */
+ if (window->gl_paint_context == NULL)
+ return;
- gboolean do_frame_sync = FALSE;
+ context_win32 = GDK_WIN32_GL_CONTEXT (window->gl_paint_context);
+ context_win32->do_blit_swap = FALSE;
- if (context == NULL)
+ if (gdk_gl_context_has_framebuffer_blit (window->gl_paint_context) &&
+ cairo_region_contains_rectangle (update_area, &whole_window) != CAIRO_REGION_OVERLAP_IN)
{
- if (display_win32->have_wgl)
- wglMakeCurrent(NULL, NULL);
-
-#ifdef GDK_WIN32_ENABLE_EGL
- else if (display_win32->have_egl)
- eglMakeCurrent (display_win32->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-#endif
- return TRUE;
+ context_win32->do_blit_swap = TRUE;
}
+ else
+ invalidate_all = TRUE;
- context_win32 = GDK_WIN32_GL_CONTEXT (context);
- window = gdk_gl_context_get_window (context);
-
- if (!gdk_gl_context_get_use_es (context))
+ if (invalidate_all)
{
- if (!wglMakeCurrent (context_win32->gl_hdc, context_win32->hglrc))
- {
- GDK_NOTE (OPENGL,
- g_print ("Making WGL context current failed\n"));
- return FALSE;
- }
+ window_rect.x = 0;
+ window_rect.y = 0;
+ window_rect.width = gdk_window_get_width (window);
+ window_rect.height = gdk_window_get_height (window);
- if (context_win32->is_attached)
- {
- if (display_win32->hasWglEXTSwapControl)
- {
- /* 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. */
- screen = gdk_window_get_screen (window);
- do_frame_sync = ! gdk_screen_is_composited (screen);
-
- 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);
- }
- }
- }
+ /* If nothing else is known, repaint everything so that the back
+ buffer is fully up-to-date for the swapbuffer */
+ cairo_region_union_rectangle (update_area, &window_rect);
}
+}
+
+static void
+gdk_win32_display_init_gl (GdkDisplay *display,
+ const gboolean need_alpha_bits)
+{
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+ gint best_idx = 0;
+ gboolean disable_wgl = FALSE;
+
+ if (display_win32->gl_type == GDK_WIN32_GL_WGL ||
+ display_win32->gl_type == GDK_WIN32_GL_EGL)
+ return;
+
+ disable_wgl = ((_gdk_gl_flags & GDK_GL_GLES) != 0) ||
+ display_win32->running_on_arm64;
+
+ if (!disable_wgl)
+ gdk_win32_display_init_wgl (display_win32, need_alpha_bits);
-#ifdef GDK_WIN32_ENABLE_EGL
else
- {
- if (context_win32->is_attached)
- egl_surface = _gdk_win32_window_get_egl_surface (window, context_win32->egl_config, FALSE);
- else
- {
- if (display_win32->hasEglSurfacelessContext)
- egl_surface = EGL_NO_SURFACE;
- else
- egl_surface = _gdk_win32_window_get_egl_surface (window, context_win32->egl_config, TRUE);
- }
+ gdk_win32_display_init_egl (display_win32);
+}
- if (!eglMakeCurrent (display_win32->egl_disp,
- egl_surface,
- egl_surface,
- context_win32->egl_context))
- {
- g_warning ("eglMakeCurrent failed");
- return FALSE;
- }
+GdkGLContext *
+gdk_win32_window_create_gl_context (GdkWindow *window,
+ gboolean attached,
+ GdkGLContext *share,
+ GError **error)
+{
+ GdkDisplay *display = gdk_window_get_display (window);
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_window_get_display (window));
+ GdkWin32GLContext *context_win32 = NULL;
+ GdkVisual *visual = gdk_window_get_visual (window);
+
+ gboolean need_alpha_bits = (visual == gdk_screen_get_rgba_visual (gdk_display_get_default_screen
(display)));
+
+ /* Acquire and store up the Windows-specific HWND and HDC */
+ HDC hdc = GetDC (GDK_WINDOW_HWND (window));
+
+ /* display_win32->hdc_egl_temp should *not* be destroyed here! It is destroyed at dispose()! */
+ display_win32->hdc_egl_temp = hdc;
+ gdk_win32_display_init_gl (display, need_alpha_bits);
- if (display_win32->egl_min_swap_interval == 0)
- eglSwapInterval (display_win32->egl_disp, 0);
- else
- g_debug ("Can't disable GL swap interval");
+ if (display_win32->gl_type == GDK_WIN32_GL_NONE)
+ {
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ _("No GL implementation is available"));
+ return NULL;
+ }
+
+ if (display_win32->gl_type == GDK_WIN32_GL_EGL &&
+ !find_eglconfig_for_window (display_win32, need_alpha_bits, error))
+ {
+ display_win32->gl_type = GDK_WIN32_GL_NONE;
+ return NULL;
}
+
+ if (display_win32->gl_type == GDK_WIN32_GL_WGL)
+ context_win32 = GDK_WIN32_GL_CONTEXT (g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
+ "display", display,
+ "window", window,
+ "shared-context", share,
+ NULL));
+#ifdef GDK_WIN32_ENABLE_EGL
+ else if (display_win32->gl_type == GDK_WIN32_GL_EGL)
+ context_win32 = GDK_WIN32_GL_CONTEXT (g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL,
+ "display", display,
+ "window", window,
+ "shared-context", share,
+ NULL));
#endif
- return TRUE;
+ context_win32->need_alpha_bits = need_alpha_bits;
+ context_win32->gl_hdc = hdc;
+ context_win32->is_attached = attached;
+
+ return GDK_GL_CONTEXT (context_win32);
+}
+
+gboolean
+gdk_win32_display_make_gl_context_current (GdkDisplay *display,
+ GdkGLContext *context)
+{
+ GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+
+ if (display_win32->gl_type == GDK_WIN32_GL_WGL)
+ return gdk_win32_display_make_wgl_context_current (display, context);
+
+ if (display_win32->gl_type == GDK_WIN32_GL_EGL)
+ return gdk_win32_display_make_egl_context_current (display, context);
+
+ g_assert_not_reached ();
+ return FALSE;
}
/**
@@ -1353,47 +1514,16 @@ gdk_win32_display_get_wgl_version (GdkDisplay *display,
display_win32 = GDK_WIN32_DISPLAY (display);
- if (!_gdk_win32_display_init_gl (display, FALSE) || !display_win32->have_wgl
-#ifdef GDK_WIN32_ENABLE_EGL
- || !display_win32->have_egl
-#endif
- )
- return FALSE;
+ if (display_win32->gl_type == GDK_WIN32_GL_PENDING)
+ gdk_win32_display_init_gl (display, FALSE);
- if (display_win32->have_wgl)
- {
- if (major != NULL)
- *major = GDK_WIN32_DISPLAY (display)->gl_version / 10;
- if (minor != NULL)
- *minor = GDK_WIN32_DISPLAY (display)->gl_version % 10;
- }
+ if (display_win32->gl_type == GDK_WIN32_GL_NONE)
+ return FALSE;
-#ifdef GDK_WIN32_ENABLE_EGL
- else if (display_win32->have_egl)
- {
- if (major != NULL)
- *major = GDK_WIN32_DISPLAY (display)->egl_version / 10;
- if (minor != NULL)
- *minor = GDK_WIN32_DISPLAY (display)->egl_version % 10;
- }
-#endif
+ if (major != NULL)
+ *major = GDK_WIN32_DISPLAY (display)->gl_version / 10;
+ if (minor != NULL)
+ *minor = GDK_WIN32_DISPLAY (display)->gl_version % 10;
return TRUE;
}
-
-void
-_gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window)
-{
-/* If we are using ANGLE, we need to force redraw of the whole Window and its child windows
- * as we need to re-acquire the EGL surfaces that we rendered to upload to Cairo explicitly,
- * using gdk_window_invalidate_rect (), when we maximize or restore or use aerosnap
- */
-#ifdef GDK_WIN32_ENABLE_EGL
- if (window->gl_paint_context != NULL && gdk_gl_context_get_use_es (window->gl_paint_context))
- {
- GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
-
- impl->egl_force_redraw_all = TRUE;
- }
-#endif
-}
diff --git a/gdk/win32/gdkglcontext-win32.h b/gdk/win32/gdkglcontext-win32.h
index d58760ce63..283e67c969 100644
--- a/gdk/win32/gdkglcontext-win32.h
+++ b/gdk/win32/gdkglcontext-win32.h
@@ -32,62 +32,29 @@
#include "gdkdisplayprivate.h"
#include "gdkvisual.h"
#include "gdkwindow.h"
-#include "gdkinternals.h"
-#include "gdkmain.h"
G_BEGIN_DECLS
-struct _GdkWin32GLContext
-{
- GdkGLContext parent_instance;
+#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)
- /* WGL Context Items */
- HGLRC hglrc;
- HDC gl_hdc;
- guint need_alpha_bits : 1;
-
- /* other items */
- guint is_attached : 1;
- guint do_frame_sync : 1;
- guint do_blit_swap : 1;
-
-#ifdef GDK_WIN32_ENABLE_EGL
- /* EGL (Angle) Context Items */
- EGLContext egl_context;
- EGLConfig egl_config;
-#endif
-};
-
-struct _GdkWin32GLContextClass
-{
- GdkGLContextClass parent_class;
-};
+void
+gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window);
GdkGLContext *
-_gdk_win32_window_create_gl_context (GdkWindow *window,
- gboolean attached,
- GdkGLContext *share,
- GError **error);
+gdk_win32_window_create_gl_context (GdkWindow *window,
+ gboolean attached,
+ GdkGLContext *share,
+ GError **error);
void
-_gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
- cairo_region_t *update_area);
-
-void
-_gdk_win32_gl_context_end_frame (GdkGLContext *context,
- cairo_region_t *painted,
- cairo_region_t *damage);
-
-gboolean
-_gdk_win32_display_make_gl_context_current (GdkDisplay *display,
- GdkGLContext *context);
+gdk_win32_window_invalidate_for_new_frame (GdkWindow *window,
+ cairo_region_t *update_area);
gboolean
-_gdk_win32_gl_context_realize (GdkGLContext *context,
- GError **error);
-
-void
-_gdk_win32_window_invalidate_egl_framebuffer (GdkWindow *window);
+gdk_win32_display_make_gl_context_current (GdkDisplay *display,
+ GdkGLContext *context);
G_END_DECLS
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 2d0faaca3e..6334e10325 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -1690,7 +1690,7 @@ gdk_win32_window_move_resize (GdkWindow *window,
}
else
{
- _gdk_win32_window_invalidate_egl_framebuffer (window);
+ gdk_win32_window_invalidate_egl_framebuffer (window);
if (with_move)
{
gdk_win32_window_move_resize_internal (window, x, y, width, height);
@@ -4758,7 +4758,7 @@ gdk_win32_window_end_move_resize_drag (GdkWindow *window)
GdkW32DragMoveResizeContext *context = &impl->drag_move_resize_context;
if (context->op == GDK_WIN32_DRAGOP_RESIZE)
- _gdk_win32_window_invalidate_egl_framebuffer (window);
+ gdk_win32_window_invalidate_egl_framebuffer (window);
context->op = GDK_WIN32_DRAGOP_NONE;
@@ -5279,7 +5279,7 @@ gdk_win32_window_unmaximize (GdkWindow *window)
GDK_WINDOW_HWND (window),
_gdk_win32_window_state_to_string (window->state)));
- _gdk_win32_window_invalidate_egl_framebuffer (window);
+ gdk_win32_window_invalidate_egl_framebuffer (window);
if (GDK_WINDOW_IS_MAPPED (window))
GtkShowWindow (window, SW_RESTORE);
@@ -5376,7 +5376,7 @@ gdk_win32_window_unfullscreen (GdkWindow *window)
impl->hint_flags = fi->hint_flags;
SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
- _gdk_win32_window_invalidate_egl_framebuffer (window);
+ gdk_win32_window_invalidate_egl_framebuffer (window);
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
fi->r.left, fi->r.top,
fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
@@ -6279,8 +6279,8 @@ gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
impl_class->get_property = _gdk_win32_window_get_property;
impl_class->change_property = _gdk_win32_window_change_property;
impl_class->delete_property = _gdk_win32_window_delete_property;
- impl_class->create_gl_context = _gdk_win32_window_create_gl_context;
- impl_class->invalidate_for_new_frame = _gdk_win32_window_invalidate_for_new_frame;
+ impl_class->create_gl_context = gdk_win32_window_create_gl_context;
+ impl_class->invalidate_for_new_frame = gdk_win32_window_invalidate_for_new_frame;
impl_class->get_scale_factor = _gdk_win32_window_get_scale_factor;
impl_class->get_unscaled_size = _gdk_win32_window_get_unscaled_size;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]