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
This commit is contained in:
parent
5257c6ecc2
commit
2731be6929
@ -1778,6 +1778,15 @@ clutter_actor_unmap (ClutterActor *self)
|
|||||||
clutter_actor_update_map_state (self, MAP_STATE_MAKE_UNMAPPED);
|
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
|
static void
|
||||||
clutter_actor_real_show (ClutterActor *self)
|
clutter_actor_real_show (ClutterActor *self)
|
||||||
{
|
{
|
||||||
@ -1811,6 +1820,11 @@ clutter_actor_real_show (ClutterActor *self)
|
|||||||
|
|
||||||
clutter_actor_queue_relayout (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
|
static inline void
|
||||||
@ -2864,9 +2878,23 @@ clutter_actor_real_queue_relayout (ClutterActor *self)
|
|||||||
memset (priv->height_requests, 0,
|
memset (priv->height_requests, 0,
|
||||||
N_CACHED_SIZE_REQUESTS * sizeof (SizeRequest));
|
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)
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user