[gtk/wip/otte/gl-hdr: 14/14] egl: Move EGLSurface handling to GdkSurface




commit 22df05503d54f35ef880155946a9b5803e2708d2
Author: Benjamin Otte <otte redhat com>
Date:   Sun Oct 3 21:58:57 2021 +0200

    egl: Move EGLSurface handling to GdkSurface
    
    Calling gdk_surface_set_egl_native_window() enables this.

 gdk/gdkdisplay.c                   |  1 +
 gdk/gdksurface.c                   | 52 +++++++++++++++++++++-
 gdk/gdksurfaceprivate.h            |  4 ++
 gdk/wayland/gdkglcontext-wayland.c |  8 ++--
 gdk/wayland/gdksurface-wayland.c   | 39 ++---------------
 gdk/wayland/gdksurface-wayland.h   |  5 +--
 gdk/x11/gdkdisplay-x11.c           |  2 -
 gdk/x11/gdkdisplay-x11.h           |  1 -
 gdk/x11/gdkglcontext-egl.c         | 89 +++++++++++---------------------------
 gdk/x11/gdkglcontext-x11.c         |  1 -
 gdk/x11/gdkglcontext-x11.h         |  2 -
 gdk/x11/gdksurface-x11.c           |  4 +-
 gdk/x11/gdksurface-x11.h           |  1 -
 13 files changed, 94 insertions(+), 115 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index 61b8d2c821..98cfc2e0c0 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -1666,6 +1666,7 @@ gdk_display_init_egl (GdkDisplay  *self,
 
   if (!gdk_display_check_egl_extensions (priv->egl_display,
                                          (const char *[]) {
+                                           "EGL_KHR_create_context",
                                            "EGL_KHR_surfaceless_context",
                                            NULL
                                          },
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index 82cb6ecf2f..c55f69dad3 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -46,6 +46,8 @@
 
 #include <math.h>
 
+#include <epoxy/egl.h>
+
 /**
  * GdkSurface:
  *
@@ -64,6 +66,9 @@ typedef struct _GdkSurfacePrivate GdkSurfacePrivate;
 
 struct _GdkSurfacePrivate
 {
+  gpointer egl_native_window;
+  EGLSurface egl_surface;
+
   gpointer widget;
 };
 
@@ -920,8 +925,10 @@ surface_remove_from_pointer_info (GdkSurface  *surface,
  */
 static void
 _gdk_surface_destroy_hierarchy (GdkSurface *surface,
-                                gboolean   foreign_destroy)
+                                gboolean    foreign_destroy)
 {
+  G_GNUC_UNUSED GdkSurfacePrivate *priv = gdk_surface_get_instance_private (surface);
+
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
   if (GDK_SURFACE_DESTROYED (surface))
@@ -929,6 +936,9 @@ _gdk_surface_destroy_hierarchy (GdkSurface *surface,
 
   GDK_SURFACE_GET_CLASS (surface)->destroy (surface, foreign_destroy);
 
+  /* backend must have unset this */
+  g_assert (priv->egl_native_window == NULL);
+
   if (surface->gl_paint_context)
     {
       /* Make sure to destroy if current */
@@ -1063,6 +1073,46 @@ gdk_surface_get_mapped (GdkSurface *surface)
   return GDK_SURFACE_IS_MAPPED (surface);
 }
 
+void
+gdk_surface_set_egl_native_window (GdkSurface *self,
+                                   gpointer    native_window)
+{
+  GdkSurfacePrivate *priv = gdk_surface_get_instance_private (self);
+
+  /* This checks that all EGL platforms we support conform to the same struct sizes.
+   * When this ever fails, there will be some fun times happening for whoever tries
+   * this weird EGL backend... */
+  G_STATIC_ASSERT (sizeof (gpointer) == sizeof (EGLNativeWindowType));
+
+  if (priv->egl_surface != NULL)
+    {
+      eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
+      priv->egl_surface = NULL;
+    }
+
+  priv->egl_native_window = native_window;
+}
+
+gpointer /* EGLSurface */
+gdk_surface_get_egl_surface (GdkSurface *self)
+{
+  GdkSurfacePrivate *priv = gdk_surface_get_instance_private (self);
+
+  g_return_val_if_fail (priv->egl_native_window != NULL, NULL);
+
+  if (priv->egl_surface == NULL)
+    {
+      GdkDisplay *display = gdk_surface_get_display (self);
+
+      priv->egl_surface = eglCreateWindowSurface (gdk_display_get_egl_display (display),
+                                                  gdk_display_get_egl_config (display),
+                                                  (EGLNativeWindowType) priv->egl_native_window,
+                                                  NULL);
+    }
+
+  return priv->egl_surface;
+}
+
 GdkGLContext *
 gdk_surface_get_paint_gl_context (GdkSurface  *surface,
                                   GError     **error)
diff --git a/gdk/gdksurfaceprivate.h b/gdk/gdksurfaceprivate.h
index 16a6bf8bea..ec9f177e5e 100644
--- a/gdk/gdksurfaceprivate.h
+++ b/gdk/gdksurfaceprivate.h
@@ -292,6 +292,10 @@ void gdk_surface_get_geometry (GdkSurface *surface,
                                int        *width,
                                int        *height);
 
+void                    gdk_surface_set_egl_native_window       (GdkSurface             *self,
+                                                                 gpointer                native_window);
+gpointer /*EGLSurface*/ gdk_surface_get_egl_surface             (GdkSurface             *self);
+
 void                    gdk_surface_set_widget                  (GdkSurface             *self,
                                                                  gpointer                widget);
 gpointer                gdk_surface_get_widget                  (GdkSurface             *self);
diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c
index 2f239ee929..3eafebe1b4 100644
--- a/gdk/wayland/gdkglcontext-wayland.c
+++ b/gdk/wayland/gdkglcontext-wayland.c
@@ -215,7 +215,7 @@ gdk_wayland_gl_context_get_damage (GdkGLContext *context)
 
   if (display_wayland->have_egl_buffer_age)
     {
-      egl_surface = gdk_wayland_surface_get_egl_surface (surface);
+      egl_surface = gdk_surface_get_egl_surface (surface);
       gdk_gl_context_make_current (context);
       eglQuerySurface (gdk_display_get_egl_display (display), egl_surface,
                        EGL_BUFFER_AGE_EXT, &buffer_age);
@@ -269,7 +269,7 @@ gdk_wayland_gl_context_make_current (GdkGLContext *context,
   EGLSurface egl_surface;
 
   if (!surfaceless)
-    egl_surface = gdk_wayland_surface_get_egl_surface (gdk_gl_context_get_surface (context));
+    egl_surface = gdk_surface_get_egl_surface (gdk_gl_context_get_surface (context));
   else
     egl_surface = EGL_NO_SURFACE;
 
@@ -284,6 +284,8 @@ gdk_wayland_gl_context_begin_frame (GdkDrawContext *draw_context,
                                     gboolean        request_hdr,
                                     cairo_region_t *region)
 {
+  gdk_wayland_surface_ensure_wl_egl_window (gdk_draw_context_get_surface (draw_context));
+
   GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->begin_frame (draw_context, request_hdr, 
region);
 
   glDrawBuffers (1, (GLenum[1]) { GL_BACK });
@@ -303,7 +305,7 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
 
   gdk_gl_context_make_current (context);
 
-  egl_surface = gdk_wayland_surface_get_egl_surface (surface);
+  egl_surface = gdk_surface_get_egl_surface (surface);
   gdk_wayland_surface_sync (surface);
   gdk_wayland_surface_request_frame (surface);
 
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index c1f1357165..0a02cede91 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -110,8 +110,6 @@ struct _GdkWaylandSurface
 
   struct wl_event_queue *event_queue;
 
-  EGLSurface egl_surface;
-
   uint32_t reposition_token;
   uint32_t received_reposition_token;
 
@@ -2901,14 +2899,9 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
 
   if (impl->display_server.wl_surface)
     {
-      if (impl->egl_surface)
-        {
-          eglDestroySurface (gdk_display_get_egl_display (display), impl->egl_surface);
-          impl->egl_surface = NULL;
-        }
-
       if (impl->display_server.egl_window)
         {
+          gdk_surface_set_egl_native_window (surface, NULL);
           wl_egl_window_destroy (impl->display_server.egl_window);
           impl->display_server.egl_window = NULL;
         }
@@ -4332,8 +4325,8 @@ gdk_wayland_surface_get_wl_output (GdkSurface *surface)
   return NULL;
 }
 
-static struct wl_egl_window *
-gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface)
+void
+gdk_wayland_surface_ensure_wl_egl_window (GdkSurface *surface)
 {
   GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
@@ -4344,33 +4337,9 @@ gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface)
                               surface->width * impl->scale,
                               surface->height * impl->scale);
       wl_surface_set_buffer_scale (impl->display_server.wl_surface, impl->scale);
-    }
-
-  return impl->display_server.egl_window;
-}
 
-EGLSurface
-gdk_wayland_surface_get_egl_surface (GdkSurface *surface)
-{
-  GdkDisplay *display = gdk_surface_get_display (surface);
-  GdkWaylandSurface *impl;
-  struct wl_egl_window *egl_window;
-
-  g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
-
-  impl = GDK_WAYLAND_SURFACE (surface);
-
-  if (impl->egl_surface == NULL)
-    {
-      egl_window = gdk_wayland_surface_get_wl_egl_window (surface);
-
-      impl->egl_surface = eglCreateWindowSurface (gdk_display_get_egl_display (display),
-                                                  gdk_display_get_egl_config (display),
-                                                  egl_window,
-                                                  NULL);
+      gdk_surface_set_egl_native_window (surface, impl->display_server.egl_window);
     }
-
-  return impl->egl_surface;
 }
 
 struct gtk_surface1 *
diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h
index cd2b1f3e9a..d6d90d6908 100644
--- a/gdk/wayland/gdksurface-wayland.h
+++ b/gdk/wayland/gdksurface-wayland.h
@@ -22,9 +22,6 @@
 
 #include "gdkwaylandsurface.h"
 
-#include <wayland-egl.h>
-#include <epoxy/egl.h>
-
 G_BEGIN_DECLS
 
 void                     gdk_wayland_toplevel_set_dbus_properties       (GdkToplevel *toplevel,
@@ -41,6 +38,6 @@ void                     gdk_wayland_toplevel_announce_ssd              (GdkTopl
 gboolean                 gdk_wayland_toplevel_inhibit_idle              (GdkToplevel *toplevel);
 void                     gdk_wayland_toplevel_uninhibit_idle            (GdkToplevel *toplevel);
 
-EGLSurface               gdk_wayland_surface_get_egl_surface            (GdkSurface  *surface);
+void                     gdk_wayland_surface_ensure_wl_egl_window       (GdkSurface  *surface);
 
 G_END_DECLS
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 269fd9cd2f..499bbd86f3 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -2995,8 +2995,6 @@ gdk_x11_display_init_gl_backend (GdkX11Display  *self,
 
   self->egl_version = epoxy_egl_version (egl_display);
 
-  self->has_egl_khr_create_context =
-    epoxy_has_egl_extension (egl_display, "EGL_KHR_create_context");
   self->has_egl_buffer_age =
     epoxy_has_egl_extension (egl_display, "EGL_EXT_buffer_age");
   self->has_egl_swap_buffers_with_damage =
diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h
index 5be6c8e5e0..6ebca4bd29 100644
--- a/gdk/x11/gdkdisplay-x11.h
+++ b/gdk/x11/gdkdisplay-x11.h
@@ -157,7 +157,6 @@ struct _GdkX11Display
   guint has_async_glx_swap_buffers : 1;
 
   /* EGL extensions we check */
-  guint has_egl_khr_create_context : 1;
   guint has_egl_buffer_age : 1;
   guint has_egl_swap_buffers_with_damage : 1;
 };
diff --git a/gdk/x11/gdkglcontext-egl.c b/gdk/x11/gdkglcontext-egl.c
index 7113cc3424..fcc571ccf8 100644
--- a/gdk/x11/gdkglcontext-egl.c
+++ b/gdk/x11/gdkglcontext-egl.c
@@ -18,7 +18,6 @@
 #include "gdkx11display.h"
 #include "gdkx11glcontext.h"
 #include "gdkx11screen.h"
-#include "gdkx11surface.h"
 #include "gdkx11property.h"
 #include <X11/Xatom.h>
 
@@ -62,38 +61,6 @@ gdk_x11_display_get_egl_display (GdkDisplay *display)
   return gdk_display_get_egl_display (display);
 }
 
-static EGLSurface
-gdk_x11_surface_get_egl_surface (GdkSurface *surface)
-{
-  GdkX11Surface *self = GDK_X11_SURFACE (surface);
-  GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (self));
-
-  if (self->egl_surface)
-    return self->egl_surface;
-
-  self->egl_surface =
-    eglCreateWindowSurface (gdk_display_get_egl_display (display), 
-                            gdk_display_get_egl_config (display),
-                            (EGLNativeWindowType) gdk_x11_surface_get_xid (surface),
-                            NULL);
-
-  return self->egl_surface;
-}
-
-void
-gdk_x11_surface_destroy_egl_surface (GdkX11Surface *self)
-{
-  GdkDisplay *display;
-
-  if (self->egl_surface == NULL)
-    return;
-
-  display = gdk_surface_get_display (GDK_SURFACE (self));
-
-  eglDestroySurface (gdk_display_get_egl_display (display), self->egl_surface);
-  self->egl_surface = NULL;
-}
-
 static void
 gdk_x11_gl_context_egl_begin_frame (GdkDrawContext *draw_context,
                                     gboolean        request_hdr,
@@ -118,7 +85,7 @@ gdk_x11_gl_context_egl_end_frame (GdkDrawContext *draw_context,
 
   gdk_gl_context_make_current (context);
 
-  egl_surface = gdk_x11_surface_get_egl_surface (surface);
+  egl_surface = gdk_surface_get_egl_surface (surface);
 
   gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "x11", "swap buffers");
   if (display_x11->has_egl_swap_buffers_with_damage)
@@ -185,7 +152,7 @@ gdk_x11_gl_context_egl_make_current (GdkGLContext *context,
     }
 
   surface = gdk_gl_context_get_surface (context);
-  egl_surface = gdk_x11_surface_get_egl_surface (surface);
+  egl_surface = gdk_surface_get_egl_surface (surface);
 
   GDK_DISPLAY_NOTE (display, OPENGL,
                     g_message ("Making EGL context %p current to surface %p",
@@ -228,7 +195,7 @@ gdk_x11_gl_context_egl_get_damage (GdkGLContext *context)
       EGLSurface egl_surface;
       int buffer_age = 0;
 
-      egl_surface = gdk_x11_surface_get_egl_surface (surface);
+      egl_surface = gdk_surface_get_egl_surface (surface);
       gdk_gl_context_make_current (context);
 
       eglQuerySurface (gdk_display_get_egl_display (display),
@@ -269,20 +236,18 @@ static gboolean
 gdk_x11_gl_context_egl_realize (GdkGLContext  *context,
                                 GError       **error)
 {
-  GdkX11Display *display_x11;
   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, i = 0;
+  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);
-  display_x11 = GDK_X11_DISPLAY (display);
   share = gdk_display_get_gl_context (display);
   egl_display = gdk_display_get_egl_display (display),
   egl_config = gdk_display_get_egl_config (display),
@@ -295,35 +260,28 @@ gdk_x11_gl_context_egl_realize (GdkGLContext  *context,
   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);
 
-      if (display_x11->has_egl_khr_create_context)
-        {
-          int flags = 0;
-
-          if (debug_bit)
-            flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
-          if (forward_bit)
-            flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
-
-          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;
-          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;
-          context_attrs[i++] = flags;
-          context_attrs[i++] = EGL_NONE;
-        }
-      else
-        {
-          context_attrs[i++] = EGL_NONE;
-        }
+      /* 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
     {
@@ -336,6 +294,9 @@ gdk_x11_gl_context_egl_realize (GdkGLContext  *context,
         context_attrs[i++] = 2;
     }
 
+  context_attrs[i++] = flags;
+  context_attrs[i++] = EGL_NONE;
+
   context_attrs[i++] = EGL_NONE;
   g_assert (i < N_EGL_ATTRS);
 
diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c
index 8c78e3c07e..567ae89002 100644
--- a/gdk/x11/gdkglcontext-x11.c
+++ b/gdk/x11/gdkglcontext-x11.c
@@ -28,7 +28,6 @@
 #include "gdkx11display.h"
 #include "gdkx11glcontext.h"
 #include "gdkx11screen.h"
-#include "gdkx11surface.h"
 #include "gdkx11property.h"
 #include <X11/Xatom.h>
 
diff --git a/gdk/x11/gdkglcontext-x11.h b/gdk/x11/gdkglcontext-x11.h
index cf268d9f15..10b94ca54b 100644
--- a/gdk/x11/gdkglcontext-x11.h
+++ b/gdk/x11/gdkglcontext-x11.h
@@ -76,8 +76,6 @@ GType                   gdk_x11_gl_context_glx_get_type         (void) G_GNUC_CO
 
 typedef struct _GdkX11GLContextEGL      GdkX11GLContextEGL;
 
-void                    gdk_x11_surface_destroy_egl_surface     (GdkX11Surface *self);
-
 GType                   gdk_x11_gl_context_egl_get_type         (void) G_GNUC_CONST;
 
 G_END_DECLS
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c
index 06bc9cf00e..16e1a3678d 100644
--- a/gdk/x11/gdksurface-x11.c
+++ b/gdk/x11/gdksurface-x11.c
@@ -1275,6 +1275,8 @@ _gdk_x11_display_create_surface (GdkDisplay     *display,
   g_object_ref (surface);
   _gdk_x11_display_add_window (x11_screen->display, &impl->xid, surface);
 
+  gdk_surface_set_egl_native_window (surface, (void *) impl->xid);
+
   gdk_x11_surface_set_title (surface, get_default_title ());
   if (surface_type == GDK_SURFACE_TOPLEVEL)
     gdk_x11_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_NORMAL);
@@ -1364,7 +1366,7 @@ gdk_x11_surface_destroy (GdkSurface *surface,
 
   if (!foreign_destroy)
     {
-      gdk_x11_surface_destroy_egl_surface (impl);
+      gdk_surface_set_egl_native_window (surface, NULL);
       gdk_x11_surface_destroy_glx_drawable (impl);
 
       XDestroyWindow (GDK_SURFACE_XDISPLAY (surface), GDK_SURFACE_XID (surface));
diff --git a/gdk/x11/gdksurface-x11.h b/gdk/x11/gdksurface-x11.h
index 8a50b5b5d4..f338ccfc21 100644
--- a/gdk/x11/gdksurface-x11.h
+++ b/gdk/x11/gdksurface-x11.h
@@ -86,7 +86,6 @@ struct _GdkX11Surface
   guint compute_size_source_id;
 
   cairo_surface_t *cairo_surface;
-  /* EGLSurface */ gpointer egl_surface;
   /* GLXDrawable */ XID glx_drawable;
   guint32 glx_frame_counter;
 


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