glarea: Clean up dispose
We were getting our gl and dmabuf texture mixed up and ending up freeing the Texture structs while they were still used as callback data for dmabuf texture destroys. Avoid that by keeping separate pointers for the gl and dmabuf textures. Fixes: #6623
This commit is contained in:
@@ -156,7 +156,8 @@
|
||||
|
||||
typedef struct {
|
||||
GdkGLTextureBuilder *builder;
|
||||
GdkTexture *holder;
|
||||
GdkTexture *gl_texture;
|
||||
GdkTexture *dmabuf_texture;
|
||||
} Texture;
|
||||
|
||||
typedef struct {
|
||||
@@ -415,16 +416,20 @@ delete_one_texture (gpointer data)
|
||||
Texture *texture = data;
|
||||
guint id;
|
||||
|
||||
if (texture->holder)
|
||||
gdk_gl_texture_release (GDK_GL_TEXTURE (texture->holder));
|
||||
if (texture->gl_texture)
|
||||
{
|
||||
gdk_gl_texture_release (GDK_GL_TEXTURE (texture->gl_texture));
|
||||
texture->gl_texture = NULL;
|
||||
}
|
||||
|
||||
id = gdk_gl_texture_builder_get_id (texture->builder);
|
||||
if (id != 0)
|
||||
glDeleteTextures (1, &id);
|
||||
|
||||
g_object_unref (texture->builder);
|
||||
g_clear_object (&texture->builder);
|
||||
|
||||
g_free (texture);
|
||||
if (texture->gl_texture == NULL && texture->dmabuf_texture == NULL)
|
||||
g_free (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -449,7 +454,7 @@ gtk_gl_area_ensure_texture (GtkGLArea *area)
|
||||
link = l;
|
||||
l = l->next;
|
||||
|
||||
if (texture->holder)
|
||||
if (texture->gl_texture)
|
||||
continue;
|
||||
|
||||
priv->textures = g_list_delete_link (priv->textures, link);
|
||||
@@ -466,7 +471,8 @@ gtk_gl_area_ensure_texture (GtkGLArea *area)
|
||||
GLuint id;
|
||||
|
||||
priv->texture = g_new (Texture, 1);
|
||||
priv->texture->holder = NULL;
|
||||
priv->texture->gl_texture = NULL;
|
||||
priv->texture->dmabuf_texture = NULL;
|
||||
|
||||
priv->texture->builder = gdk_gl_texture_builder_new ();
|
||||
gdk_gl_texture_builder_set_context (priv->texture->builder, priv->context);
|
||||
@@ -524,7 +530,7 @@ gtk_gl_area_allocate_texture (GtkGLArea *area)
|
||||
if (priv->texture == NULL)
|
||||
return;
|
||||
|
||||
g_assert (priv->texture->holder == NULL);
|
||||
g_assert (priv->texture->gl_texture == NULL);
|
||||
|
||||
scale = gtk_widget_get_scale_factor (widget);
|
||||
width = gtk_widget_get_width (widget) * scale;
|
||||
@@ -706,7 +712,7 @@ gtk_gl_area_draw_error_screen (GtkGLArea *area,
|
||||
}
|
||||
|
||||
static void
|
||||
release_texture (gpointer data)
|
||||
release_gl_texture (gpointer data)
|
||||
{
|
||||
Texture *texture = data;
|
||||
gpointer sync;
|
||||
@@ -718,7 +724,7 @@ release_texture (gpointer data)
|
||||
gdk_gl_texture_builder_set_sync (texture->builder, NULL);
|
||||
}
|
||||
|
||||
texture->holder = NULL;
|
||||
texture->gl_texture = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -735,10 +741,14 @@ release_dmabuf_texture (gpointer data)
|
||||
{
|
||||
Texture *texture = data;
|
||||
|
||||
release_dmabuf (gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture->holder)));
|
||||
g_object_set_data (G_OBJECT (texture->holder), "gltexture", NULL);
|
||||
g_clear_object (&texture->gl_texture);
|
||||
|
||||
texture->holder = NULL;
|
||||
if (texture->dmabuf_texture == NULL)
|
||||
return;
|
||||
|
||||
release_dmabuf (gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture->dmabuf_texture )));
|
||||
|
||||
texture->dmabuf_texture = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -784,8 +794,8 @@ gtk_gl_area_snapshot (GtkWidget *widget,
|
||||
{
|
||||
Texture *texture;
|
||||
gpointer sync = NULL;
|
||||
GdkTexture *gltexture;
|
||||
GdkDmabuf dmabuf;
|
||||
GdkTexture *holder;
|
||||
|
||||
if (priv->needs_render || priv->auto_render)
|
||||
{
|
||||
@@ -809,9 +819,10 @@ gtk_gl_area_snapshot (GtkWidget *widget,
|
||||
|
||||
gdk_gl_texture_builder_set_sync (texture->builder, sync);
|
||||
|
||||
gltexture = gdk_gl_texture_builder_build (texture->builder,
|
||||
release_texture,
|
||||
texture);
|
||||
texture->gl_texture = gdk_gl_texture_builder_build (texture->builder,
|
||||
release_gl_texture,
|
||||
texture);
|
||||
holder = texture->gl_texture;
|
||||
|
||||
if (gdk_gl_context_export_dmabuf (priv->context,
|
||||
gdk_gl_texture_builder_get_id (texture->builder),
|
||||
@@ -820,22 +831,20 @@ gtk_gl_area_snapshot (GtkWidget *widget,
|
||||
GdkDmabufTextureBuilder *builder = gdk_dmabuf_texture_builder_new ();
|
||||
|
||||
gdk_dmabuf_texture_builder_set_display (builder, gdk_gl_context_get_display (priv->context));
|
||||
gdk_dmabuf_texture_builder_set_width (builder, gdk_texture_get_width (gltexture));
|
||||
gdk_dmabuf_texture_builder_set_height (builder, gdk_texture_get_height (gltexture));
|
||||
gdk_dmabuf_texture_builder_set_width (builder, gdk_texture_get_width (texture->gl_texture));
|
||||
gdk_dmabuf_texture_builder_set_height (builder, gdk_texture_get_height (texture->gl_texture));
|
||||
gdk_dmabuf_texture_builder_set_premultiplied (builder, TRUE);
|
||||
gdk_dmabuf_texture_builder_set_dmabuf (builder, &dmabuf);
|
||||
|
||||
texture->holder = gdk_dmabuf_texture_builder_build (builder, release_dmabuf_texture, texture, NULL);
|
||||
texture->dmabuf_texture = gdk_dmabuf_texture_builder_build (builder, release_dmabuf_texture, texture, NULL);
|
||||
|
||||
g_object_unref (builder);
|
||||
|
||||
if (texture->holder != NULL)
|
||||
g_object_set_data_full (G_OBJECT (texture->holder), "gltexture", gltexture, g_object_unref);
|
||||
if (texture->dmabuf_texture != NULL)
|
||||
holder = texture->dmabuf_texture;
|
||||
else
|
||||
release_dmabuf (&dmabuf);
|
||||
}
|
||||
else
|
||||
texture->holder = gltexture;
|
||||
|
||||
/* Our texture is rendered by OpenGL, so it is upside down,
|
||||
* compared to what GSK expects, so flip it back.
|
||||
@@ -844,13 +853,13 @@ gtk_gl_area_snapshot (GtkWidget *widget,
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (0, gtk_widget_get_height (widget)));
|
||||
gtk_snapshot_scale (snapshot, 1, -1);
|
||||
gtk_snapshot_append_texture (snapshot,
|
||||
texture->holder,
|
||||
holder,
|
||||
&GRAPHENE_RECT_INIT (0, 0,
|
||||
gtk_widget_get_width (widget),
|
||||
gtk_widget_get_height (widget)));
|
||||
gtk_snapshot_restore (snapshot);
|
||||
|
||||
g_object_unref (texture->holder);
|
||||
g_object_unref (holder);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user