[mutter/wip/texture-purge-on-nvidia: 4/4] wip! compositor: save and restore textures on suspend



commit 013968445cfa1bd40e45cd524e6f1c1dee1c6ebf
Author: Ray Strode <rstrode redhat com>
Date:   Thu Jan 10 10:48:02 2019 -0500

    wip! compositor: save and restore textures on suspend

 src/compositor/meta-shaped-texture.c | 102 +++++++++++++++++++++++++++++++++++
 src/meta/meta-shaped-texture.h       |   2 +
 2 files changed, 104 insertions(+)
---
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 98346c6ae..b5dc17587 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -37,6 +37,7 @@
 #include "meta-texture-tower.h"
 
 #include "meta-cullable.h"
+#include <meta/meta-backend.h>
 
 static void meta_shaped_texture_dispose  (GObject    *object);
 
@@ -92,6 +93,9 @@ struct _MetaShapedTexturePrivate
   cairo_region_t *clip_region;
   cairo_region_t *unobscured_region;
 
+  cairo_surface_t *saved_base_surface;
+  cairo_surface_t *saved_mask_surface;
+
   guint tex_width, tex_height;
   guint fallback_width, fallback_height;
 
@@ -125,6 +129,7 @@ static void
 meta_shaped_texture_init (MetaShapedTexture *self)
 {
   MetaShapedTexturePrivate *priv;
+  MetaBackend *backend = meta_get_backend ();
 
   priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self);
 
@@ -134,6 +139,9 @@ meta_shaped_texture_init (MetaShapedTexture *self)
   priv->mask_texture = NULL;
   priv->create_mipmaps = TRUE;
   priv->is_y_inverted = TRUE;
+
+  g_signal_connect_object (backend, "suspending", G_CALLBACK (meta_shaped_texture_save), self, 
G_CONNECT_SWAPPED);
+  g_signal_connect_object (backend, "resuming", G_CALLBACK (meta_shaped_texture_restore), self, 
G_CONNECT_SWAPPED);
 }
 
 static void
@@ -986,6 +994,100 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
   return surface;
 }
 
+void
+meta_shaped_texture_save (MetaShapedTexture *stex)
+{
+
+  CoglTexture *texture, *mask_texture;
+  cairo_rectangle_int_t texture_rect = { 0, 0, 0, 0 };
+  MetaShapedTexturePrivate *priv = stex->priv;
+  cairo_surface_t *surface;
+
+  g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
+
+  texture = COGL_TEXTURE (priv->texture);
+
+  if (texture == NULL)
+    return;
+
+  g_clear_pointer (&priv->saved_base_surface, cairo_surface_destroy);
+  g_clear_pointer (&priv->saved_mask_surface, cairo_surface_destroy);
+
+  texture_rect.width = cogl_texture_get_width (texture);
+  texture_rect.height = cogl_texture_get_height (texture);
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                        cogl_texture_get_width (texture),
+                                        cogl_texture_get_height (texture));
+
+  cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+                         cairo_image_surface_get_stride (surface),
+                         cairo_image_surface_get_data (surface));
+
+  cairo_surface_mark_dirty (surface);
+
+  priv->saved_base_surface = surface;
+
+  mask_texture = stex->priv->mask_texture;
+  if (mask_texture != NULL)
+    {
+      cairo_t *cr;
+      cairo_surface_t *mask_surface;
+
+      mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
+                                                 cogl_texture_get_width (mask_texture),
+                                                 cogl_texture_get_height (mask_texture));
+
+      cogl_texture_get_data (mask_texture, COGL_PIXEL_FORMAT_A_8,
+                             cairo_image_surface_get_stride (mask_surface),
+                             cairo_image_surface_get_data (mask_surface));
+
+      cairo_surface_mark_dirty (mask_surface);
+
+      priv->saved_mask_surface = mask_surface;
+    }
+}
+
+void
+meta_shaped_texture_restore (MetaShapedTexture *stex)
+{
+  MetaShapedTexturePrivate *priv = stex->priv;
+  CoglTexture *texture, *mask_texture;
+  CoglError *error = NULL;
+
+  texture = COGL_TEXTURE (priv->texture);
+
+  if (texture == NULL)
+    return;
+
+  if (!cogl_texture_set_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+                              cairo_image_surface_get_stride (priv->saved_base_surface),
+                              cairo_image_surface_get_data (priv->saved_base_surface), 0,
+                              &error))
+    {
+      g_warning ("Failed to restore texture");
+      cogl_error_free (error);
+      error = NULL;
+    }
+  g_clear_pointer (&priv->saved_base_surface, cairo_surface_destroy);
+
+  mask_texture = stex->priv->mask_texture;
+
+  if (mask_texture != NULL)
+    {
+      if (!cogl_texture_set_data (mask_texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+                                  cairo_image_surface_get_stride (priv->saved_mask_surface),
+                                  cairo_image_surface_get_data (priv->saved_mask_surface), 0,
+                                  &error))
+      {
+          g_warning ("Failed to restore texture");
+          cogl_error_free (error);
+          error = NULL;
+      }
+      g_clear_pointer (&priv->saved_mask_surface, cairo_surface_destroy);
+    }
+}
+
 void
 meta_shaped_texture_set_fallback_size (MetaShapedTexture *self,
                                        guint              fallback_width,
diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h
index 80b23f2ea..fc0567c9f 100644
--- a/src/meta/meta-shaped-texture.h
+++ b/src/meta/meta-shaped-texture.h
@@ -81,6 +81,8 @@ void meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex,
 cairo_surface_t * meta_shaped_texture_get_image (MetaShapedTexture     *stex,
                                                  cairo_rectangle_int_t *clip);
 
+void meta_shaped_texture_save (MetaShapedTexture *self);
+void meta_shaped_texture_restore (MetaShapedTexture *self);
 G_END_DECLS
 
 #endif /* __META_SHAPED_TEXTURE_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]