[gtk/wip/otte/gleanup: 49/70] gdk: Add GdkDisplay::init_gl vfunc




commit 4cdcd10c691521a41da442aedd05105dfb6503cf
Author: Benjamin Otte <otte redhat com>
Date:   Mon Jul 5 01:57:03 2021 +0200

    gdk: Add GdkDisplay::init_gl vfunc
    
    The vfunc is called to initialize GL and it returns a "base" context
    that GDK then uses as the context all others are shared with. So the GL
    context share tree now looks like:
    
    + context from init_gl
      - context1
      - context2
      ...
    
    So this is a flat tree now, the complexity is gone.
    
    The only caveat is that backends now need to create a GL context when
    initializing GL so some refactoring was needed.
    
    Two new functions have been added:
    
    * gdk_display_prepare_gl()
      This is public API and can be used to ensure that GL has been
      initialized or if not, retrieve an error to display (or debug-print).
    * gdk_display_get_gl_context()
      This is a private function to retrieve the base context from
      init_gl(). It replaces gdk_surface_get_shared_data_context().

 gdk/gdkdisplay.c                      | 135 +++++++++++++++++++++++++++++--
 gdk/gdkdisplay.h                      |   4 +
 gdk/gdkdisplayprivate.h               |   3 +
 gdk/gdksurface.c                      |  51 +-----------
 gdk/gdksurfaceprivate.h               |   1 -
 gdk/macos/gdkmacosdisplay.c           |   8 ++
 gdk/macos/gdkmacosglcontext-private.h |   7 +-
 gdk/macos/gdkmacosglcontext.c         |  19 ++---
 gdk/macos/gdkmacossurface.c           |   3 +-
 gdk/wayland/gdkdisplay-wayland.c      |   1 +
 gdk/wayland/gdkglcontext-wayland.c    |  39 ++++-----
 gdk/wayland/gdkglcontext-wayland.h    |   4 +-
 gdk/win32/gdkglcontext-win32.c        |   8 +-
 gdk/x11/gdkdisplay-x11.c              | 145 +++++++++++++++++++---------------
 gdk/x11/gdkglcontext-egl.c            |  17 ++--
 gdk/x11/gdkglcontext-glx.c            |  16 ++--
 gdk/x11/gdkglcontext-x11.c            |   8 +-
 gdk/x11/gdkglcontext-x11.h            |   2 +-
 gsk/ngl/gsknglrenderer.c              |   4 +-
 19 files changed, 285 insertions(+), 190 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index dbe8c4cf82..5891bbe5f0 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -80,6 +80,13 @@ enum {
 typedef struct _GdkDisplayPrivate GdkDisplayPrivate;
 
 struct _GdkDisplayPrivate {
+  /* The base context that all other contexts inherit from.
+   * This context is never exposed to public API and is
+   * allowed to have a %NULL surface.
+   */
+  GdkGLContext *gl_context;
+  GError *gl_error;
+
   guint rgba : 1;
   guint composited : 1;
   guint input_shapes : 1;
@@ -129,10 +136,14 @@ gdk_display_real_make_default (GdkDisplay *display)
 {
 }
 
-static void
-gdk_display_real_opened (GdkDisplay *display)
+static GdkGLContext *
+gdk_display_default_init_gl (GdkDisplay  *display,
+                             GError     **error)
 {
-  _gdk_display_manager_add_display (gdk_display_manager_get (), display);
+  g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
+                       _("The current backend does not support OpenGL"));
+
+  return NULL;
 }
 
 static GdkSeat *
@@ -144,6 +155,12 @@ gdk_display_real_get_default_seat (GdkDisplay *display)
   return display->seats->data;
 }
 
+static void
+gdk_display_real_opened (GdkDisplay *display)
+{
+  _gdk_display_manager_add_display (gdk_display_manager_get (), display);
+}
+
 static void
 gdk_display_class_init (GdkDisplayClass *class)
 {
@@ -153,10 +170,11 @@ gdk_display_class_init (GdkDisplayClass *class)
   object_class->dispose = gdk_display_dispose;
   object_class->get_property = gdk_display_get_property;
 
-  class->get_app_launch_context = gdk_display_real_get_app_launch_context;
-  class->opened = gdk_display_real_opened;
   class->make_default = gdk_display_real_make_default;
+  class->get_app_launch_context = gdk_display_real_get_app_launch_context;
+  class->init_gl = gdk_display_default_init_gl;
   class->get_default_seat = gdk_display_real_get_default_seat;
+  class->opened = gdk_display_real_opened;
 
   /**
    * GdkDisplay:composited: (attributes org.gtk.Property.get=gdk_display_is_composited)
@@ -327,11 +345,15 @@ static void
 gdk_display_dispose (GObject *object)
 {
   GdkDisplay *display = GDK_DISPLAY (object);
+  GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
 
   _gdk_display_manager_remove_display (gdk_display_manager_get (), display);
 
   g_queue_clear (&display->queued_events);
 
+  g_clear_object (&priv->gl_context);
+  g_clear_error (&priv->gl_error);
+
   G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object);
 }
 
@@ -1173,6 +1195,109 @@ gdk_display_get_keymap (GdkDisplay *display)
   return GDK_DISPLAY_GET_CLASS (display)->get_keymap (display);
 }
 
+static void
+gdk_display_init_gl (GdkDisplay *self)
+{
+  GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
+  GdkGLContext *context;
+
+  if (GDK_DISPLAY_DEBUG_CHECK (self, GL_DISABLE))
+    {
+      g_set_error_literal (&priv->gl_error, GDK_GL_ERROR,
+                           GDK_GL_ERROR_NOT_AVAILABLE,
+                           _("GL support disabled via GDK_DEBUG"));
+      return;
+    }
+
+  context = GDK_DISPLAY_GET_CLASS (self)->init_gl (self, &priv->gl_error);
+  if (context == NULL)
+    return;
+
+  if (!gdk_gl_context_realize (context, &priv->gl_error))
+    {
+      g_object_unref (context);
+      return;
+    }
+
+  /* Only assign after realize, so GdkGLContext::realize() can use
+   * gdk_display_get_gl_context() == NULL to differentiate between
+   * the display's context and any other context.
+   */
+  priv->gl_context = context;
+}
+
+/**
+ * gdk_display_prepare_gl:
+ * @self: a `GdkDisplay`
+ * @error: return location for a `GError`
+ *
+ * Checks that OpenGL is available for @self and ensures that it is
+ * properly initialized.
+ * When this fails, an @error will be set describing the error and this
+ * function returns %FALSE.
+ *
+ * Note that even if this function succeeds, creating a `GdkGLContext`
+ * may still fail.
+ *
+ * This function is idempotent. Calling it multiple times will just 
+ * return the same value or error.
+ *
+ * You never need to call this function, GDK will call it automatically
+ * as needed. But you can use it as a check when setting up code that
+ * might make use of OpenGL.
+ *
+ * Returns: %TRUE if the display supports OpenGL
+ *
+ * Since: 4.4
+ **/
+gboolean
+gdk_display_prepare_gl (GdkDisplay  *self,
+                        GError     **error)
+{
+  GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
+
+  g_return_val_if_fail (GDK_IS_DISPLAY (self), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  for (;;)
+    {
+      if (priv->gl_context)
+        return TRUE;
+
+      if (priv->gl_error != NULL)
+        {
+          if (error)
+            *error = g_error_copy (priv->gl_error);
+          return FALSE;
+        }
+
+      gdk_display_init_gl (self);
+
+      /* try again */
+    }
+}
+
+/*< private >
+ * gdk_display_get_gl_context:
+ * @self: the `GdkDisplay`
+ *
+ * Gets the GL context returned from [vfunc@Gdk.Display.init_gl]
+ * previously.
+ *
+ * If that function has not been called yet or did fail, %NULL is
+ * returned.
+ * Call [method@Gdk.Display.prepare_gl] to avoid this.
+ *
+ * Returns: The `GdkGLContext`
+ */
+GdkGLContext *
+gdk_display_get_gl_context (GdkDisplay *self)
+{
+  GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
+
+  return priv->gl_context;
+}
+
 /*< private >
  * gdk_display_make_gl_context_current:
  * @display: a `GdkDisplay`
diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h
index 97d8e7eee6..9fabac6b50 100644
--- a/gdk/gdkdisplay.h
+++ b/gdk/gdkdisplay.h
@@ -68,6 +68,10 @@ gboolean    gdk_display_is_rgba            (GdkDisplay  *display);
 GDK_AVAILABLE_IN_ALL
 gboolean    gdk_display_supports_input_shapes (GdkDisplay    *display);
 
+GDK_AVAILABLE_IN_4_4
+gboolean    gdk_display_prepare_gl         (GdkDisplay  *self,
+                                            GError     **error);
+
 GDK_AVAILABLE_IN_ALL
 GdkDisplay *gdk_display_get_default (void);
 
diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h
index 4aa99c30dd..a2913b50e9 100644
--- a/gdk/gdkdisplayprivate.h
+++ b/gdk/gdkdisplayprivate.h
@@ -140,6 +140,8 @@ struct _GdkDisplayClass
 
   GdkKeymap *                (*get_keymap)         (GdkDisplay    *display);
 
+  GdkGLContext *         (*init_gl)                    (GdkDisplay        *display,
+                                                        GError           **error);
   gboolean               (*make_gl_context_current)    (GdkDisplay        *display,
                                                         GdkGLContext      *context);
 
@@ -206,6 +208,7 @@ GdkSurface *        gdk_display_create_surface        (GdkDisplay       *display
                                                        int               width,
                                                        int               height);
 
+GdkGLContext *      gdk_display_get_gl_context        (GdkDisplay       *display);
 gboolean            gdk_display_make_gl_context_current  (GdkDisplay        *display,
                                                           GdkGLContext      *context);
 
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index 8f562f7d1c..274ad99345 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -1065,59 +1065,14 @@ gdk_surface_get_mapped (GdkSurface *surface)
   return GDK_SURFACE_IS_MAPPED (surface);
 }
 
-GdkGLContext *
-gdk_surface_get_shared_data_gl_context (GdkSurface *surface)
-{
-  static int in_shared_data_creation;
-  GdkDisplay *display;
-  GdkGLContext *context;
-
-  if (in_shared_data_creation)
-    return NULL;
-
-  in_shared_data_creation = 1;
-
-  display = gdk_surface_get_display (surface);
-  context = (GdkGLContext *)g_object_get_data (G_OBJECT (display), "gdk-gl-shared-data-context");
-  if (context == NULL)
-    {
-      GError *error = NULL;
-      context = GDK_SURFACE_GET_CLASS (surface)->create_gl_context (surface, FALSE, NULL, &error);
-      if (context == NULL)
-        {
-          g_warning ("Failed to create shared context: %s", error->message);
-          g_clear_error (&error);
-        }
-
-      gdk_gl_context_realize (context, &error);
-      if (context == NULL)
-        {
-          g_warning ("Failed to realize shared context: %s", error->message);
-          g_clear_error (&error);
-        }
-
-
-      g_object_set_data (G_OBJECT (display), "gdk-gl-shared-data-context", context);
-    }
-
-  in_shared_data_creation = 0;
-
-  return context;
-}
-
 GdkGLContext *
 gdk_surface_get_paint_gl_context (GdkSurface  *surface,
-                                  GError    **error)
+                                  GError     **error)
 {
   GError *internal_error = NULL;
 
-  if (GDK_DISPLAY_DEBUG_CHECK (surface->display, GL_DISABLE))
-    {
-      g_set_error_literal (error, GDK_GL_ERROR,
-                           GDK_GL_ERROR_NOT_AVAILABLE,
-                           _("GL support disabled via GDK_DEBUG"));
-      return NULL;
-    }
+  if (!gdk_display_prepare_gl (surface->display, error))
+    return NULL;
 
   if (surface->gl_paint_context == NULL)
     {
diff --git a/gdk/gdksurfaceprivate.h b/gdk/gdksurfaceprivate.h
index 90f5bcba2d..c29827c34e 100644
--- a/gdk/gdksurfaceprivate.h
+++ b/gdk/gdksurfaceprivate.h
@@ -266,7 +266,6 @@ void       _gdk_surface_update_size       (GdkSurface      *surface);
 
 GdkGLContext * gdk_surface_get_paint_gl_context (GdkSurface *surface,
                                                  GError   **error);
-GdkGLContext * gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
 
 gboolean gdk_surface_handle_event (GdkEvent       *event);
 GdkSeat * gdk_surface_get_seat_from_event (GdkSurface *surface,
diff --git a/gdk/macos/gdkmacosdisplay.c b/gdk/macos/gdkmacosdisplay.c
index 20041ac076..351ff574fd 100644
--- a/gdk/macos/gdkmacosdisplay.c
+++ b/gdk/macos/gdkmacosdisplay.c
@@ -637,6 +637,13 @@ gdk_macos_display_load_clipboard (GdkMacosDisplay *self)
   GDK_DISPLAY (self)->clipboard = _gdk_macos_clipboard_new (self);
 }
 
+static GdkGLContext *
+gdk_macos_display_init_gl (GdkDisplay  *display,
+                           GError     **error)
+{
+  return _gdk_macos_gl_context_new (display, NULL, FALSE, NULL, error);
+}
+
 static gboolean
 gdk_macos_display_make_gl_context_current (GdkDisplay   *display,
                                            GdkGLContext *gl_context)
@@ -695,6 +702,7 @@ gdk_macos_display_class_init (GdkMacosDisplayClass *klass)
   display_class->get_name = gdk_macos_display_get_name;
   display_class->get_setting = gdk_macos_display_get_setting;
   display_class->has_pending = gdk_macos_display_has_pending;
+  display_class->init_gl = gdk_macos_display_init_gl;
   display_class->make_gl_context_current = gdk_macos_display_make_gl_context_current;
   display_class->notify_startup_complete = gdk_macos_display_notify_startup_complete;
   display_class->queue_events = gdk_macos_display_queue_events;
diff --git a/gdk/macos/gdkmacosglcontext-private.h b/gdk/macos/gdkmacosglcontext-private.h
index 97d209b6f7..8d5eea931c 100644
--- a/gdk/macos/gdkmacosglcontext-private.h
+++ b/gdk/macos/gdkmacosglcontext-private.h
@@ -19,12 +19,14 @@
 #ifndef __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
 #define __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
 
+#include "gdkmacosglcontext.h"
+
 #include "gdkglcontextprivate.h"
 #include "gdkdisplayprivate.h"
 #include "gdksurface.h"
 #include "gdkinternals.h"
 
-#include "gdkmacosglcontext.h"
+#include "gdkmacosdisplay.h"
 #include "gdkmacossurface.h"
 
 #import <OpenGL/OpenGL.h>
@@ -55,7 +57,8 @@ struct _GdkMacosGLContextClass
   GdkGLContextClass parent_class;
 };
 
-GdkGLContext *_gdk_macos_gl_context_new          (GdkMacosSurface    *surface,
+GdkGLContext *_gdk_macos_gl_context_new          (GdkMacosDisplay    *display,
+                                                  GdkMacosSurface    *surface,
                                                   gboolean            attached,
                                                   GdkGLContext       *share,
                                                   GError            **error);
diff --git a/gdk/macos/gdkmacosglcontext.c b/gdk/macos/gdkmacosglcontext.c
index e4ef4abcb1..66f767c19d 100644
--- a/gdk/macos/gdkmacosglcontext.c
+++ b/gdk/macos/gdkmacosglcontext.c
@@ -170,12 +170,12 @@ gdk_macos_gl_context_real_realize (GdkGLContext  *context,
 {
   GdkMacosGLContext *self = (GdkMacosGLContext *)context;
   GdkSurface *surface;
+  GdkDisplay *display;
   NSOpenGLContext *shared_gl_context = nil;
   NSOpenGLContext *gl_context;
   NSOpenGLPixelFormat *pixelFormat;
   CGLContextObj cgl_context;
   GdkGLContext *shared;
-  GdkGLContext *shared_data;
   NSOpenGLContext *existing;
   GLint sync_to_framerate = 1;
   GLint validate = 0;
@@ -192,21 +192,16 @@ gdk_macos_gl_context_real_realize (GdkGLContext  *context,
   gdk_gl_context_get_required_version (context, &major, &minor);
 
   surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
-  shared = gdk_gl_context_get_shared_context (context);
-  shared_data = gdk_surface_get_shared_data_gl_context (surface);
+  display = gdk_gl_context_get_display (context);
+  shared = gdk_display_get_gl_context (display);
 
   if (shared != NULL)
     {
       if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared), error)))
         return FALSE;
     }
-  else if (shared_data != NULL)
-    {
-      if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared_data), error)))
-        return FALSE;
-    }
 
-  GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)),
+  GDK_DISPLAY_NOTE (display,
                     OPENGL,
                     g_message ("Creating NSOpenGLContext (version %d.%d)",
                                major, minor));
@@ -253,7 +248,7 @@ gdk_macos_gl_context_real_realize (GdkGLContext  *context,
 
   GLint renderer_id = 0;
   [gl_context getValues:&renderer_id forParameter:NSOpenGLContextParameterCurrentRendererID];
-  GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)),
+  GDK_DISPLAY_NOTE (display,
                     OPENGL,
                     g_message ("Created NSOpenGLContext[%p] using %s",
                                gl_context,
@@ -479,7 +474,8 @@ gdk_macos_gl_context_init (GdkMacosGLContext *self)
 }
 
 GdkGLContext *
-_gdk_macos_gl_context_new (GdkMacosSurface  *surface,
+_gdk_macos_gl_context_new (GdkMacosDisplay  *display,
+                           GdkMacosSurface  *surface,
                            gboolean          attached,
                            GdkGLContext     *share,
                            GError          **error)
@@ -490,6 +486,7 @@ _gdk_macos_gl_context_new (GdkMacosSurface  *surface,
   g_return_val_if_fail (!share || GDK_IS_MACOS_GL_CONTEXT (share), NULL);
 
   context = g_object_new (GDK_TYPE_MACOS_GL_CONTEXT,
+                          "display", display,
                           "surface", surface,
                           "shared-context", share,
                           NULL);
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index 9a1f73835b..aa8df2f35e 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -369,7 +369,8 @@ gdk_macos_surface_create_gl_context (GdkSurface    *surface,
   g_assert (GDK_IS_MACOS_SURFACE (self));
   g_assert (!share || GDK_IS_GL_CONTEXT (share));
 
-  return _gdk_macos_gl_context_new (self, attached, share, error);
+  return _gdk_macos_gl_context_new ((GdkMacosDisplay *) gdk_surface_get_display (surface),
+                                    self, attached, share, error);
 }
 
 static void
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index c27b165594..5d2d3826ae 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -969,6 +969,7 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
   display_class->create_surface = _gdk_wayland_display_create_surface;
   display_class->get_keymap = _gdk_wayland_display_get_keymap;
 
+  display_class->init_gl = gdk_wayland_display_init_gl;
   display_class->make_gl_context_current = gdk_wayland_display_make_gl_context_current;
 
   display_class->get_monitors = gdk_wayland_display_get_monitors;
diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c
index 3e8e8bf6f4..23e0105802 100644
--- a/gdk/wayland/gdkglcontext-wayland.c
+++ b/gdk/wayland/gdkglcontext-wayland.c
@@ -55,8 +55,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
 {
   GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
   GdkDisplay *display = gdk_gl_context_get_display (context);
-  GdkGLContext *share = gdk_gl_context_get_shared_context (context);
-  GdkGLContext *shared_data_context = gdk_surface_get_shared_data_gl_context (gdk_gl_context_get_surface 
(context));
+  GdkGLContext *share = gdk_display_get_gl_context (display);
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
   EGLContext ctx;
   EGLint context_attribs[N_EGL_ATTRS];
@@ -124,8 +123,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
   ctx = eglCreateContext (display_wayland->egl_display,
                           display_wayland->egl_config,
                           share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
-                             : shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT 
(shared_data_context)->egl_context
-                                                  : EGL_NO_CONTEXT,
+                                        : EGL_NO_CONTEXT,
                           context_attribs);
 
   /* If context creation failed without the ES bit, let's try again with it */
@@ -151,8 +149,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
       ctx = eglCreateContext (display_wayland->egl_display,
                               display_wayland->egl_config,
                               share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
-                                 : shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT 
(shared_data_context)->egl_context
-                                    : EGL_NO_CONTEXT,
+                                            : EGL_NO_CONTEXT,
                               context_attribs);
     }
 
@@ -181,8 +178,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
       ctx = eglCreateContext (display_wayland->egl_display,
                               display_wayland->egl_config,
                               share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
-                                 : shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT 
(shared_data_context)->egl_context
-                                    : EGL_NO_CONTEXT,
+                                            : EGL_NO_CONTEXT,
                               context_attribs);
     }
 
@@ -346,7 +342,7 @@ gdk_wayland_display_get_egl_display (GdkDisplay *display)
 
   g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), NULL);
 
-  if (!gdk_wayland_display_init_gl (display, NULL))
+  if (!gdk_display_prepare_gl (display, NULL))
     return NULL;
 
   display_wayland = GDK_WAYLAND_DISPLAY (display);
@@ -428,7 +424,7 @@ get_eglconfig (EGLDisplay dpy)
 
 #undef MAX_EGL_ATTRS
 
-gboolean
+GdkGLContext *
 gdk_wayland_display_init_gl (GdkDisplay  *display,
                              GError     **error)
 {
@@ -436,16 +432,13 @@ gdk_wayland_display_init_gl (GdkDisplay  *display,
   EGLint major, minor;
   EGLDisplay dpy;
 
-  if (display_wayland->egl_display)
-    return TRUE;
-
   dpy = get_egl_display (display_wayland);
   if (dpy == NULL)
     {
       g_set_error_literal (error, GDK_GL_ERROR,
                            GDK_GL_ERROR_NOT_AVAILABLE,
                            _("Failed to create EGL display"));
-      return FALSE;
+      return NULL;
     }
 
   if (!eglInitialize (dpy, &major, &minor))
@@ -453,7 +446,7 @@ gdk_wayland_display_init_gl (GdkDisplay  *display,
       g_set_error_literal (error, GDK_GL_ERROR,
                            GDK_GL_ERROR_NOT_AVAILABLE,
                            _("Could not initialize EGL display"));
-      return FALSE;
+      return NULL;
     }
 
   if (!eglBindAPI (EGL_OPENGL_API))
@@ -462,7 +455,7 @@ gdk_wayland_display_init_gl (GdkDisplay  *display,
       g_set_error_literal (error, GDK_GL_ERROR,
                            GDK_GL_ERROR_NOT_AVAILABLE,
                            _("No GL implementation is available"));
-      return FALSE;
+      return NULL;
     }
 
   if (!epoxy_has_egl_extension (dpy, "EGL_KHR_create_context"))
@@ -471,7 +464,7 @@ gdk_wayland_display_init_gl (GdkDisplay  *display,
       g_set_error_literal (error, GDK_GL_ERROR,
                            GDK_GL_ERROR_UNSUPPORTED_PROFILE,
                            _("Core GL is not available on EGL implementation"));
-      return FALSE;
+      return NULL;
     }
 
   display_wayland->egl_config = get_eglconfig (dpy);
@@ -481,7 +474,7 @@ gdk_wayland_display_init_gl (GdkDisplay  *display,
       g_set_error_literal (error, GDK_GL_ERROR,
                            GDK_GL_ERROR_UNSUPPORTED_FORMAT,
                            _("No available configurations for the given pixel format"));
-      return FALSE;
+      return NULL;
     }
 
   display_wayland->egl_display = dpy;
@@ -511,21 +504,19 @@ gdk_wayland_display_init_gl (GdkDisplay  *display,
                        eglQueryString (dpy, EGL_CLIENT_APIS),
                        eglQueryString (dpy, EGL_EXTENSIONS)));
 
-  return TRUE;
+  return g_object_new (GDK_TYPE_WAYLAND_GL_CONTEXT,
+                       "display", display,
+                       NULL);
 }
 
 GdkGLContext *
-gdk_wayland_surface_create_gl_context (GdkSurface     *surface,
+gdk_wayland_surface_create_gl_context (GdkSurface    *surface,
                                        gboolean       attached,
                                        GdkGLContext  *share,
                                        GError       **error)
 {
-  GdkDisplay *display = gdk_surface_get_display (surface);
   GdkWaylandGLContext *context;
 
-  if (!gdk_wayland_display_init_gl (display, error))
-    return NULL;
-
   context = g_object_new (GDK_TYPE_WAYLAND_GL_CONTEXT,
                           "surface", surface,
                           "shared-context", share,
diff --git a/gdk/wayland/gdkglcontext-wayland.h b/gdk/wayland/gdkglcontext-wayland.h
index 6e75a4bffd..d939a4ad39 100644
--- a/gdk/wayland/gdkglcontext-wayland.h
+++ b/gdk/wayland/gdkglcontext-wayland.h
@@ -44,9 +44,9 @@ struct _GdkWaylandGLContextClass
   GdkGLContextClass parent_class;
 };
 
-gboolean        gdk_wayland_display_init_gl                         (GdkDisplay        *display,
+GdkGLContext *  gdk_wayland_display_init_gl                         (GdkDisplay        *display,
                                                                      GError           **error);
-GdkGLContext *  gdk_wayland_surface_create_gl_context                (GdkSurface         *surface,
+GdkGLContext *  gdk_wayland_surface_create_gl_context               (GdkSurface        *surface,
                                                                     gboolean           attach,
                                                                      GdkGLContext      *share,
                                                                      GError           **error);
diff --git a/gdk/win32/gdkglcontext-win32.c b/gdk/win32/gdkglcontext-win32.c
index b3c0d8ad2b..66adbb858e 100644
--- a/gdk/win32/gdkglcontext-win32.c
+++ b/gdk/win32/gdkglcontext-win32.c
@@ -910,8 +910,6 @@ static gboolean
 gdk_win32_gl_context_realize (GdkGLContext *context,
                               GError **error)
 {
-  GdkGLContext *share = gdk_gl_context_get_shared_context (context);
-  GdkGLContext *shared_data_context;
   GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
 
   gboolean debug_bit, compat_bit, legacy_bit;
@@ -926,11 +924,11 @@ gdk_win32_gl_context_realize (GdkGLContext *context,
   GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
   GdkDisplay *display = gdk_surface_get_display (surface);
   GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
+  GdkGLContext *share = gdk_display_get_gl_context (display);
 
   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);
-  shared_data_context = gdk_surface_get_shared_data_gl_context (surface);
 
   /*
    * A legacy context cannot be shared with core profile ones, so this means we
@@ -980,7 +978,7 @@ gdk_win32_gl_context_realize (GdkGLContext *context,
                           legacy_bit ? "yes" : "no"));
 
       hglrc = _create_gl_context (context_win32->gl_hdc,
-                                  share ? share : shared_data_context,
+                                  share,
                                   flags,
                                   major,
                                   minor,
@@ -1022,7 +1020,7 @@ gdk_win32_gl_context_realize (GdkGLContext *context,
 
       ctx = _create_egl_context (win32_display->egl_disp,
                                  context_win32->egl_config,
-                                 share ? share : shared_data_context,
+                                 share,
                                  flags,
                                  major,
                                  minor,
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 9441ed1417..0b838c25dd 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1339,40 +1339,6 @@ set_sm_client_id (GdkDisplay  *display,
                      gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
 }
 
-static void
-gdk_x11_display_query_default_visual (GdkX11Display  *self,
-                                      Visual        **out_visual,
-                                      int            *out_depth)
-{
-  XVisualInfo template, *visinfo;
-  int n_visuals;
-  Display *dpy;
-
-  dpy = gdk_x11_display_get_xdisplay (GDK_DISPLAY (self));
-
-  template.screen = self->screen->screen_num;
-  template.depth = 32;
-  template.red_mask  = 0xff0000;
-  template.green_mask = 0x00ff00;
-  template.blue_mask = 0x0000ff;
-
-  visinfo = XGetVisualInfo (dpy,
-                            VisualScreenMask | VisualDepthMask
-                            | VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask,
-                            &template,
-                            &n_visuals);
-  if (visinfo != NULL)
-    {
-      *out_visual = visinfo[0].visual;
-      *out_depth = visinfo[0].depth;
-      XFree (visinfo);
-      return;
-    }
-
-  *out_visual = DefaultVisual (dpy, self->screen->screen_num);
-  *out_depth = DefaultDepth (dpy, self->screen->screen_num);
-}
-
 /**
  * gdk_x11_display_open:
  * @display_name: (nullable): name of the X display.
@@ -1443,36 +1409,11 @@ gdk_x11_display_open (const char *display_name)
   /* If GL is available we want to pick better default/rgba visuals,
    * as we care about GLX details such as alpha/depth/stencil depth,
    * stereo and double buffering
+   *
+   * Note that this also sets up the leader surface while creating the inital
+   * GL context.
    */
-  if (!gdk_x11_display_init_gl (display_x11, &display_x11->window_visual, &display_x11->window_depth, 
&display_x11->gl_error))
-    gdk_x11_display_query_default_visual (display_x11, &display_x11->window_visual, 
&display_x11->window_depth);
-
-  display_x11->window_colormap = XCreateColormap (xdisplay,
-                                                  DefaultRootWindow (xdisplay),
-                                                  display_x11->window_visual,
-                                                  AllocNone);
-  gdk_display_set_rgba (display, display_x11->window_depth == 32);
-
-  /* We need to initialize events after we have the screen
-   * structures in places
-   */
-  _gdk_x11_xsettings_init (GDK_X11_SCREEN (display_x11->screen));
-
-  display_x11->device_manager = _gdk_x11_device_manager_new (display);
-
-  gdk_event_init (display);
-
-  display_x11->leader_gdk_surface =
-      _gdk_x11_display_create_surface (display,
-                                       GDK_SURFACE_TEMP,
-                                       NULL,
-                                       -100, -100, 1, 1);
-
-  (_gdk_x11_surface_get_toplevel (display_x11->leader_gdk_surface))->is_leader = TRUE;
-
-  display_x11->leader_window = GDK_SURFACE_XID (display_x11->leader_gdk_surface);
-
-  display_x11->leader_window_title_set = FALSE;
+  gdk_display_prepare_gl (display, NULL);
 
 #ifdef HAVE_XFIXES
   if (XFixesQueryExtension (display_x11->xdisplay, 
@@ -2896,6 +2837,83 @@ gdk_boolean_handled_accumulator (GSignalInvocationHint *ihint,
   return continue_emission;
 }
 
+static void
+gdk_x11_display_query_default_visual (GdkX11Display  *self,
+                                      Visual        **out_visual,
+                                      int            *out_depth)
+{
+  XVisualInfo template, *visinfo;
+  int n_visuals;
+  Display *dpy;
+
+  dpy = gdk_x11_display_get_xdisplay (GDK_DISPLAY (self));
+
+  template.screen = self->screen->screen_num;
+  template.depth = 32;
+  template.red_mask  = 0xff0000;
+  template.green_mask = 0x00ff00;
+  template.blue_mask = 0x0000ff;
+
+  visinfo = XGetVisualInfo (dpy,
+                            VisualScreenMask | VisualDepthMask
+                            | VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask,
+                            &template,
+                            &n_visuals);
+  if (visinfo != NULL)
+    {
+      *out_visual = visinfo[0].visual;
+      *out_depth = visinfo[0].depth;
+      XFree (visinfo);
+      return;
+    }
+
+  *out_visual = DefaultVisual (dpy, self->screen->screen_num);
+  *out_depth = DefaultDepth (dpy, self->screen->screen_num);
+}
+
+static GdkGLContext *
+gdk_x11_display_init_gl (GdkDisplay  *display,
+                         GError     **error)
+{
+  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+  Display *xdisplay = gdk_x11_display_get_xdisplay (display);
+  gboolean have_gl;
+
+  have_gl = gdk_x11_display_init_gl_backend (display_x11, &display_x11->window_visual, 
&display_x11->window_depth, error);
+  if (!have_gl)
+    gdk_x11_display_query_default_visual (display_x11, &display_x11->window_visual, 
&display_x11->window_depth);
+
+  display_x11->window_colormap = XCreateColormap (xdisplay,
+                                                  DefaultRootWindow (xdisplay),
+                                                  display_x11->window_visual,
+                                                  AllocNone);
+  gdk_display_set_rgba (display, display_x11->window_depth == 32);
+
+  /* We need to initialize events after we have the screen
+   * structures in places
+   */
+  _gdk_x11_xsettings_init (GDK_X11_SCREEN (display_x11->screen));
+
+  display_x11->device_manager = _gdk_x11_device_manager_new (display);
+
+  gdk_event_init (display);
+
+  display_x11->leader_gdk_surface =
+      _gdk_x11_display_create_surface (display,
+                                       GDK_SURFACE_TEMP,
+                                       NULL,
+                                       -100, -100, 1, 1);
+
+  (_gdk_x11_surface_get_toplevel (display_x11->leader_gdk_surface))->is_leader = TRUE;
+  display_x11->leader_window = GDK_SURFACE_XID (display_x11->leader_gdk_surface);
+  display_x11->leader_window_title_set = FALSE;
+
+  if (!have_gl)
+    return NULL;
+
+  return gdk_x11_surface_create_gl_context (display_x11->leader_gdk_surface, FALSE, NULL, error);
+}
+
 static void
 gdk_x11_display_class_init (GdkX11DisplayClass * class)
 {
@@ -2926,6 +2944,7 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
   display_class->create_surface = _gdk_x11_display_create_surface;
   display_class->get_keymap = gdk_x11_display_get_keymap;
 
+  display_class->init_gl = gdk_x11_display_init_gl;
   display_class->make_gl_context_current = gdk_x11_display_make_gl_context_current;
 
   display_class->get_default_seat = gdk_x11_display_get_default_seat;
diff --git a/gdk/x11/gdkglcontext-egl.c b/gdk/x11/gdkglcontext-egl.c
index 56a17168b1..271e77c2f2 100644
--- a/gdk/x11/gdkglcontext-egl.c
+++ b/gdk/x11/gdkglcontext-egl.c
@@ -423,19 +423,16 @@ gdk_x11_gl_context_egl_realize (GdkGLContext  *context,
   GdkX11Display *display_x11;
   GdkDisplay *display;
   GdkX11GLContextEGL *context_egl;
-  GdkGLContext *share, *shared_data_context;
-  GdkSurface *surface;
+  GdkGLContext *share;
   gboolean debug_bit, forward_bit, legacy_bit, use_es;
   int major, minor, i = 0;
   EGLint context_attrs[N_EGL_ATTRS];
 
-  surface = gdk_gl_context_get_surface (context);
-  display = gdk_surface_get_display (surface);
+  display = gdk_gl_context_get_display (context);
 
   context_egl = GDK_X11_GL_CONTEXT_EGL (context);
   display_x11 = GDK_X11_DISPLAY (display);
-  share = gdk_gl_context_get_shared_context (context);
-  shared_data_context = gdk_surface_get_shared_data_gl_context (surface);
+  share = gdk_display_get_gl_context (display);
 
   gdk_gl_context_get_required_version (context, &major, &minor);
   debug_bit = gdk_gl_context_get_debug_enabled (context);
@@ -503,9 +500,7 @@ gdk_x11_gl_context_egl_realize (GdkGLContext  *context,
                       display_x11->egl_config,
                       share != NULL
                         ? GDK_X11_GL_CONTEXT_EGL (share)->egl_context
-                        : shared_data_context != NULL
-                            ? GDK_X11_GL_CONTEXT_EGL (shared_data_context)->egl_context
-                            : EGL_NO_CONTEXT,
+                        : EGL_NO_CONTEXT,
                       context_attrs);
 
   /* If we're not asking for a GLES context, and we don't have the legacy bit set
@@ -528,9 +523,7 @@ gdk_x11_gl_context_egl_realize (GdkGLContext  *context,
                           display_x11->egl_config,
                           share != NULL
                             ? GDK_X11_GL_CONTEXT_EGL (share)->egl_context
-                            : shared_data_context != NULL
-                                ? GDK_X11_GL_CONTEXT_EGL (shared_data_context)->egl_context
-                                : EGL_NO_CONTEXT,
+                            : EGL_NO_CONTEXT,
                           context_attrs);
     }
 
diff --git a/gdk/x11/gdkglcontext-glx.c b/gdk/x11/gdkglcontext-glx.c
index c6bd867361..cc68137aab 100644
--- a/gdk/x11/gdkglcontext-glx.c
+++ b/gdk/x11/gdkglcontext-glx.c
@@ -503,20 +503,18 @@ gdk_x11_gl_context_glx_realize (GdkGLContext  *context,
   GdkDisplay *display;
   GdkX11GLContextGLX *context_glx;
   Display *dpy;
+  GdkSurface *surface;
   DrawableInfo *info;
   GdkGLContext *share;
-  GdkGLContext *shared_data_context;
-  GdkSurface *surface;
   gboolean debug_bit, compat_bit, legacy_bit, es_bit;
   int major, minor, flags;
 
-  surface = gdk_gl_context_get_surface (context);
-  display = gdk_surface_get_display (surface);
+  display = gdk_gl_context_get_display (context);
   dpy = gdk_x11_display_get_xdisplay (display);
   context_glx = GDK_X11_GL_CONTEXT_GLX (context);
   display_x11 = GDK_X11_DISPLAY (display);
-  share = gdk_gl_context_get_shared_context (context);
-  shared_data_context = gdk_surface_get_shared_data_gl_context (surface);
+  share = gdk_display_get_gl_context (display);
+  surface = gdk_gl_context_get_surface (context);
 
   gdk_gl_context_get_required_version (context, &major, &minor);
   debug_bit = gdk_gl_context_get_debug_enabled (context);
@@ -556,7 +554,7 @@ gdk_x11_gl_context_glx_realize (GdkGLContext  *context,
   if (legacy_bit && !GDK_X11_DISPLAY (display)->has_glx_create_context)
     {
       GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Creating legacy GL context on request"));
-      context_glx->glx_context = create_legacy_context (display, display_x11->glx_config, share ? share : 
shared_data_context);
+      context_glx->glx_context = create_legacy_context (display, display_x11->glx_config, share);
     }
   else
     {
@@ -581,14 +579,14 @@ gdk_x11_gl_context_glx_realize (GdkGLContext  *context,
       GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Creating GL3 context"));
       context_glx->glx_context = create_gl3_context (display,
                                                      display_x11->glx_config,
-                                                     share ? share : shared_data_context,
+                                                     share,
                                                      profile, flags, major, minor);
 
       /* Fall back to legacy in case the GL3 context creation failed */
       if (context_glx->glx_context == NULL)
         {
           GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Creating fallback legacy context"));
-          context_glx->glx_context = create_legacy_context (display, display_x11->glx_config, share ? share 
: shared_data_context);
+          context_glx->glx_context = create_legacy_context (display, display_x11->glx_config, share);
           legacy_bit = TRUE;
           es_bit = FALSE;
         }
diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c
index c74a994c70..3585367596 100644
--- a/gdk/x11/gdkglcontext-x11.c
+++ b/gdk/x11/gdkglcontext-x11.c
@@ -103,10 +103,10 @@ gdk_x11_display_make_gl_context_current (GdkDisplay   *display,
 }
 
 gboolean
-gdk_x11_display_init_gl (GdkX11Display  *self,
-                         Visual        **out_visual,
-                         int            *out_depth,
-                         GError        **error)
+gdk_x11_display_init_gl_backend (GdkX11Display  *self,
+                                 Visual        **out_visual,
+                                 int            *out_depth,
+                                 GError        **error)
 {
   GdkDisplay *display G_GNUC_UNUSED = GDK_DISPLAY (self);
 
diff --git a/gdk/x11/gdkglcontext-x11.h b/gdk/x11/gdkglcontext-x11.h
index 5cc2ebf5d6..e62a4795d7 100644
--- a/gdk/x11/gdkglcontext-x11.h
+++ b/gdk/x11/gdkglcontext-x11.h
@@ -59,7 +59,7 @@ struct _GdkX11GLContextClass
   void (* bind_for_frame_fence) (GdkX11GLContext *self);
 };
 
-gboolean                gdk_x11_display_init_gl                 (GdkX11Display *self,
+gboolean                gdk_x11_display_init_gl_backend         (GdkX11Display *self,
                                                                  Visual       **out_visual,
                                                                  int           *out_depth,
                                                                  GError       **error);
diff --git a/gsk/ngl/gsknglrenderer.c b/gsk/ngl/gsknglrenderer.c
index e343479abd..c84f112047 100644
--- a/gsk/ngl/gsknglrenderer.c
+++ b/gsk/ngl/gsknglrenderer.c
@@ -21,7 +21,7 @@
 #include "config.h"
 
 #include <gdk/gdkprofilerprivate.h>
-#include <gdk/gdksurfaceprivate.h>
+#include <gdk/gdkdisplayprivate.h>
 #include <gsk/gskdebugprivate.h>
 #include <gsk/gskrendererprivate.h>
 
@@ -105,7 +105,7 @@ gsk_ngl_renderer_realize (GskRenderer  *renderer,
       !gdk_gl_context_realize (context, error))
     goto failure;
 
-  if (!(shared_context = gdk_surface_get_shared_data_gl_context (surface)))
+  if (!(shared_context = gdk_display_get_gl_context (gdk_surface_get_display (surface))))
     {
       g_set_error (error,
                    GDK_GL_ERROR,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]