gpu: Fix fd leak in GL dmabuf export

The texture ID is not deleted on dmabuf export; a copy is made, the
GskGpuImage retains ownership.

However when doing GL export, the texture *does* take ownership, so we
need the stealing semantics for that case.
This commit is contained in:
Benjamin Otte
2024-08-26 04:24:42 +02:00
parent a7afde2e7d
commit 65c8320a32
3 changed files with 18 additions and 14 deletions

View File

@@ -46,7 +46,7 @@ gsk_gl_image_finalize (GObject *object)
if (self->texture_id && self->framebuffer_id) if (self->texture_id && self->framebuffer_id)
glDeleteFramebuffers (1, &self->framebuffer_id); glDeleteFramebuffers (1, &self->framebuffer_id);
if (self->owns_texture) if (gsk_gpu_image_get_flags (GSK_GPU_IMAGE (self)) & GSK_GPU_IMAGE_TOGGLE_REF)
glDeleteTextures (1, &self->texture_id); glDeleteTextures (1, &self->texture_id);
G_OBJECT_CLASS (gsk_gl_image_parent_class)->finalize (object); G_OBJECT_CLASS (gsk_gl_image_parent_class)->finalize (object);
@@ -336,17 +336,17 @@ gsk_gl_image_get_gl_type (GskGLImage *self)
} }
GLuint GLuint
gsk_gl_image_steal_texture (GskGLImage *self) gsk_gl_image_get_texture_id (GskGLImage *self)
{ {
g_assert (self->owns_texture);
if (self->framebuffer_id)
{
glDeleteFramebuffers (1, &self->framebuffer_id);
self->framebuffer_id = 0;
}
self->owns_texture = FALSE;
return self->texture_id; return self->texture_id;
} }
void
gsk_gl_image_steal_texture_ownership (GskGLImage *self)
{
g_assert (self->texture_id);
g_assert (self->owns_texture);
self->owns_texture = FALSE;
}

View File

@@ -39,6 +39,7 @@ GLint gsk_gl_image_get_gl_internal_format (GskGLIm
GLenum gsk_gl_image_get_gl_format (GskGLImage *self); GLenum gsk_gl_image_get_gl_format (GskGLImage *self);
GLenum gsk_gl_image_get_gl_type (GskGLImage *self); GLenum gsk_gl_image_get_gl_type (GskGLImage *self);
GLuint gsk_gl_image_steal_texture (GskGLImage *self); GLuint gsk_gl_image_get_texture_id (GskGLImage *self);
void gsk_gl_image_steal_texture_ownership (GskGLImage *self);
G_END_DECLS G_END_DECLS

View File

@@ -300,7 +300,7 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op,
/* Don't use the renderer context, the texture might survive the frame /* Don't use the renderer context, the texture might survive the frame
* and its surface */ * and its surface */
context = gdk_display_get_gl_context (gsk_gpu_device_get_display (gsk_gpu_frame_get_device (frame))); context = gdk_display_get_gl_context (gsk_gpu_device_get_display (gsk_gpu_frame_get_device (frame)));
texture_id = gsk_gl_image_steal_texture (GSK_GL_IMAGE (self->image)); texture_id = gsk_gl_image_get_texture_id (GSK_GL_IMAGE (self->image));
#ifdef HAVE_DMABUF #ifdef HAVE_DMABUF
if (self->allow_dmabuf) if (self->allow_dmabuf)
@@ -351,6 +351,9 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op,
gsk_gl_texture_data_free, gsk_gl_texture_data_free,
data); data);
gsk_gpu_image_toggle_ref_texture (self->image, self->texture);
gsk_gl_image_steal_texture_ownership (GSK_GL_IMAGE (self->image));
g_object_unref (builder); g_object_unref (builder);
return op->next; return op->next;