mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 14:00:09 +00:00
Add a way to release GL resources
The inspector may hold on to render nodes and textures beyond the lifetime of the widget (and thus the GL resources). To handle this situation, allow the widget to explicitly release the GL resources, and make the texture available on the clent-side as a cairo surface. This lets the recorder still show the content after the widget is gone.
This commit is contained in:
parent
34c63b8e4f
commit
5e302ae2cc
@ -443,6 +443,8 @@ struct _GdkGLTexture {
|
||||
GdkGLContext *context;
|
||||
int id;
|
||||
|
||||
cairo_surface_t *saved;
|
||||
|
||||
GDestroyNotify destroy;
|
||||
gpointer data;
|
||||
};
|
||||
@ -458,10 +460,21 @@ gdk_gl_texture_dispose (GObject *object)
|
||||
{
|
||||
GdkGLTexture *self = GDK_GL_TEXTURE (object);
|
||||
|
||||
g_object_unref (self->context);
|
||||
|
||||
if (self->destroy)
|
||||
self->destroy (self->data);
|
||||
{
|
||||
self->destroy (self->data);
|
||||
self->destroy = NULL;
|
||||
self->data = NULL;
|
||||
}
|
||||
|
||||
g_clear_object (&self->context);
|
||||
self->id = 0;
|
||||
|
||||
if (self->saved)
|
||||
{
|
||||
cairo_surface_destroy (self->saved);
|
||||
self->saved = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gdk_gl_texture_parent_class)->dispose (object);
|
||||
}
|
||||
@ -474,7 +487,6 @@ gdk_gl_texture_download (GdkTexture *texture,
|
||||
GdkGLTexture *self = GDK_GL_TEXTURE (texture);
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
GdkWindow *window;
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
@ -482,8 +494,21 @@ gdk_gl_texture_download (GdkTexture *texture,
|
||||
stride);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
window = gdk_gl_context_get_window (self->context);
|
||||
gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0, texture->width, texture->height);
|
||||
|
||||
if (self->saved)
|
||||
{
|
||||
cairo_set_source_surface (cr, self->saved, 0, 0);
|
||||
cairo_paint (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkWindow *window;
|
||||
|
||||
window = gdk_gl_context_get_window (self->context);
|
||||
gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0,
|
||||
texture->width, texture->height);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_finish (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
@ -516,6 +541,41 @@ gdk_gl_texture_get_id (GdkGLTexture *self)
|
||||
return self->id;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_texture_release_gl (GdkTexture *texture)
|
||||
{
|
||||
GdkGLTexture *self;
|
||||
GdkWindow *window;
|
||||
cairo_t *cr;
|
||||
|
||||
g_return_if_fail (GDK_IS_GL_TEXTURE (texture));
|
||||
|
||||
self = GDK_GL_TEXTURE (texture);
|
||||
|
||||
g_return_if_fail (self->saved == NULL);
|
||||
|
||||
self->saved = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
texture->width, texture->height);
|
||||
|
||||
cr = cairo_create (self->saved);
|
||||
|
||||
window = gdk_gl_context_get_window (self->context);
|
||||
gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0,
|
||||
texture->width, texture->height);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
if (self->destroy)
|
||||
{
|
||||
self->destroy (self->data);
|
||||
self->destroy = NULL;
|
||||
self->data = NULL;
|
||||
}
|
||||
|
||||
g_clear_object (&self->context);
|
||||
self->id = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_new_for_pixbuf:
|
||||
* @pixbuf: a #GdkPixbuf
|
||||
|
@ -64,6 +64,9 @@ GdkTexture * gdk_texture_new_for_gl (GdkGLContext
|
||||
GDestroyNotify destroy,
|
||||
gpointer data);
|
||||
|
||||
GDK_AVAILABLE_IN_3_94
|
||||
void gdk_texture_release_gl (GdkTexture *texture);
|
||||
|
||||
GDK_AVAILABLE_IN_3_94
|
||||
int gdk_texture_get_width (GdkTexture *texture);
|
||||
GDK_AVAILABLE_IN_3_94
|
||||
|
Loading…
Reference in New Issue
Block a user