[mutter/wip/fmuellner/gtk-shadows: 5/8] window-actor: Use different shape_regions/masks based on focus state



commit b35ad080ced79b39aa1c8d0264241463a4a58015
Author: Florian Müllner <fmuellner gnome org>
Date:   Fri Oct 28 12:58:39 2016 +0200

    window-actor: Use different shape_regions/masks based on focus state
    
    We now update the frame mask and -shape on every focus change, which
    is expensive and wasteful if we recompute the same two regions over
    and over again. To address this, use different regions/masks based on
    the focus state, so that we'll be able to re-use a previously computed
    one if possible.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=744667

 src/compositor/meta-window-actor.c |   57 ++++++++++++++++++++++++++---------
 1 files changed, 42 insertions(+), 15 deletions(-)
---
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index c3df284..73d017a 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -67,8 +67,12 @@ struct _MetaWindowActorPrivate
   MetaShadow       *focused_shadow;
   MetaShadow       *unfocused_shadow;
 
+  CoglTexture      *focused_mask;
+  CoglTexture      *unfocused_mask;
+
   /* A region that matches the shape of the window, including frame bounds */
-  cairo_region_t   *shape_region;
+  cairo_region_t   *focused_shape_region;
+  cairo_region_t   *unfocused_shape_region;
   /* The region we should clip to when painting the shadow */
   cairo_region_t   *shadow_clip;
 
@@ -458,7 +462,8 @@ meta_window_actor_constructed (GObject *object)
 
   /* Start off with an empty shape region to maintain the invariant
    * that it's always set */
-  priv->shape_region = cairo_region_create ();
+  priv->focused_shape_region = cairo_region_create ();
+  priv->unfocused_shape_region = cairo_region_create ();
 }
 
 static void
@@ -479,9 +484,13 @@ meta_window_actor_dispose (GObject *object)
       priv->send_frame_messages_timer = 0;
     }
 
-  g_clear_pointer (&priv->shape_region, cairo_region_destroy);
+  g_clear_pointer (&priv->focused_shape_region, cairo_region_destroy);
+  g_clear_pointer (&priv->unfocused_shape_region, cairo_region_destroy);
   g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
 
+  g_clear_pointer (&priv->focused_mask, cogl_object_unref);
+  g_clear_pointer (&priv->unfocused_mask, cogl_object_unref);
+
   g_clear_pointer (&priv->shadow_class, g_free);
   g_clear_pointer (&priv->focused_shadow, meta_shadow_unref);
   g_clear_pointer (&priv->unfocused_shadow, meta_shadow_unref);
@@ -622,8 +631,10 @@ meta_window_actor_get_shape_bounds (MetaWindowActor       *self,
                                     cairo_rectangle_int_t *bounds)
 {
   MetaWindowActorPrivate *priv = self->priv;
-
-  cairo_region_get_extents (priv->shape_region, bounds);
+  gboolean appears_focused = meta_window_appears_focused (priv->window);
+  cairo_region_t *shape_region = appears_focused ? priv->focused_shape_region
+                                                 : priv->unfocused_shape_region;
+  cairo_region_get_extents (shape_region, bounds);
 }
 
 static void
@@ -1586,7 +1597,12 @@ check_needs_shadow (MetaWindowActor *self)
   if (*shadow_location == NULL && should_have_shadow)
     {
       if (priv->shadow_shape == NULL)
-        priv->shadow_shape = meta_window_shape_new (priv->shape_region);
+        {
+          cairo_region_t *shape_region;
+          shape_region = appears_focused ? priv->focused_shape_region
+                                         : priv->unfocused_shape_region;
+          priv->shadow_shape = meta_window_shape_new (shape_region);
+        }
 
       MetaShadowFactory *factory = meta_shadow_factory_get_default ();
       const char *shadow_class = meta_window_actor_get_shadow_class (self);
@@ -1679,10 +1695,11 @@ build_and_scan_frame_mask (MetaWindowActor       *self,
   guchar *mask_data;
   guint tex_width, tex_height;
   MetaShapedTexture *stex;
-  CoglTexture *paint_tex, *mask_texture;
+  CoglTexture *paint_tex, *mask_texture, **mask_ptr;
   int stride;
   cairo_t *cr;
   cairo_surface_t *surface;
+  gboolean appears_focused = meta_window_appears_focused (priv->window);
 
   stex = meta_surface_actor_get_texture (priv->surface);
   g_return_if_fail (stex);
@@ -1763,8 +1780,10 @@ build_and_scan_frame_mask (MetaWindowActor       *self,
     }
 
   meta_shaped_texture_set_mask_texture (stex, mask_texture);
-  if (mask_texture)
-    cogl_object_unref (mask_texture);
+
+  mask_ptr = appears_focused ? &priv->focused_mask : &priv->unfocused_mask;
+  g_clear_pointer (mask_ptr, cogl_object_unref);
+  *mask_ptr = mask_texture;
 
   g_free (mask_data);
 }
@@ -1773,8 +1792,12 @@ static void
 meta_window_actor_update_shape_region (MetaWindowActor *self)
 {
   MetaWindowActorPrivate *priv = self->priv;
-  cairo_region_t *region = NULL;
+  cairo_region_t *region = NULL, **shape_region;
   cairo_rectangle_int_t client_area;
+  gboolean appears_focused = meta_window_appears_focused (priv->window);
+
+  shape_region = appears_focused ? &priv->focused_shape_region
+                                 : &priv->unfocused_shape_region;
 
   meta_window_get_client_area_rect (priv->window, &client_area);
 
@@ -1798,8 +1821,8 @@ meta_window_actor_update_shape_region (MetaWindowActor *self)
   if ((priv->window->shape_region != NULL) || (priv->window->frame != NULL))
     build_and_scan_frame_mask (self, &client_area, region);
 
-  g_clear_pointer (&priv->shape_region, cairo_region_destroy);
-  priv->shape_region = region;
+  g_clear_pointer (shape_region, cairo_region_destroy);
+  *shape_region = region;
 
   g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref);
 
@@ -1833,8 +1856,12 @@ static void
 meta_window_actor_update_opaque_region (MetaWindowActor *self)
 {
   MetaWindowActorPrivate *priv = self->priv;
-  cairo_region_t *opaque_region;
+  cairo_region_t *opaque_region, *shape_region;
   gboolean argb32 = is_argb32 (self);
+  gboolean appears_focused = meta_window_appears_focused (priv->window);
+
+  shape_region = appears_focused ? priv->focused_shape_region
+                                 : priv->unfocused_shape_region;
 
   if (argb32 && priv->window->opaque_region != NULL)
     {
@@ -1854,12 +1881,12 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self)
        */
       opaque_region = cairo_region_copy (priv->window->opaque_region);
       cairo_region_translate (opaque_region, client_area.x, client_area.y);
-      cairo_region_intersect (opaque_region, priv->shape_region);
+      cairo_region_intersect (opaque_region, shape_region);
     }
   else if (argb32)
     opaque_region = NULL;
   else
-    opaque_region = cairo_region_reference (priv->shape_region);
+    opaque_region = cairo_region_reference (shape_region);
 
   meta_surface_actor_set_opaque_region (priv->surface, opaque_region);
   cairo_region_destroy (opaque_region);


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