[gtk/wip/otte/for-main] gl: Clear current when destroying current's surface




commit c41979931382bc35a839eb7f59e8a6940dc47144
Author: Benjamin Otte <otte redhat com>
Date:   Wed Dec 22 19:49:13 2021 +0100

    gl: Clear current when destroying current's surface
    
    When destroying the EGLSurface or GLXDrawable of a GdkSurface, make sure
    the current context is not still bound to it.
    
    If it is, clear the current context.
    
    Fixes #4554

 gdk/gdkglcontext.c         | 31 +++++++++++++++++++++++++++++++
 gdk/gdkglcontextprivate.h  |  2 ++
 gdk/gdksurface.c           |  2 ++
 gdk/x11/gdkglcontext-glx.c |  2 ++
 4 files changed, 37 insertions(+)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 23c5eba8bf..9ab690f6fa 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -151,6 +151,12 @@ unmask_context (MaskedContext *mask)
   return GDK_GL_CONTEXT (GSIZE_TO_POINTER (GPOINTER_TO_SIZE (mask) & ~(gsize) 1));
 }
 
+static inline gboolean
+mask_is_surfaceless (MaskedContext *mask)
+{
+  return GPOINTER_TO_SIZE (mask) & (gsize) 1;
+}
+
 static void
 unref_unmasked (gpointer data)
 {
@@ -1655,6 +1661,31 @@ gdk_gl_context_clear_current (void)
     }
 }
 
+/*<private>
+ * gdk_gl_context_clear_current_if_surface:
+ * @surface: surface to clear for
+ *
+ * Does a gdk_gl_context_clear_current() if the current context is attached
+ * to @surface, leaves the current context alone otherwise.
+ **/
+void
+gdk_gl_context_clear_current_if_surface (GdkSurface *surface)
+{
+  MaskedContext *current;
+
+  current = g_private_get (&thread_current_context);
+  if (current != NULL && !mask_is_surfaceless (current))
+    {
+      GdkGLContext *context = unmask_context (current);
+
+      if (gdk_gl_context_get_surface (context) != surface)
+        return;
+
+      if (GDK_GL_CONTEXT_GET_CLASS (context)->clear_current (context))
+        g_private_replace (&thread_current_context, NULL);
+    }
+}
+
 /**
  * gdk_gl_context_get_current:
  *
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index e07420f1c1..fccffdb013 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -99,6 +99,8 @@ gboolean                gdk_gl_backend_can_be_used              (GdkGLBackend
                                                                  GError         **error);
 void                    gdk_gl_backend_use                      (GdkGLBackend     backend_type);
 
+void                    gdk_gl_context_clear_current_if_surface (GdkSurface      *surface);
+
 GdkGLContext *          gdk_gl_context_new                      (GdkDisplay      *display,
                                                                  GdkSurface      *surface);
 
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index a8c6cab390..1f176b9b87 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -1095,6 +1095,7 @@ gdk_surface_set_egl_native_window (GdkSurface *self,
 
   if (priv->egl_surface != NULL)
     {
+      gdk_gl_context_clear_current_if_surface (self);
       eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
       priv->egl_surface = NULL;
     }
@@ -1123,6 +1124,7 @@ gdk_surface_ensure_egl_surface (GdkSurface *self,
       priv->egl_surface != NULL &&
       gdk_display_get_egl_config_high_depth (display) != gdk_display_get_egl_config (display))
     {
+      gdk_gl_context_clear_current_if_surface (self);
       eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
       priv->egl_surface = NULL;
     }
diff --git a/gdk/x11/gdkglcontext-glx.c b/gdk/x11/gdkglcontext-glx.c
index 334acf8ff9..d768ccf35c 100644
--- a/gdk/x11/gdkglcontext-glx.c
+++ b/gdk/x11/gdkglcontext-glx.c
@@ -71,6 +71,8 @@ gdk_x11_surface_destroy_glx_drawable (GdkX11Surface *self)
   if (self->glx_drawable == None)
     return;
 
+  gdk_gl_context_clear_current_if_surface (GDK_SURFACE (self));
+
   glXDestroyWindow (gdk_x11_display_get_xdisplay (gdk_surface_get_display (GDK_SURFACE (self))),
                     self->glx_drawable);
 


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