[gtk+] Add a way to release GL resources



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]