[mutter] clutter/actor: Don't traverse whole actor tree for updating stage-views
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] clutter/actor: Don't traverse whole actor tree for updating stage-views
- Date: Tue, 9 Jun 2020 16:45:53 +0000 (UTC)
commit 0f97196d84c038562fe3c8d11f9ef0e7593c412c
Author: Jonas Dreßler <verdre v0yd nl>
Date: Fri Apr 10 01:19:00 2020 +0200
clutter/actor: Don't traverse whole actor tree for updating stage-views
We currently go through the whole tree of mapped actors on every paint
cycle to update the stage views actors are on. Even if no actors need
updating of their stage views, traversing the actor tree is still quite
expensive and shows up when using a profiler.
So tone down the amounts of full-tree traversals we have to do on every
paint cycle and only traverse a subtree if it includes an actor which
actually needs updating of its stage views.
We do that by setting the `needs_update_stage_views` flag to TRUE
recursively for all parents up to the stage when the stage-views list of
an actor gets invalidated. This way we end up updating a few more actors
than necessary, but can avoid searching the whole actor tree for actors
which have `needs_update_stage_views` set to TRUE.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1196
clutter/clutter/clutter-actor.c | 40 ++++++++++++++++++++++++++++++++++------
1 file changed, 34 insertions(+), 6 deletions(-)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index dd7b1ba740..fe02d3abdd 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -1618,6 +1618,22 @@ clutter_actor_update_map_state (ClutterActor *self,
#endif
}
+static void
+queue_update_stage_views (ClutterActor *actor)
+{
+ while (actor && !actor->priv->needs_update_stage_views)
+ {
+ actor->priv->needs_update_stage_views = TRUE;
+
+ /* We don't really need to update the stage-views of the actors up the
+ * hierarchy, we set the flag anyway though so we can avoid traversing
+ * the whole scenegraph when looking for actors which need an update
+ * in clutter_actor_update_stage_views().
+ */
+ actor = actor->priv->parent;
+ }
+}
+
static void
clutter_actor_real_map (ClutterActor *self)
{
@@ -1632,6 +1648,18 @@ clutter_actor_real_map (ClutterActor *self)
self->priv->needs_paint_volume_update = TRUE;
+ /* We skip unmapped actors when updating the stage-views list, so if
+ * an actors list got invalidated while it was unmapped make sure to
+ * set priv->needs_update_stage_views to TRUE for all actors up the
+ * hierarchy now.
+ */
+ if (self->priv->needs_update_stage_views)
+ {
+ /* Avoid the early return in queue_update_stage_views() */
+ self->priv->needs_update_stage_views = FALSE;
+ queue_update_stage_views (self);
+ }
+
clutter_actor_ensure_resource_scale (self);
/* notify on parent mapped before potentially mapping
@@ -2569,7 +2597,7 @@ static void
absolute_allocation_changed (ClutterActor *actor)
{
actor->priv->needs_compute_resource_scale = TRUE;
- actor->priv->needs_update_stage_views = TRUE;
+ queue_update_stage_views (actor);
}
static ClutterActorTraverseVisitFlags
@@ -17748,12 +17776,12 @@ clutter_actor_update_stage_views (ClutterActor *self)
CLUTTER_ACTOR_IN_DESTRUCTION (self))
return;
- if (priv->needs_update_stage_views)
- {
- update_stage_views (self);
+ if (!priv->needs_update_stage_views)
+ return;
- priv->needs_update_stage_views = FALSE;
- }
+ update_stage_views (self);
+
+ priv->needs_update_stage_views = FALSE;
for (child = priv->first_child; child; child = child->priv->next_sibling)
clutter_actor_update_stage_views (child);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]