[gtk+] Add a way to release GL resources
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] Add a way to release GL resources
- Date: Thu, 18 Jan 2018 01:20:03 +0000 (UTC)
commit 5e302ae2cc62d2e1d7cae9e6efb3b32b368c7b30
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Jan 17 20:15:45 2018 -0500
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.
gdk/gdktexture.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++----
gdk/gdktexture.h | 3 ++
2 files changed, 69 insertions(+), 6 deletions(-)
---
diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c
index c87ed57..f85b096 100644
--- a/gdk/gdktexture.c
+++ b/gdk/gdktexture.c
@@ -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
diff --git a/gdk/gdktexture.h b/gdk/gdktexture.h
index 4f3ead2..ae7ac81 100644
--- a/gdk/gdktexture.h
+++ b/gdk/gdktexture.h
@@ -65,6 +65,9 @@ GdkTexture * gdk_texture_new_for_gl (GdkGLContext
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
int gdk_texture_get_height (GdkTexture *texture);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]