gltexture: Optionally take a sync object
authorMatthias Clasen <mclasen@redhat.com>
Tue, 25 Apr 2023 09:03:51 +0000 (11:03 +0200)
committerBenjamin Otte <otte@redhat.com>
Thu, 27 Apr 2023 04:55:37 +0000 (06:55 +0200)
Add a new function to TextureBuilder that takes a GLsync that
requires internal code to wait on before using the texture.

Somewhat sneakily, we don't take the sync if syncs are not supported by
the current GL context.
As public API has no code to query the sync for the destroy notify, this
is fine and it means we don't have to do the check every time we want to
call gdk_texture_get_sync() internally.

gdk/gdkgltexture.c
gdk/gdkgltexturebuilder.c
gdk/gdkgltexturebuilder.h
gdk/gdkgltextureprivate.h

index e7818e9a07f425e1d09305b032f4d28f88ca97b1..3b6c20a63789755be5096d2b4b6ed79ac772ee44 100644 (file)
@@ -39,6 +39,7 @@ struct _GdkGLTexture {
   GdkGLContext *context;
   guint id;
   gboolean has_mipmap;
+  gpointer sync;
 
   GdkTexture *saved;
 
@@ -296,6 +297,12 @@ gdk_gl_texture_has_mipmap (GdkGLTexture *self)
   return self->has_mipmap;
 }
 
+gpointer
+gdk_gl_texture_get_sync (GdkGLTexture *self)
+{
+  return self->sync;
+}
+
 /**
  * gdk_gl_texture_release:
  * @self: a `GdkTexture` wrapping a GL texture
@@ -337,6 +344,8 @@ gdk_gl_texture_new_from_builder (GdkGLTextureBuilder *builder,
   self->id = gdk_gl_texture_builder_get_id (builder);
   GDK_TEXTURE (self)->format = gdk_gl_texture_builder_get_format (builder);
   self->has_mipmap = gdk_gl_texture_builder_get_has_mipmap (builder);
+  if (gdk_gl_context_has_sync (self->context))
+    self->sync = gdk_gl_texture_builder_get_sync (builder);
   self->destroy = destroy;
   self->data = data;
 
index ca13fe6618fbc7db6b235e5639a172f45435f5fa..ceaf44a9c80b5b639074bce2dd15bd0e08bf9c8c 100644 (file)
@@ -35,6 +35,7 @@ struct _GdkGLTextureBuilder
   int height;
   GdkMemoryFormat format;
   gboolean has_mipmap;
+  gpointer sync;
 };
 
 struct _GdkGLTextureBuilderClass
@@ -68,6 +69,7 @@ enum
   PROP_HAS_MIPMAP,
   PROP_HEIGHT,
   PROP_ID,
+  PROP_SYNC,
   PROP_WIDTH,
 
   N_PROPS
@@ -117,6 +119,10 @@ gdk_gl_texture_builder_get_property (GObject    *object,
       g_value_set_uint (value, self->id);
       break;
 
+    case PROP_SYNC:
+      g_value_set_pointer (value, self->sync);
+      break;
+
     case PROP_WIDTH:
       g_value_set_int (value, self->width);
       break;
@@ -157,6 +163,10 @@ gdk_gl_texture_builder_set_property (GObject      *object,
       gdk_gl_texture_builder_set_id (self, g_value_get_uint (value));
       break;
 
+    case PROP_SYNC:
+      gdk_gl_texture_builder_set_sync (self, g_value_get_pointer (value));
+      break;
+
     case PROP_WIDTH:
       gdk_gl_texture_builder_set_width (self, g_value_get_int (value));
       break;
@@ -237,6 +247,19 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
                        0, G_MAXUINT, 0,
                        G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
 
+  /**
+   * GdkGLTextureBuilder:sync: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_sync org.gdk.Property.set=gdk_gl_texture_builder_set_sync)
+   *
+   * An optional `GLSync` object.
+   *
+   * If this is set, GTK will wait on it before using the texture.
+   *
+   * Since: 4.12
+   */
+  properties[PROP_SYNC] =
+    g_param_spec_pointer ("sync", NULL, NULL,
+                          G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
   /**
    * GdkGLTextureBuilder:width: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_width org.gdk.Property.set=gdk_gl_texture_builder_set_width)
    *
@@ -494,6 +517,54 @@ gdk_gl_texture_builder_set_has_mipmap (GdkGLTextureBuilder *self,
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HAS_MIPMAP]);
 }
 
+/**
+ * gdk_gl_texture_builder_get_sync: (attributes org.gdk.Method.get_property=sync)
+ * @self: a `GdkGLTextureBuilder`
+ *
+ * Gets the `GLsync` previously set via gdk_gl_texture_builder_set_sync().
+ *
+ * Returns: (nullable): the `GLSync`
+ *
+ * Since: 4.12
+ */
+gpointer
+gdk_gl_texture_builder_get_sync (GdkGLTextureBuilder *self)
+{
+  g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
+
+  return self->sync;
+}
+
+/**
+ * gdk_gl_texture_builder_set_sync: (attributes org.gdk.Method.set_property=sync)
+ * @self: a `GdkGLTextureBuilder`
+ * @sync: (nullable): the GLSync object
+ *
+ * Sets the GLSync object to use for the texture.
+ *
+ * GTK will wait on this object before using the created `GdkTexture`.
+ *
+ * The `destroy` function that is passed to [method@Gdk.GLTextureBuilder.build]
+ * is responsible for freeing the sync object when it is no longer needed.
+ * The texture builder does not destroy it and it is the callers
+ * responsibility to make sure it doesn't leak.
+ *
+ * Since: 4.12
+ */
+void
+gdk_gl_texture_builder_set_sync (GdkGLTextureBuilder *self,
+                                 gpointer             sync)
+{
+  g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
+
+  if (self->sync == sync)
+    return;
+
+  self->sync = sync;
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SYNC]);
+}
+
 /**
  * gdk_gl_texture_builder_get_format: (attributes org.gdk.Method.get_property=format)
  * @self: a `GdkGLTextureBuilder`
@@ -553,9 +624,9 @@ gdk_gl_texture_builder_set_format (GdkGLTextureBuilder *self,
  *
  * The `destroy` function gets called when the returned texture gets released;
  * either when the texture is finalized or by an explicit call to
- * [method@Gdk.GLTexture.release].
- * This function should release all GL resources associated with the texture,
- * such as the [property@Gdk.GLTextureBuilder:id].
+ * [method@Gdk.GLTexture.release]. It should release all GL resources associated
+ * with the texture, such as the [property@Gdk.GLTextureBuilder:id] and the
+ * [property@Gdk.GLTextureBuilder:sync].
  *
  * Note that it is a programming error to call this function if any mandatory
  * property has not been set.
index 1633bca1c25922195eaf781acc6a193089af8553..03ee185e0c16071d914359ce280e17507689a45b 100644 (file)
@@ -72,6 +72,12 @@ GDK_AVAILABLE_IN_4_12
 void                    gdk_gl_texture_builder_set_has_mipmap   (GdkGLTextureBuilder    *self,
                                                                  gboolean                has_mipmap);
 
+GDK_AVAILABLE_IN_4_12
+gpointer                gdk_gl_texture_builder_get_sync         (GdkGLTextureBuilder    *self) G_GNUC_PURE;
+GDK_AVAILABLE_IN_4_12
+void                    gdk_gl_texture_builder_set_sync         (GdkGLTextureBuilder    *self,
+                                                                 gpointer                sync);
+
 GDK_AVAILABLE_IN_4_12
 GdkTexture *            gdk_gl_texture_builder_build            (GdkGLTextureBuilder    *self,
                                                                  GDestroyNotify          destroy,
index eae09290a9dad5fa2affdee5d19a4bea62593607..c2841fb55ee8fc89d151b2595d9d6320bffb2986 100644 (file)
@@ -10,11 +10,12 @@ G_BEGIN_DECLS
 GdkTexture *            gdk_gl_texture_new_from_builder (GdkGLTextureBuilder    *builder,
                                                          GDestroyNotify          destroy,
                                                          gpointer                data);
-                                                         
+
 
 GdkGLContext *          gdk_gl_texture_get_context      (GdkGLTexture           *self);
 guint                   gdk_gl_texture_get_id           (GdkGLTexture           *self);
 gboolean                gdk_gl_texture_has_mipmap       (GdkGLTexture           *self);
+gpointer                gdk_gl_texture_get_sync         (GdkGLTexture           *self);
 
 G_END_DECLS