[mutter] clutter/actor: Use the new shallow relayout API



commit 2731be6929ca8b14e3b0ddf5fd2aebce722b5664
Author: Daniel van Vugt <daniel van vugt canonical com>
Date:   Fri May 10 16:06:18 2019 +0800

    clutter/actor: Use the new shallow relayout API
    
    If an actor sets flag `CLUTTER_ACTOR_NO_LAYOUT` then that means it
    is (or should be) unaffected by `queue_relayout` calls in its children.
    So we can avoid propagating `queue_relayout` all the way up to the stage
    and avoid a full stage relayout each time.
    
    But those children whose parent has `CLUTTER_ACTOR_NO_LAYOUT` still need
    to be allocated at some point. So we do it at the same point where it
    happened before. Only we now queue a *shallow* relayout so the `allocate`
    run on the next frame doesn't need to descend the whole actor tree anymore.
    Only a subtree and hopefully very small.
    
    For free-floating and top-level actors this provides a measurable
    performance benefit. According to Google Profiler, calls to
    `_clutter_stage_maybe_relayout` are now so cheap that they no longer show
    up in performance profiles.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/575

 clutter/clutter/clutter-actor.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index d711f0607..ebbd5303e 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -1778,6 +1778,15 @@ clutter_actor_unmap (ClutterActor *self)
   clutter_actor_update_map_state (self, MAP_STATE_MAKE_UNMAPPED);
 }
 
+static void
+clutter_actor_queue_shallow_relayout (ClutterActor *self)
+{
+  ClutterActor *stage = _clutter_actor_get_stage_internal (self);
+
+  if (stage != NULL)
+    clutter_stage_queue_actor_relayout (CLUTTER_STAGE (stage), self);
+}
+
 static void
 clutter_actor_real_show (ClutterActor *self)
 {
@@ -1811,6 +1820,11 @@ clutter_actor_real_show (ClutterActor *self)
 
       clutter_actor_queue_relayout (self);
     }
+  else  /* but still don't leave the actor un-allocated before showing it */
+    {
+      clutter_actor_queue_shallow_relayout (self);
+      clutter_actor_queue_redraw (self);
+    }
 }
 
 static inline void
@@ -2864,9 +2878,23 @@ clutter_actor_real_queue_relayout (ClutterActor *self)
   memset (priv->height_requests, 0,
           N_CACHED_SIZE_REQUESTS * sizeof (SizeRequest));
 
-  /* We need to go all the way up the hierarchy */
+  /* We may need to go all the way up the hierarchy */
   if (priv->parent != NULL)
-    _clutter_actor_queue_only_relayout (priv->parent);
+    {
+      if (priv->parent->flags & CLUTTER_ACTOR_NO_LAYOUT)
+        {
+          clutter_actor_queue_shallow_relayout (self);
+
+          /* The above might have invalidated the parent's paint volume if self
+           * has moved or resized. DnD seems to require this...
+           */
+          priv->parent->priv->needs_paint_volume_update = TRUE;
+        }
+      else
+        {
+          _clutter_actor_queue_only_relayout (priv->parent);
+        }
+    }
 }
 
 /**


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