mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 18:11:05 -05:00
clutter/actor: Avoid always traversing actor tree on finish_layout
With commit 5a565b4258
, we changed
clutter_actor_finish_layout() to be not only about updating stage views,
but also take care of updating the visible_paint_volume, for that we
started doing a full tree traversal of all mapped actors.
This can be quite a performance issue, apparently especially on certain
ARM devices, where the simple tree traversal can take as long as 2ms.
This is precious time we need to paint our next frame, so lets do a bit
more work to avoid those useless traversals.
Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/2459
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2679>
This commit is contained in:
parent
261f516af4
commit
4579e86330
@ -850,6 +850,7 @@ struct _ClutterActorPrivate
|
||||
guint needs_update_stage_views : 1;
|
||||
guint clear_stage_views_needs_stage_views_changed : 1;
|
||||
guint needs_redraw : 1;
|
||||
guint needs_finish_layout : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -1511,6 +1512,7 @@ queue_update_paint_volume (ClutterActor *actor)
|
||||
{
|
||||
actor->priv->needs_paint_volume_update = TRUE;
|
||||
actor->priv->needs_visible_paint_volume_update = TRUE;
|
||||
actor->priv->needs_finish_layout = TRUE;
|
||||
actor = actor->priv->parent;
|
||||
}
|
||||
}
|
||||
@ -1530,6 +1532,19 @@ clutter_actor_real_map (ClutterActor *self)
|
||||
|
||||
if (priv->unmapped_paint_branch_counter == 0)
|
||||
{
|
||||
/* Invariant that needs_finish_layout is set all the way up to the stage
|
||||
* needs to be met.
|
||||
*/
|
||||
if (priv->needs_finish_layout)
|
||||
{
|
||||
iter = priv->parent;
|
||||
while (iter && !iter->priv->needs_finish_layout)
|
||||
{
|
||||
iter->priv->needs_finish_layout = TRUE;
|
||||
iter = iter->priv->parent;
|
||||
}
|
||||
}
|
||||
|
||||
/* Avoid the early return in clutter_actor_queue_relayout() */
|
||||
priv->needs_width_request = FALSE;
|
||||
priv->needs_height_request = FALSE;
|
||||
@ -2479,6 +2494,11 @@ absolute_geometry_changed (ClutterActor *actor)
|
||||
{
|
||||
actor->priv->needs_update_stage_views = TRUE;
|
||||
actor->priv->needs_visible_paint_volume_update = TRUE;
|
||||
|
||||
actor->priv->needs_finish_layout = TRUE;
|
||||
/* needs_finish_layout is already TRUE on the whole parent tree thanks
|
||||
* to queue_update_paint_volume() that was called by transform_changed().
|
||||
*/
|
||||
}
|
||||
|
||||
static ClutterActorTraverseVisitFlags
|
||||
@ -7566,6 +7586,7 @@ clutter_actor_init (ClutterActor *self)
|
||||
priv->needs_paint_volume_update = TRUE;
|
||||
priv->needs_visible_paint_volume_update = TRUE;
|
||||
priv->needs_update_stage_views = TRUE;
|
||||
priv->needs_finish_layout = TRUE;
|
||||
|
||||
priv->cached_width_age = 1;
|
||||
priv->cached_height_age = 1;
|
||||
@ -7700,9 +7721,17 @@ _clutter_actor_queue_redraw_full (ClutterActor *self,
|
||||
{
|
||||
if (!priv->needs_redraw)
|
||||
{
|
||||
ClutterActor *iter = self;
|
||||
|
||||
priv->needs_redraw = TRUE;
|
||||
|
||||
clutter_stage_schedule_update (CLUTTER_STAGE (stage));
|
||||
|
||||
while (iter && !iter->priv->needs_finish_layout)
|
||||
{
|
||||
iter->priv->needs_finish_layout = TRUE;
|
||||
iter = iter->priv->parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (volume)
|
||||
@ -15230,6 +15259,7 @@ clear_stage_views_cb (ClutterActor *actor,
|
||||
_clutter_actor_stop_transitions (actor);
|
||||
|
||||
actor->priv->needs_update_stage_views = TRUE;
|
||||
actor->priv->needs_finish_layout = TRUE;
|
||||
|
||||
old_stage_views = g_steal_pointer (&actor->priv->stage_views);
|
||||
|
||||
@ -15506,6 +15536,9 @@ clutter_actor_finish_layout (ClutterActor *self,
|
||||
gboolean old_visible_paint_volume_valid = FALSE;
|
||||
ClutterPaintVolume old_visible_paint_volume;
|
||||
|
||||
if (!priv->needs_finish_layout)
|
||||
return;
|
||||
|
||||
if ((!CLUTTER_ACTOR_IS_MAPPED (self) &&
|
||||
!clutter_actor_has_mapped_clones (self)) ||
|
||||
CLUTTER_ACTOR_IN_DESTRUCTION (self))
|
||||
@ -15547,6 +15580,8 @@ clutter_actor_finish_layout (ClutterActor *self,
|
||||
priv->needs_redraw = FALSE;
|
||||
}
|
||||
|
||||
priv->needs_finish_layout = FALSE;
|
||||
|
||||
for (child = priv->first_child; child; child = child->priv->next_sibling)
|
||||
clutter_actor_finish_layout (child, use_max_scale);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user