summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2023-04-25 20:08:33 +0200
committerBenjamin Otte <otte@redhat.com>2023-04-27 02:13:32 +0200
commit34662fc4b05fa5b43b88a093b5db7a700380387d (patch)
treeabcb32cc02a8a4e30dbb70d02a098dc09f404a05 /gdk
parent5b376cedcff5e6d30e9d1db93563d47d13b19aac (diff)
downloadgtk+-34662fc4b05fa5b43b88a093b5db7a700380387d.tar.gz
egl: Make sure highest possible GL version is created
The EGL spec states: The context returned must be the specified version, or a later version which is backwards compatible with that version. Even if a later version is returned, the specified version must correspond to a defined version of the client API. GTK has so far been relying on EGL implementations returning a later version, because that is what Mesa does. But ANGLE does not do that and only provides the minimum version, which means Windows EGL has been forced to use a lower EGL version for no reason. So fix this and try versions in order from highest to lowest.
Diffstat (limited to 'gdk')
-rw-r--r--gdk/gdkglcontext.c39
-rw-r--r--gdk/gdkglcontextprivate.h12
-rw-r--r--gdk/gdkglversionprivate.h42
3 files changed, 79 insertions, 14 deletions
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 8deca9ea1d..96eaac8d30 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -287,8 +287,11 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
EGLConfig egl_config;
EGLContext ctx;
EGLint context_attribs[N_EGL_ATTRS], i = 0, flags = 0;
+ gsize major_idx, minor_idx;
gboolean debug_bit, forward_bit;
GdkGLVersion min, version;
+ const GdkGLVersion* supported_versions;
+ gsize j;
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
if (!gdk_gl_context_is_api_allowed (context, api, NULL))
@@ -328,9 +331,9 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
flags &= ~EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION;
- context_attribs[i++] = gdk_gl_version_get_major (&version);
+ major_idx = i++;
context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
- context_attribs[i++] = gdk_gl_version_get_minor (&version);
+ minor_idx = i++;
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
context_attribs[i++] = flags;
@@ -345,17 +348,27 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
legacy ? "yes" : "no",
api == GDK_GL_API_GLES ? "yes" : "no");
- ctx = eglCreateContext (egl_display,
- egl_config,
- share ? share_priv->egl_context : EGL_NO_CONTEXT,
- context_attribs);
+ supported_versions = gdk_gl_versions_get_for_api (api);
+ for (j = 0; gdk_gl_version_greater_equal (&supported_versions[j], &version); j++)
+ {
+ context_attribs [major_idx] = gdk_gl_version_get_major (&supported_versions[j]);
+ context_attribs [minor_idx] = gdk_gl_version_get_minor (&supported_versions[j]);
+
+ ctx = eglCreateContext (egl_display,
+ egl_config,
+ share ? share_priv->egl_context : EGL_NO_CONTEXT,
+ context_attribs);
+ if (ctx != NULL)
+ break;
+ }
if (ctx == NULL)
- return 0;
+ return 0;
GDK_DISPLAY_DEBUG (display, OPENGL, "Created EGL context[%p]", ctx);
priv->egl_context = ctx;
+ gdk_gl_context_set_version (context, &supported_versions[j]);
gdk_gl_context_set_is_legacy (context, legacy);
if (epoxy_has_egl_extension (egl_display, "EGL_KHR_swap_buffers_with_damage"))
@@ -1133,6 +1146,15 @@ gdk_gl_context_is_legacy (GdkGLContext *context)
}
void
+gdk_gl_context_set_version (GdkGLContext *context,
+ const GdkGLVersion *version)
+{
+ GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
+
+ priv->gl_version = *version;
+}
+
+void
gdk_gl_context_set_is_legacy (GdkGLContext *context,
gboolean is_legacy)
{
@@ -1493,7 +1515,8 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
if (priv->extensions_checked)
return;
- gdk_gl_version_init_epoxy (&priv->gl_version);
+ if (!gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (0, 0)))
+ gdk_gl_version_init_epoxy (&priv->gl_version);
priv->has_debug_output = epoxy_has_gl_extension ("GL_ARB_debug_output") ||
epoxy_has_gl_extension ("GL_KHR_debug");
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index 139a3a2bc7..24809f88ef 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -99,11 +99,13 @@ void gdk_gl_context_clear_current_if_surface (GdkSurface
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
GdkSurface *surface);
-gboolean gdk_gl_context_is_api_allowed (GdkGLContext *self,
- GdkGLAPI api,
- GError **error);
-void gdk_gl_context_set_is_legacy (GdkGLContext *context,
- gboolean is_legacy);
+gboolean gdk_gl_context_is_api_allowed (GdkGLContext *self,
+ GdkGLAPI api,
+ GError **error);
+void gdk_gl_context_set_version (GdkGLContext *context,
+ const GdkGLVersion *version);
+void gdk_gl_context_set_is_legacy (GdkGLContext *context,
+ gboolean is_legacy);
gboolean gdk_gl_context_check_gl_version (GdkGLContext *context,
const GdkGLVersion *gl_version,
const GdkGLVersion *gles_version);
diff --git a/gdk/gdkglversionprivate.h b/gdk/gdkglversionprivate.h
index 4ea97bceb6..3b1f8352df 100644
--- a/gdk/gdkglversionprivate.h
+++ b/gdk/gdkglversionprivate.h
@@ -20,7 +20,7 @@
#pragma once
-#include <glib.h>
+#include <gdkenums.h>
G_BEGIN_DECLS
@@ -52,6 +52,46 @@ struct _GdkGLVersion
#define GDK_GL_VERSION_INIT(maj,min) (GdkGLVersion) { maj, min }
#define GDK_GL_VERSION_STRING(str) GDK_GL_VERSION_INIT(str[0] - '0', str[2] - '0')
+static const GdkGLVersion supported_gl_versions[] = {
+ GDK_GL_VERSION_INIT (4, 6),
+ GDK_GL_VERSION_INIT (4, 5),
+ GDK_GL_VERSION_INIT (4, 4),
+ GDK_GL_VERSION_INIT (4, 3),
+ GDK_GL_VERSION_INIT (4, 2),
+ GDK_GL_VERSION_INIT (4, 1),
+ GDK_GL_VERSION_INIT (4, 0),
+ GDK_GL_VERSION_INIT (3, 3),
+ GDK_GL_VERSION_INIT (3, 2),
+ GDK_GL_VERSION_INIT (3, 1),
+ GDK_GL_VERSION_INIT (3, 0),
+
+ GDK_GL_VERSION_INIT (0, 0)
+};
+
+static const GdkGLVersion supported_gles_versions[] = {
+ GDK_GL_VERSION_INIT (3, 2),
+ GDK_GL_VERSION_INIT (3, 1),
+ GDK_GL_VERSION_INIT (3, 0),
+ GDK_GL_VERSION_INIT (2, 0),
+
+ GDK_GL_VERSION_INIT (0, 0)
+};
+
+static inline const GdkGLVersion *
+gdk_gl_versions_get_for_api (GdkGLAPI api)
+{
+ switch (api)
+ {
+ case GDK_GL_API_GL:
+ return supported_gl_versions;
+ case GDK_GL_API_GLES:
+ return supported_gles_versions;
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+}
+
static inline int
gdk_gl_version_get_major (const GdkGLVersion *self)
{