gdkgl: Check for GLsync before using it
authorBenjamin Otte <otte@redhat.com>
Sat, 1 Jul 2023 20:46:47 +0000 (22:46 +0200)
committerSimon McVittie <smcv@debian.org>
Wed, 8 Nov 2023 16:30:21 +0000 (16:30 +0000)
Copy what we do in GTK4: Check for GL >= 3.2 or GLES >= 3.0 or the
GL_ARB_sync extension.
Then store that info for a (private) gdk_gl_context_has_sync()
function.
And then check that function before using GLsync objects as introduced
by commit 9811485990b.

Bug: https://gitlab.gnome.org/GNOME/gtk/-/issues/5749
Forwarded: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6162
Origin: 3.24.39, commit:cf7decae1a1a2af825caca8da018ce09cd9ce31a

Gbp-Pq: Name gdkgl-Check-for-GLsync-before-using-it.patch

gdk/gdkgl.c
gdk/gdkglcontext.c
gdk/gdkglcontextprivate.h

index 86b169039a8d7921117debc2f72f467c78c20ebd..d3b460b4b716ab5605ee75288dd039cc4e22682b 100644 (file)
@@ -341,7 +341,7 @@ gdk_cairo_draw_from_gl (cairo_t              *cr,
                         int                   width,
                         int                   height)
 {
-  GdkGLContext *paint_context;
+  GdkGLContext *paint_context, *current_context;
   cairo_surface_t *image;
   cairo_matrix_t matrix;
   int dx, dy, window_scale;
@@ -352,7 +352,7 @@ gdk_cairo_draw_from_gl (cairo_t              *cr,
   int alpha_size = 0;
   cairo_region_t *clip_region;
   GdkGLContextPaintData *paint_data;
-  GLsync sync = NULL;
+  GLsync sync;
 
   impl_window = window->impl_window;
 
@@ -366,9 +366,13 @@ gdk_cairo_draw_from_gl (cairo_t              *cr,
     }
 
   clip_region = gdk_cairo_region_from_clip (cr);
+  current_context = gdk_gl_context_get_current ();
 
-  if ((gdk_gl_context_get_current () != NULL) && (gdk_gl_context_get_current () != paint_context))
+  if ((current_context != NULL) && (current_context != paint_context) &&
+      gdk_gl_context_has_sync (current_context))
     sync = glFenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+  else
+    sync = NULL;
 
   gdk_gl_context_make_current (paint_context);
 
index 3b23639e1ce91452307e10536f42c21b9c8befff..4c137a8d5dd435cff1cfc851cced0c41ea31ef82 100644 (file)
@@ -101,6 +101,7 @@ typedef struct {
   guint has_gl_framebuffer_blit : 1;
   guint has_frame_terminator : 1;
   guint has_unpack_subimage : 1;
+  guint has_sync : 1;
   guint extensions_checked : 1;
   guint debug_enabled : 1;
   guint forward_compatible : 1;
@@ -441,6 +442,14 @@ gdk_gl_context_has_unpack_subimage (GdkGLContext *context)
   return priv->has_unpack_subimage;
 }
 
+gboolean
+gdk_gl_context_has_sync (GdkGLContext *context)
+{
+  GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
+
+  return priv->has_sync;
+}
+
 /**
  * gdk_gl_context_set_debug_enabled:
  * @context: a #GdkGLContext
@@ -809,6 +818,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
       priv->has_frame_terminator = FALSE;
 
       priv->has_unpack_subimage = epoxy_has_gl_extension ("GL_EXT_unpack_subimage");
+      priv->has_sync = priv->gl_version >= 30;
     }
   else
     {
@@ -818,6 +828,9 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
       priv->has_gl_framebuffer_blit = priv->gl_version >= 30 || epoxy_has_gl_extension ("GL_EXT_framebuffer_blit");
       priv->has_frame_terminator = epoxy_has_gl_extension ("GL_GREMEDY_frame_terminator");
       priv->has_unpack_subimage = TRUE;
+      priv->has_sync = priv->gl_version >= 32 ||
+                       epoxy_has_gl_extension ("GL_ARB_sync") ||
+                       epoxy_has_gl_extension ("GL_APPLE_sync");
 
       /* We asked for a core profile, but we didn't get one, so we're in legacy mode */
       if (priv->gl_version < 32)
index cb0b76793fa0f54580574a63deb7762b69f8a184..94ecb34d30b58c87a85d217bd11524509a3a07b6 100644 (file)
@@ -86,6 +86,7 @@ gboolean                gdk_gl_context_use_texture_rectangle    (GdkGLContext
 gboolean                gdk_gl_context_has_framebuffer_blit     (GdkGLContext    *context);
 gboolean                gdk_gl_context_has_frame_terminator     (GdkGLContext    *context);
 gboolean                gdk_gl_context_has_unpack_subimage      (GdkGLContext    *context);
+gboolean                gdk_gl_context_has_sync                 (GdkGLContext    *context);
 void                    gdk_gl_context_end_frame                (GdkGLContext    *context,
                                                                  cairo_region_t  *painted,
                                                                  cairo_region_t  *damage);