1
0
mirror of https://gitlab.gnome.org/GNOME/libmks.git synced 2025-04-14 08:27:16 +00:00

Merge branch 'bilelmoussaoui/fix-rendering' into 'main'

dmabuf-paintable: Build the texture when snapshot is called

See merge request GNOME/libmks!28
This commit is contained in:
Christian Hergert 2023-08-15 19:41:08 +00:00
commit 46a05c4ba4

View File

@ -35,67 +35,20 @@
* so we can pass the damage region to `GdkGLTextureBuilder`. * so we can pass the damage region to `GdkGLTextureBuilder`.
*/ */
struct _MksDmabufPaintable
{
GObject parent_instance;
GdkTexture *texture;
guint width;
guint height;
};
typedef struct _MksDmabufTextureData typedef struct _MksDmabufTextureData
{ {
GdkGLContext *gl_context; GdkGLContext *gl_context;
GLuint texture_id; GLuint texture_id;
} MksDmabufTextureData; } MksDmabufTextureData;
static int struct _MksDmabufPaintable
mks_dmabuf_paintable_get_intrinsic_width (GdkPaintable *paintable)
{ {
return MKS_DMABUF_PAINTABLE (paintable)->width; GObject parent_instance;
} GdkTexture *texture;
GdkGLTextureBuilder *builder;
static int guint width;
mks_dmabuf_paintable_get_intrinsic_height (GdkPaintable *paintable) guint height;
{ };
return MKS_DMABUF_PAINTABLE (paintable)->height;
}
static double
mks_dmabuf_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
{
MksDmabufPaintable *self = MKS_DMABUF_PAINTABLE (paintable);
return (double)self->width / (double)self->height;
}
static void
mks_dmabuf_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
MksDmabufPaintable *self = (MksDmabufPaintable *)paintable;
graphene_rect_t area;
g_assert (MKS_IS_DMABUF_PAINTABLE (self));
g_assert (GDK_IS_SNAPSHOT (snapshot));
area = GRAPHENE_RECT_INIT (0, 0, width, height);
gtk_snapshot_append_texture (snapshot, self->texture, &area);
}
static void
paintable_iface_init (GdkPaintableInterface *iface)
{
iface->get_intrinsic_width = mks_dmabuf_paintable_get_intrinsic_width;
iface->get_intrinsic_height = mks_dmabuf_paintable_get_intrinsic_height;
iface->get_intrinsic_aspect_ratio = mks_dmabuf_paintable_get_intrinsic_aspect_ratio;
iface->snapshot = mks_dmabuf_paintable_snapshot;
}
G_DEFINE_FINAL_TYPE_WITH_CODE (MksDmabufPaintable, mks_dmabuf_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, paintable_iface_init))
static MksDmabufTextureData * static MksDmabufTextureData *
mks_dmabuf_texture_data_new (GdkGLContext *gl_context, mks_dmabuf_texture_data_new (GdkGLContext *gl_context,
@ -127,12 +80,76 @@ mks_dmabuf_texture_data_free (gpointer data)
g_free (texture_data); g_free (texture_data);
} }
static int
mks_dmabuf_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
return MKS_DMABUF_PAINTABLE (paintable)->width;
}
static int
mks_dmabuf_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
return MKS_DMABUF_PAINTABLE (paintable)->height;
}
static double
mks_dmabuf_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
{
MksDmabufPaintable *self = MKS_DMABUF_PAINTABLE (paintable);
return (double)self->width / (double)self->height;
}
static void
mks_dmabuf_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
MksDmabufPaintable *self = (MksDmabufPaintable *)paintable;
g_autoptr(GdkTexture) texture = NULL;
GdkGLContext *gl_context;
GLuint texture_id;
graphene_rect_t area;
g_assert (MKS_IS_DMABUF_PAINTABLE (self));
g_assert (GDK_IS_SNAPSHOT (snapshot));
texture_id = gdk_gl_texture_builder_get_id (self->builder);
gl_context = gdk_gl_texture_builder_get_context (self->builder);
gdk_gl_texture_builder_set_update_texture (self->builder, self->texture);
texture = gdk_gl_texture_builder_build (self->builder,
mks_dmabuf_texture_data_free,
mks_dmabuf_texture_data_new (gl_context,
texture_id));
// Clear up the update region to not union it with the next UpdateDMABuf call
gdk_gl_texture_builder_set_update_region (self->builder, NULL);
g_set_object (&self->texture, texture);
area = GRAPHENE_RECT_INIT (0, 0, width, height);
gtk_snapshot_append_texture (snapshot, self->texture, &area);
}
static void
paintable_iface_init (GdkPaintableInterface *iface)
{
iface->get_intrinsic_width = mks_dmabuf_paintable_get_intrinsic_width;
iface->get_intrinsic_height = mks_dmabuf_paintable_get_intrinsic_height;
iface->get_intrinsic_aspect_ratio = mks_dmabuf_paintable_get_intrinsic_aspect_ratio;
iface->snapshot = mks_dmabuf_paintable_snapshot;
}
G_DEFINE_FINAL_TYPE_WITH_CODE (MksDmabufPaintable, mks_dmabuf_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, paintable_iface_init))
static void static void
mks_dmabuf_paintable_dispose (GObject *object) mks_dmabuf_paintable_dispose (GObject *object)
{ {
MksDmabufPaintable *self = (MksDmabufPaintable *)object; MksDmabufPaintable *self = (MksDmabufPaintable *)object;
g_clear_object (&self->texture); g_clear_object (&self->texture);
g_clear_object (&self->builder);
G_OBJECT_CLASS (mks_dmabuf_paintable_parent_class)->dispose (object); G_OBJECT_CLASS (mks_dmabuf_paintable_parent_class)->dispose (object);
} }
@ -157,8 +174,8 @@ mks_dmabuf_paintable_import (MksDmabufPaintable *self,
cairo_region_t *region, cairo_region_t *region,
GError **error) GError **error)
{ {
g_autoptr(GdkGLTextureBuilder) builder = NULL; cairo_region_t *accumulated_damages;
g_autoptr(GdkTexture) texture = NULL; cairo_region_t *previous_region;
GLuint texture_id; GLuint texture_id;
guint zero = 0; guint zero = 0;
@ -204,25 +221,32 @@ mks_dmabuf_paintable_import (MksDmabufPaintable *self,
return FALSE; return FALSE;
} }
builder = gdk_gl_texture_builder_new (); accumulated_damages = cairo_region_create ();
gdk_gl_texture_builder_set_id (builder, texture_id);
gdk_gl_texture_builder_set_width (builder, self->width);
gdk_gl_texture_builder_set_height (builder, self->height);
gdk_gl_texture_builder_set_context (builder, gl_context);
if (region != NULL) if (region != NULL)
cairo_region_union (accumulated_damages, region);
if (self->builder != NULL)
{ {
gdk_gl_texture_builder_set_update_region (builder, region); previous_region = gdk_gl_texture_builder_get_update_region (self->builder);
gdk_gl_texture_builder_set_update_texture (builder, self->texture); if (previous_region != NULL)
cairo_region_union (accumulated_damages, previous_region);
} }
texture = gdk_gl_texture_builder_build (builder, g_clear_object (&self->builder);
mks_dmabuf_texture_data_free,
mks_dmabuf_texture_data_new (gl_context, texture_id));
g_set_object (&self->texture, texture); self->builder = gdk_gl_texture_builder_new ();
gdk_gl_texture_builder_set_width (self->builder, self->width);
gdk_gl_texture_builder_set_height (self->builder, self->height);
gdk_gl_texture_builder_set_context (self->builder, gl_context);
gdk_gl_texture_builder_set_id (self->builder, texture_id);
if (cairo_region_num_rectangles (accumulated_damages) > 0)
gdk_gl_texture_builder_set_update_region (self->builder,
accumulated_damages);
g_clear_pointer (&accumulated_damages, cairo_region_destroy);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self)); gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
return TRUE; return TRUE;
} }