[gtk/wip/otte/gl-hdr: 7/7] egl: Unify context creation
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/gl-hdr: 7/7] egl: Unify context creation
- Date: Tue, 5 Oct 2021 23:49:46 +0000 (UTC)
commit 502068fbfd3f2fd6a5535e29761b722b899d3867
Author: Benjamin Otte <otte redhat com>
Date: Wed Oct 6 00:34:10 2021 +0200
egl: Unify context creation
Make sure X11 and Wayland EGL run the same context creation code.
This is a bit ugly to implement, because I don't want to create an
interfae and I can't make them inherit from the same object, because
one needs to inherit from X11GLContext and the other from
WaylandGLContext.
So we pass in the offset to the EGLContext member as a struct offset.
gdk/gdkglcontext.c | 167 +++++++++++++++++++++++++++++++++++++
gdk/gdkglcontextprivate.h | 3 +
gdk/wayland/gdkglcontext-wayland.c | 153 +--------------------------------
gdk/x11/gdkglcontext-egl.c | 126 +---------------------------
4 files changed, 178 insertions(+), 271 deletions(-)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 2b2e15c54f..d5f2ca15bb 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -80,6 +80,7 @@
#include "gdkdisplayprivate.h"
#include "gdkintl.h"
#include "gdkmemorytextureprivate.h"
+#include "gdkprofilerprivate.h"
#include "gdk-private.h"
@@ -88,6 +89,9 @@
#endif
#include <epoxy/gl.h>
+#ifdef HAVE_EGL
+#include <epoxy/egl.h>
+#endif
typedef struct {
int major;
@@ -1358,3 +1362,166 @@ gdk_gl_backend_use (GdkGLBackend backend_type)
g_assert (the_gl_backend_type == backend_type);
}
+
+#ifdef HAVE_EGL
+
+#define N_EGL_ATTRS 16
+
+gboolean
+gdk_gl_context_egl_create_context (GdkGLContext *context,
+ gsize struct_offset,
+ GError **error)
+{
+ GdkDisplay *display = gdk_gl_context_get_display (context);
+ GdkGLContext *share = gdk_display_get_gl_context (display);
+ EGLDisplay egl_display = gdk_display_get_egl_display (display);
+ EGLConfig egl_config = gdk_display_get_egl_config (display);
+ EGLContext ctx;
+ EGLint context_attribs[N_EGL_ATTRS];
+ int major, minor, flags;
+ gboolean debug_bit, forward_bit, legacy_bit, use_es;
+ int i = 0;
+ G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
+
+ 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) ||
+ (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));
+
+ flags = 0;
+
+ if (debug_bit)
+ flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
+ if (forward_bit)
+ flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
+
+ if (!use_es)
+ {
+ eglBindAPI (EGL_OPENGL_API);
+
+ /* We want a core profile, unless in legacy mode */
+ context_attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
+ context_attribs[i++] = legacy_bit
+ ? EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR
+ : EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
+
+ /* Specify the version */
+ context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION_KHR;
+ context_attribs[i++] = legacy_bit ? 3 : major;
+ context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION_KHR;
+ context_attribs[i++] = legacy_bit ? 0 : minor;
+ }
+ else
+ {
+ eglBindAPI (EGL_OPENGL_ES_API);
+
+ context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
+ if (major == 3)
+ context_attribs[i++] = 3;
+ else
+ context_attribs[i++] = 2;
+ }
+
+ /* 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);
+
+ GDK_DISPLAY_NOTE (display, OPENGL,
+ g_message ("Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s, es:%s)",
+ major, minor,
+ debug_bit ? "yes" : "no",
+ forward_bit ? "yes" : "no",
+ legacy_bit ? "yes" : "no",
+ use_es ? "yes" : "no"));
+
+ ctx = eglCreateContext (egl_display,
+ egl_config,
+ share != NULL ? G_STRUCT_MEMBER (EGLContext, share, struct_offset)
+ : EGL_NO_CONTEXT,
+ context_attribs);
+
+ /* If context creation failed without the ES bit, let's try again with it */
+ if (ctx == NULL)
+ {
+ i = 0;
+ context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION;
+ context_attribs[i++] = 2;
+ context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
+ context_attribs[i++] = 0;
+ context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
+ context_attribs[i++] = flags & ~EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
+ context_attribs[i++] = EGL_NONE;
+ g_assert (i < N_EGL_ATTRS);
+
+ eglBindAPI (EGL_OPENGL_ES_API);
+
+ legacy_bit = FALSE;
+ use_es = TRUE;
+
+ GDK_DISPLAY_NOTE (display, OPENGL,
+ g_message ("eglCreateContext failed, switching to OpenGLĀ ES"));
+ ctx = eglCreateContext (egl_display,
+ egl_config,
+ share != NULL ? G_STRUCT_MEMBER (EGLContext, share, struct_offset)
+ : EGL_NO_CONTEXT,
+ context_attribs);
+ }
+
+ /* If context creation failed without the legacy bit, let's try again with it */
+ if (ctx == NULL)
+ {
+ i = 0;
+ context_attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
+ context_attribs[i++] = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
+ context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION;
+ context_attribs[i++] = 3;
+ context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
+ context_attribs[i++] = 0;
+ context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
+ context_attribs[i++] = flags & ~EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
+ context_attribs[i++] = EGL_NONE;
+ g_assert (i < N_EGL_ATTRS);
+
+ eglBindAPI (EGL_OPENGL_API);
+
+ legacy_bit = TRUE;
+ use_es = FALSE;
+
+ GDK_DISPLAY_NOTE (display, OPENGL,
+ g_message ("eglCreateContext failed, switching to legacy"));
+ ctx = eglCreateContext (egl_display,
+ egl_config,
+ share != NULL ? G_STRUCT_MEMBER (EGLContext, share, struct_offset)
+ : EGL_NO_CONTEXT,
+ context_attribs);
+ }
+
+ if (ctx == NULL)
+ {
+ g_set_error_literal (error, GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ _("Unable to create a GL context"));
+ return FALSE;
+ }
+
+ GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Created EGL context[%p]", ctx));
+
+ G_STRUCT_MEMBER (EGLContext, context, struct_offset) = ctx;
+
+ gdk_gl_context_set_is_legacy (context, legacy_bit);
+ gdk_gl_context_set_use_es (context, use_es);
+
+ gdk_profiler_end_mark (start_time, "realize GdkWaylandGLContext", NULL);
+
+ return TRUE;
+}
+
+#undef N_EGL_ATTRS
+
+#endif
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index db7ab4ce9c..3447379982 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -133,6 +133,9 @@ gboolean gdk_gl_context_has_debug (GdkGLContext
gboolean gdk_gl_context_use_es_bgra (GdkGLContext *context);
+gboolean gdk_gl_context_egl_create_context (GdkGLContext *context,
+ gsize struct_offset,
+ GError **error);
G_END_DECLS
diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c
index e4b93d3edb..b725c351d1 100644
--- a/gdk/wayland/gdkglcontext-wayland.c
+++ b/gdk/wayland/gdkglcontext-wayland.c
@@ -47,159 +47,14 @@ G_DEFINE_TYPE (GdkWaylandGLContext, gdk_wayland_gl_context, GDK_TYPE_GL_CONTEXT)
static void gdk_wayland_gl_context_dispose (GObject *gobject);
-#define N_EGL_ATTRS 16
-
static gboolean
gdk_wayland_gl_context_realize (GdkGLContext *context,
GError **error)
{
- GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
- GdkDisplay *display = gdk_gl_context_get_display (context);
- GdkGLContext *share = gdk_display_get_gl_context (display);
- EGLDisplay egl_display = gdk_display_get_egl_display (display);
- EGLConfig egl_config = gdk_display_get_egl_config (display);
- EGLContext ctx;
- EGLint context_attribs[N_EGL_ATTRS];
- int major, minor, flags;
- gboolean debug_bit, forward_bit, legacy_bit, use_es;
- int i = 0;
- G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
-
- 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) ||
- (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));
-
- flags = 0;
-
- if (debug_bit)
- flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
- if (forward_bit)
- flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
-
- if (!use_es)
- {
- eglBindAPI (EGL_OPENGL_API);
-
- /* We want a core profile, unless in legacy mode */
- context_attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
- context_attribs[i++] = legacy_bit
- ? EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR
- : EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
-
- /* Specify the version */
- context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION_KHR;
- context_attribs[i++] = legacy_bit ? 3 : major;
- context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION_KHR;
- context_attribs[i++] = legacy_bit ? 0 : minor;
- }
- else
- {
- eglBindAPI (EGL_OPENGL_ES_API);
-
- context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
- if (major == 3)
- context_attribs[i++] = 3;
- else
- context_attribs[i++] = 2;
- }
-
- /* 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);
-
- GDK_DISPLAY_NOTE (display, OPENGL,
- g_message ("Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s, es:%s)",
- major, minor,
- debug_bit ? "yes" : "no",
- forward_bit ? "yes" : "no",
- legacy_bit ? "yes" : "no",
- use_es ? "yes" : "no"));
-
- ctx = eglCreateContext (egl_display,
- egl_config,
- share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
- : EGL_NO_CONTEXT,
- context_attribs);
-
- /* If context creation failed without the ES bit, let's try again with it */
- if (ctx == NULL)
- {
- i = 0;
- context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION;
- context_attribs[i++] = 2;
- context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
- context_attribs[i++] = 0;
- context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
- context_attribs[i++] = flags & ~EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
- context_attribs[i++] = EGL_NONE;
- g_assert (i < N_EGL_ATTRS);
-
- eglBindAPI (EGL_OPENGL_ES_API);
-
- legacy_bit = FALSE;
- use_es = TRUE;
-
- GDK_DISPLAY_NOTE (display, OPENGL,
- g_message ("eglCreateContext failed, switching to OpenGLĀ ES"));
- ctx = eglCreateContext (egl_display,
- egl_config,
- share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
- : EGL_NO_CONTEXT,
- context_attribs);
- }
-
- /* If context creation failed without the legacy bit, let's try again with it */
- if (ctx == NULL)
- {
- i = 0;
- context_attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
- context_attribs[i++] = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
- context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION;
- context_attribs[i++] = 3;
- context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
- context_attribs[i++] = 0;
- context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
- context_attribs[i++] = flags & ~EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
- context_attribs[i++] = EGL_NONE;
- g_assert (i < N_EGL_ATTRS);
-
- eglBindAPI (EGL_OPENGL_API);
-
- legacy_bit = TRUE;
- use_es = FALSE;
-
- GDK_DISPLAY_NOTE (display, OPENGL,
- g_message ("eglCreateContext failed, switching to legacy"));
- ctx = eglCreateContext (egl_display,
- egl_config,
- share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
- : EGL_NO_CONTEXT,
- context_attribs);
- }
-
- if (ctx == NULL)
- {
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_NOT_AVAILABLE,
- _("Unable to create a GL context"));
- return FALSE;
- }
-
- GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Created EGL context[%p]", ctx));
-
- context_wayland->egl_context = ctx;
-
- gdk_gl_context_set_is_legacy (context, legacy_bit);
- gdk_gl_context_set_use_es (context, use_es);
-
- gdk_profiler_end_mark (start_time, "realize GdkWaylandGLContext", NULL);
+ if (!gdk_gl_context_egl_create_context (context,
+ G_STRUCT_OFFSET (GdkWaylandGLContext, egl_context),
+ error))
+ return FALSE;
return TRUE;
}
diff --git a/gdk/x11/gdkglcontext-egl.c b/gdk/x11/gdkglcontext-egl.c
index 1c83e50850..d424e6a6b0 100644
--- a/gdk/x11/gdkglcontext-egl.c
+++ b/gdk/x11/gdkglcontext-egl.c
@@ -228,136 +228,18 @@ gdk_x11_gl_context_egl_get_damage (GdkGLContext *context)
return GDK_GL_CONTEXT_CLASS (gdk_x11_gl_context_egl_parent_class)->get_damage (context);
}
-#define N_EGL_ATTRS 16
-
static gboolean
gdk_x11_gl_context_egl_realize (GdkGLContext *context,
GError **error)
{
- GdkDisplay *display;
- GdkX11GLContextEGL *context_egl;
- GdkGLContext *share;
- EGLDisplay egl_display;
- EGLConfig egl_config;
- gboolean debug_bit, forward_bit, legacy_bit, use_es;
- int major, minor, flags, i = 0;
- EGLint context_attrs[N_EGL_ATTRS];
-
- display = gdk_gl_context_get_display (context);
-
- context_egl = GDK_X11_GL_CONTEXT_EGL (context);
- share = gdk_display_get_gl_context (display);
- egl_display = gdk_display_get_egl_display (display),
- egl_config = gdk_display_get_egl_config (display),
-
- 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) ||
- (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));
-
- flags = 0;
- if (debug_bit)
- flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
- if (forward_bit)
- flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
-
- if (!use_es)
- {
- eglBindAPI (EGL_OPENGL_API);
-
- /* We want a core profile, unless in legacy mode */
- context_attrs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
- context_attrs[i++] = legacy_bit
- ? EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR
- : EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
-
- /* Specify the version */
- context_attrs[i++] = EGL_CONTEXT_MAJOR_VERSION_KHR;
- context_attrs[i++] = legacy_bit ? 3 : major;
- context_attrs[i++] = EGL_CONTEXT_MINOR_VERSION_KHR;
- context_attrs[i++] = legacy_bit ? 0 : minor;
- context_attrs[i++] = EGL_CONTEXT_FLAGS_KHR;
- }
- else
- {
- eglBindAPI (EGL_OPENGL_ES_API);
-
- context_attrs[i++] = EGL_CONTEXT_CLIENT_VERSION;
- if (major == 3)
- context_attrs[i++] = 3;
- else
- context_attrs[i++] = 2;
- }
-
- context_attrs[i++] = EGL_CONTEXT_FLAGS_KHR;
- context_attrs[i++] = flags;
-
- context_attrs[i++] = EGL_NONE;
- g_assert (i < N_EGL_ATTRS);
-
- GDK_DISPLAY_NOTE (display, OPENGL,
- g_message ("Creating EGL context version %d.%d (shared:%s, debug:%s, forward:%s,
legacy:%s, es:%s)",
- major, minor,
- share != NULL ? "yes" : "no",
- debug_bit ? "yes" : "no",
- forward_bit ? "yes" : "no",
- legacy_bit ? "yes" : "no",
- use_es ? "yes" : "no"));
-
- context_egl->egl_context =
- eglCreateContext (egl_display,
- egl_config,
- share != NULL
- ? GDK_X11_GL_CONTEXT_EGL (share)->egl_context
- : EGL_NO_CONTEXT,
- context_attrs);
-
- /* If we're not asking for a GLES context, and we don't have the legacy bit set
- * already, try again with a legacy context
- */
- if (context_egl->egl_context == NULL && !use_es && !legacy_bit)
- {
- context_attrs[1] = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
- context_attrs[3] = 3;
- context_attrs[5] = 0;
-
- legacy_bit = TRUE;
- use_es = FALSE;
-
- GDK_NOTE (OPENGL,
- g_message ("Context creation failed; trying legacy EGL context"));
-
- context_egl->egl_context =
- eglCreateContext (egl_display,
- egl_config,
- share != NULL
- ? GDK_X11_GL_CONTEXT_EGL (share)->egl_context
- : EGL_NO_CONTEXT,
- context_attrs);
- }
-
- if (context_egl->egl_context == NULL)
- {
- g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
- _("Unable to create a GL context"));
- return FALSE;
- }
-
- gdk_gl_context_set_is_legacy (context, legacy_bit);
- gdk_gl_context_set_use_es (context, use_es);
-
- GDK_NOTE (OPENGL,
- g_message ("Realized EGL context[%p]",
- context_egl->egl_context));
+ if (!gdk_gl_context_egl_create_context (context,
+ G_STRUCT_OFFSET (GdkX11GLContextEGL, egl_context),
+ error))
+ return FALSE;
return TRUE;
}
-#undef N_EGL_ATTRS
-
static void
gdk_x11_gl_context_egl_dispose (GObject *gobject)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]