[gtk/wip/otte/gl-hdr: 7/7] egl: Unify context creation




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]