gltexture: Optionally take a sync object

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.
This commit is contained in:
Matthias Clasen 2023-04-25 11:03:51 +02:00 committed by Benjamin Otte
parent 5071e6154c
commit 92eb845482
4 changed files with 91 additions and 4 deletions

View File

@ -39,6 +39,7 @@ struct _GdkGLTexture {
GdkGLContext *context; GdkGLContext *context;
guint id; guint id;
gboolean has_mipmap; gboolean has_mipmap;
gpointer sync;
GdkTexture *saved; GdkTexture *saved;
@ -296,6 +297,12 @@ gdk_gl_texture_has_mipmap (GdkGLTexture *self)
return self->has_mipmap; return self->has_mipmap;
} }
gpointer
gdk_gl_texture_get_sync (GdkGLTexture *self)
{
return self->sync;
}
/** /**
* gdk_gl_texture_release: * gdk_gl_texture_release:
* @self: a `GdkTexture` wrapping a GL texture * @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); self->id = gdk_gl_texture_builder_get_id (builder);
GDK_TEXTURE (self)->format = gdk_gl_texture_builder_get_format (builder); GDK_TEXTURE (self)->format = gdk_gl_texture_builder_get_format (builder);
self->has_mipmap = gdk_gl_texture_builder_get_has_mipmap (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->destroy = destroy;
self->data = data; self->data = data;

View File

@ -35,6 +35,7 @@ struct _GdkGLTextureBuilder
int height; int height;
GdkMemoryFormat format; GdkMemoryFormat format;
gboolean has_mipmap; gboolean has_mipmap;
gpointer sync;
}; };
struct _GdkGLTextureBuilderClass struct _GdkGLTextureBuilderClass
@ -68,6 +69,7 @@ enum
PROP_HAS_MIPMAP, PROP_HAS_MIPMAP,
PROP_HEIGHT, PROP_HEIGHT,
PROP_ID, PROP_ID,
PROP_SYNC,
PROP_WIDTH, PROP_WIDTH,
N_PROPS N_PROPS
@ -117,6 +119,10 @@ gdk_gl_texture_builder_get_property (GObject *object,
g_value_set_uint (value, self->id); g_value_set_uint (value, self->id);
break; break;
case PROP_SYNC:
g_value_set_pointer (value, self->sync);
break;
case PROP_WIDTH: case PROP_WIDTH:
g_value_set_int (value, self->width); g_value_set_int (value, self->width);
break; 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)); gdk_gl_texture_builder_set_id (self, g_value_get_uint (value));
break; break;
case PROP_SYNC:
gdk_gl_texture_builder_set_sync (self, g_value_get_pointer (value));
break;
case PROP_WIDTH: case PROP_WIDTH:
gdk_gl_texture_builder_set_width (self, g_value_get_int (value)); gdk_gl_texture_builder_set_width (self, g_value_get_int (value));
break; break;
@ -237,6 +247,19 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
0, G_MAXUINT, 0, 0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); 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) * 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]); 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) * gdk_gl_texture_builder_get_format: (attributes org.gdk.Method.get_property=format)
* @self: a `GdkGLTextureBuilder` * @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; * The `destroy` function gets called when the returned texture gets released;
* either when the texture is finalized or by an explicit call to * either when the texture is finalized or by an explicit call to
* [method@Gdk.GLTexture.release]. * [method@Gdk.GLTexture.release]. It should release all GL resources associated
* This function should release all GL resources associated with the texture, * with the texture, such as the [property@Gdk.GLTextureBuilder:id] and the
* such as the [property@Gdk.GLTextureBuilder:id]. * [property@Gdk.GLTextureBuilder:sync].
* *
* Note that it is a programming error to call this function if any mandatory * Note that it is a programming error to call this function if any mandatory
* property has not been set. * property has not been set.

View File

@ -72,6 +72,12 @@ GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_has_mipmap (GdkGLTextureBuilder *self, void gdk_gl_texture_builder_set_has_mipmap (GdkGLTextureBuilder *self,
gboolean has_mipmap); 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 GDK_AVAILABLE_IN_4_12
GdkTexture * gdk_gl_texture_builder_build (GdkGLTextureBuilder *self, GdkTexture * gdk_gl_texture_builder_build (GdkGLTextureBuilder *self,
GDestroyNotify destroy, GDestroyNotify destroy,

View File

@ -15,6 +15,7 @@ GdkTexture * gdk_gl_texture_new_from_builder (GdkGLTextureBuilder
GdkGLContext * gdk_gl_texture_get_context (GdkGLTexture *self); GdkGLContext * gdk_gl_texture_get_context (GdkGLTexture *self);
guint gdk_gl_texture_get_id (GdkGLTexture *self); guint gdk_gl_texture_get_id (GdkGLTexture *self);
gboolean gdk_gl_texture_has_mipmap (GdkGLTexture *self); gboolean gdk_gl_texture_has_mipmap (GdkGLTexture *self);
gpointer gdk_gl_texture_get_sync (GdkGLTexture *self);
G_END_DECLS G_END_DECLS