[gtk/wip/otte/for-main] gl: Clear current when destroying current's surface
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/for-main] gl: Clear current when destroying current's surface
- Date: Wed, 22 Dec 2021 19:01:20 +0000 (UTC)
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]