[mutter/wip/surface-content: 2/6] cullable: Reset the culling state instead of skipping the traversal



commit 7256edeb9ae6aef718a283458f4d8ce19e0190e1
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Feb 5 13:20:18 2014 -0500

    cullable: Reset the culling state instead of skipping the traversal
    
    When we traversed down to reset the culling state, previously we
    would just skip any actors that wanted culling. In order to properly
    reset the unobscured_region before painting, we need to traverse down
    to these places as well. Do this by calling cull_out with NULL regions
    for both arguments, and adapt existing cull_out implementations to
    match.

 src/compositor/meta-cullable.c             |   40 +++++++++++++++++----------
 src/compositor/meta-shaped-texture.c       |    6 +++-
 src/compositor/meta-window-actor-private.h |    3 --
 src/compositor/meta-window-actor.c         |   16 +++++++---
 src/compositor/meta-window-group.c         |   12 --------
 5 files changed, 40 insertions(+), 37 deletions(-)
---
diff --git a/src/compositor/meta-cullable.c b/src/compositor/meta-cullable.c
index 5eb1902..c5d94ea 100644
--- a/src/compositor/meta-cullable.c
+++ b/src/compositor/meta-cullable.c
@@ -70,10 +70,16 @@ meta_cullable_cull_out_children (MetaCullable   *cullable,
   while (clutter_actor_iter_prev (&iter, &child))
     {
       float x, y;
+      gboolean wants_culling;
 
-      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
+      if (!META_IS_CULLABLE (child))
         continue;
 
+      wants_culling = (unobscured_region != NULL && clip_region != NULL);
+
+      if (wants_culling && !CLUTTER_ACTOR_IS_VISIBLE (child))
+        wants_culling = FALSE;
+
       /* If an actor has effects applied, then that can change the area
        * it paints and the opacity, so we no longer can figure out what
        * portion of the actor is obscured and what portion of the screen
@@ -90,25 +96,29 @@ meta_cullable_cull_out_children (MetaCullable   *cullable,
        * as well for the same reason, but omitted for simplicity in the
        * hopes that no-one will do that.
        */
-      if (clutter_actor_has_effects (child))
-        continue;
+      if (wants_culling && clutter_actor_has_effects (child))
+        wants_culling = FALSE;
 
-      if (!META_IS_CULLABLE (child))
-        continue;
-
-      if (!meta_actor_is_untransformed (child, NULL, NULL))
-        continue;
+      if (wants_culling && !meta_actor_is_untransformed (child, NULL, NULL))
+        wants_culling = FALSE;
 
-      clutter_actor_get_position (child, &x, &y);
+      if (wants_culling)
+        {
+          clutter_actor_get_position (child, &x, &y);
 
-      /* Temporarily move to the coordinate system of the actor */
-      cairo_region_translate (unobscured_region, - x, - y);
-      cairo_region_translate (clip_region, - x, - y);
+          /* Temporarily move to the coordinate system of the actor */
+          cairo_region_translate (unobscured_region, - x, - y);
+          cairo_region_translate (clip_region, - x, - y);
 
-      meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region);
+          meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region);
 
-      cairo_region_translate (unobscured_region, x, y);
-      cairo_region_translate (clip_region, x, y);
+          cairo_region_translate (unobscured_region, x, y);
+          cairo_region_translate (clip_region, x, y);
+        }
+      else
+        {
+          meta_cullable_cull_out (META_CULLABLE (child), NULL, NULL);
+        }
     }
 }
 
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index bc7f95b..4cbd75c 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -916,8 +916,10 @@ meta_shaped_texture_cull_out (MetaCullable   *cullable,
     {
       if (priv->opaque_region)
         {
-          cairo_region_subtract (unobscured_region, priv->opaque_region);
-          cairo_region_subtract (clip_region, priv->opaque_region);
+          if (unobscured_region)
+            cairo_region_subtract (unobscured_region, priv->opaque_region);
+          if (clip_region)
+            cairo_region_subtract (clip_region, priv->opaque_region);
         }
     }
 }
diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
index 0207a88..9c6a847 100644
--- a/src/compositor/meta-window-actor-private.h
+++ b/src/compositor/meta-window-actor-private.h
@@ -59,9 +59,6 @@ void     meta_window_actor_set_updates_frozen  (MetaWindowActor *self,
 void     meta_window_actor_queue_frame_drawn   (MetaWindowActor *self,
                                                 gboolean         no_delay_frame);
 
-void meta_window_actor_set_unobscured_region      (MetaWindowActor *self,
-                                                   cairo_region_t  *unobscured_region);
-
 void meta_window_actor_effect_completed (MetaWindowActor *actor,
                                          gulong           event);
 
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 609a58f..68295f5 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -1708,7 +1708,7 @@ see_region (cairo_region_t *region,
  * Provides a hint as to what areas of the window need to queue
  * redraws when damaged. Regions not in @unobscured_region are completely obscured.
  */
-void
+static void
 meta_window_actor_set_unobscured_region (MetaWindowActor *self,
                                          cairo_region_t  *unobscured_region)
 {
@@ -1745,13 +1745,19 @@ meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
   if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow)
     {
       g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
-      priv->shadow_clip = cairo_region_copy (beneath_region);
 
-      if (clip_shadow_under_window (self))
+      if (beneath_region)
         {
-          cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window);
-          cairo_region_subtract (priv->shadow_clip, frame_bounds);
+          priv->shadow_clip = cairo_region_copy (beneath_region);
+
+          if (clip_shadow_under_window (self))
+            {
+              cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window);
+              cairo_region_subtract (priv->shadow_clip, frame_bounds);
+            }
         }
+      else
+        priv->shadow_clip = NULL;
     }
 }
 
diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c
index a36d596..1e1b72f 100644
--- a/src/compositor/meta-window-group.c
+++ b/src/compositor/meta-window-group.c
@@ -125,18 +125,6 @@ meta_window_group_paint (ClutterActor *actor)
   MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
   ClutterActor *stage = clutter_actor_get_stage (actor);
 
-  /* Start off by treating all windows as completely unobscured, so damage anywhere
-   * in a window queues redraws, but confine it more below. */
-  clutter_actor_iter_init (&iter, actor);
-  while (clutter_actor_iter_next (&iter, &child))
-    {
-      if (META_IS_WINDOW_ACTOR (child))
-        {
-          MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
-          meta_window_actor_set_unobscured_region (window_actor, NULL);
-        }
-    }
-
   /* Normally we expect an actor to be drawn at it's position on the screen.
    * However, if we're inside the paint of a ClutterClone, that won't be the
    * case and we need to compensate. We look at the position of the window


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