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) } } +/* + * 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);