summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-01-19 13:49:40 +0000
committerMatthias Clasen <mclasen@redhat.com>2022-01-19 13:49:40 +0000
commit68985d42bb8952c24a9c0ae836363db07cd8bc44 (patch)
tree17c9e9823dc4d95711b4ce83997b5bea066dd931
parent9146a21738a310066bf2a597e424d44ac4a1c238 (diff)
parent0fe37d18282c436d736280a13bfa62538bd6ace6 (diff)
downloadgtk+-68985d42bb8952c24a9c0ae836363db07cd8bc44.tar.gz
Merge branch 'win32-gl-improvements' into 'main'
Windows: Some fixes to GL context realization (EGL/GLES in particular) See merge request GNOME/gtk!4386
-rw-r--r--gdk/gdkdisplay.c2
-rw-r--r--gdk/gdkdisplayprivate.h1
-rw-r--r--gdk/gdkglcontext.c21
-rw-r--r--gdk/win32/gdkdisplay-win32.c83
-rw-r--r--gdk/win32/gdkdisplay-win32.h1
-rw-r--r--gdk/win32/gdkglcontext-win32-wgl.c64
-rw-r--r--gsk/gskrenderer.c9
7 files changed, 87 insertions, 94 deletions
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index dddc8b2060..0e935d8176 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -1727,6 +1727,8 @@ gdk_display_init_egl (GdkDisplay *self,
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
self->have_egl_pixel_format_float =
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
+ self->have_egl_win32_libangle =
+ epoxy_has_egl_extension (priv->egl_display, "EGL_ANGLE_d3d_share_handle_client_buffer");
if (self->have_egl_no_config_context)
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h
index cb80ad3f88..4eb3625d88 100644
--- a/gdk/gdkdisplayprivate.h
+++ b/gdk/gdkdisplayprivate.h
@@ -110,6 +110,7 @@ struct _GdkDisplay
guint have_egl_swap_buffers_with_damage : 1;
guint have_egl_no_config_context : 1;
guint have_egl_pixel_format_float : 1;
+ guint have_egl_win32_libangle : 1;
};
struct _GdkDisplayClass
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 3c5e4ffdb1..d1bc7c57c2 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -278,7 +278,15 @@ gdk_gl_context_real_realize (GdkGLContext *context,
int i = 0;
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
- gdk_gl_context_get_required_version (context, &major, &minor);
+ if (share != NULL)
+ {
+ gdk_gl_context_get_required_version (share, &major, &minor);
+ gdk_gl_context_set_allowed_apis (context,
+ gdk_gl_context_get_allowed_apis (share));
+ }
+ else
+ gdk_gl_context_get_required_version (context, &major, &minor);
+
debug_bit = gdk_gl_context_get_debug_enabled (context);
forward_bit = gdk_gl_context_get_forward_compatible (context);
legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ||
@@ -1048,26 +1056,29 @@ gdk_gl_context_get_required_version (GdkGLContext *context,
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
gboolean force_gles = FALSE;
-#ifdef G_ENABLE_DEBUG
GdkDisplay *display;
-#endif
int default_major, default_minor;
int maj, min;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
-#ifdef G_ENABLE_DEBUG
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
+
+#ifdef G_ENABLE_DEBUG
force_gles = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES);
#endif
+ /* libANGLE on Windows at least requires GLES 3.0+ */
+ if (display->have_egl_win32_libangle)
+ force_gles = TRUE;
+
/* Default fallback values for uninitialised contexts; we
* enforce a context version number of 3.2 for desktop GL,
* and 2.0 for GLES
*/
if (gdk_gl_context_get_use_es (context) || force_gles)
{
- default_major = 2;
+ default_major = display->have_egl_win32_libangle ? 3 : 2;
default_minor = 0;
}
else
diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c
index 675e1af5e2..a544bf3827 100644
--- a/gdk/win32/gdkdisplay-win32.c
+++ b/gdk/win32/gdkdisplay-win32.c
@@ -1175,16 +1175,18 @@ gdk_win32_display_get_setting (GdkDisplay *display,
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
#endif
-static gboolean
-gdk_win32_display_init_gl_backend (GdkDisplay *display,
- GError **error)
+static GdkGLContext *
+gdk_win32_display_init_gl (GdkDisplay *display,
+ GError **error)
{
- gboolean result = FALSE;
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+ HDC init_gl_hdc = NULL;
if (display_win32->dummy_context_wgl.hdc == NULL)
display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
+ init_gl_hdc = display_win32->dummy_context_wgl.hdc;
+
/*
* No env vars set, do the regular GL initialization, first WGL and then EGL,
* as WGL is the more tried-and-tested configuration.
@@ -1192,59 +1194,50 @@ gdk_win32_display_init_gl_backend (GdkDisplay *display,
#ifdef HAVE_EGL
/*
- * Disable defaulting to EGL for now, since shaders need to be fixed for
- * usage against libANGLE EGL. EGL is used more as a compatibility layer
+ * Disable defaulting to EGL as EGL is used more as a compatibility layer
* on Windows rather than being a native citizen on Windows
*/
- if (_gdk_debug_flags & GDK_DEBUG_GL_EGL)
- result = gdk_display_init_egl (display,
- EGL_PLATFORM_ANGLE_ANGLE,
- display_win32->dummy_context_wgl.hdc,
- FALSE,
- error);
-#endif
-
- if (!result)
+ if (GDK_DEBUG_CHECK (GL_EGL) || GDK_DEBUG_CHECK (GL_GLES))
{
- g_clear_error (error);
- result = gdk_win32_display_init_wgl (display, error);
+ if (gdk_display_init_egl (display,
+ EGL_PLATFORM_ANGLE_ANGLE,
+ init_gl_hdc,
+ FALSE,
+ error))
+ {
+ return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL,
+ "display", display,
+ NULL);
+ }
+ else
+ g_clear_error (error);
}
+#endif
-#ifdef HAVE_EGL
- if (!result)
+ if (gdk_win32_display_init_wgl (display, error))
{
- g_clear_error (error);
- result = gdk_display_init_egl (display,
- EGL_PLATFORM_ANGLE_ANGLE,
- display_win32->dummy_context_wgl.hdc,
- TRUE,
- error);
+ return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
+ "display", display,
+ NULL);
}
-#endif
- return result;
-}
-
-static GdkGLContext *
-gdk_win32_display_init_gl (GdkDisplay *display,
- GError **error)
-{
- GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
- GdkGLContext *gl_context = NULL;
+#ifdef HAVE_EGL
+ g_clear_error (error);
- if (!gdk_win32_display_init_gl_backend (display, error))
- return NULL;
+ if (gdk_display_init_egl (display,
+ EGL_PLATFORM_ANGLE_ANGLE,
+ init_gl_hdc,
+ TRUE,
+ error))
+ {
+ return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL,
+ "display", display,
+ NULL);
- if (display_win32->wgl_pixel_format != 0)
- gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL, "display", display, NULL);
-#ifdef HAVE_EGL
- else if (gdk_display_get_egl_display (display))
- gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL, "display", display, NULL);
+ }
#endif
- g_return_val_if_fail (gl_context != NULL, NULL);
-
- return gl_context;
+ return NULL;
}
/**
diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h
index 3b746bbe1b..19f11e5f9f 100644
--- a/gdk/win32/gdkdisplay-win32.h
+++ b/gdk/win32/gdkdisplay-win32.h
@@ -125,7 +125,6 @@ struct _GdkWin32Display
/* WGL/OpenGL Items */
GdkWin32GLDummyContextWGL dummy_context_wgl;
- int wgl_pixel_format;
guint gl_version;
GListModel *monitors;
diff --git a/gdk/win32/gdkglcontext-win32-wgl.c b/gdk/win32/gdkglcontext-win32-wgl.c
index d443a2c7ff..231f2a6a01 100644
--- a/gdk/win32/gdkglcontext-win32-wgl.c
+++ b/gdk/win32/gdkglcontext-win32-wgl.c
@@ -258,9 +258,6 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, error))
return FALSE;
- 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
@@ -299,8 +296,6 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
}
}
- display_win32->wgl_pixel_format = best_idx;
-
display_win32->hasWglARBCreateContext =
epoxy_has_wgl_extension (hdc, "WGL_ARB_create_context");
display_win32->hasWglEXTSwapControl =
@@ -432,33 +427,13 @@ create_wgl_context (HDC hdc,
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);
+ 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)
@@ -564,10 +539,27 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
if (!gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, error))
return 0;
- 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);
+ /*
+ * We may need a Core GL 4.1+ context in order to use the GL support in
+ * the GStreamer media widget backend (such as on Intel drivers), but
+ * wglCreateContextAttribsARB() may only give us the GL context version
+ * that we ask for here, and nothing more. So, improve things here by
+ * asking for the GL version that is reported to us via epoxy_gl_version(),
+ * rather than the default GL core 3.2 context. Save this up in our
+ * GdkGLContext so that subsequent contexts that are shared with this
+ * context are created likewise too.
+ */
+ if (share != NULL)
+ gdk_gl_context_get_required_version (share, &major, &minor);
+ else
+ {
+ major = display_win32->gl_version / 10;
+ minor = display_win32->gl_version % 10;
+ }
+
if (surface != NULL)
hdc = GDK_WIN32_SURFACE (surface)->hdc;
else
@@ -634,6 +626,7 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
/* Ensure that any other context is created with a legacy bit set */
gdk_gl_context_set_is_legacy (context, legacy_bit);
+ gdk_gl_context_set_required_version (context, major, minor);
return GDK_GL_API_GL;
}
@@ -728,10 +721,11 @@ gdk_win32_display_get_wgl_version (GdkDisplay *display,
if (!GDK_IS_WIN32_DISPLAY (display))
return FALSE;
- display_win32 = GDK_WIN32_DISPLAY (display);
- if (display_win32->wgl_pixel_format == 0)
+ if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, NULL))
return FALSE;
+ display_win32 = GDK_WIN32_DISPLAY (display);
+
if (major != NULL)
*major = display_win32->gl_version / 10;
if (minor != NULL)
diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c
index b782cfd493..03aa87f512 100644
--- a/gsk/gskrenderer.c
+++ b/gsk/gskrenderer.c
@@ -597,14 +597,7 @@ get_renderer_for_backend (GdkSurface *surface)
#endif
#ifdef GDK_WINDOWING_WIN32
if (GDK_IS_WIN32_SURFACE (surface))
- /* remove check for OpenGL/ES when OpenGL/ES 2.0 shader is ready */
- {
- GdkDisplay *display = gdk_surface_get_display (surface);
-
- if (!(GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
- GDK_WIN32_DISPLAY (display)->running_on_arm64))
- return GSK_TYPE_GL_RENDERER;
- }
+ return GSK_TYPE_GL_RENDERER;
#endif
return G_TYPE_INVALID;