clutter/actor: Cache the visible paint volume
If no actors have changed their positions and we're only repainting because a window needs a repaint, the paint volumes of all actors remain unchanged. There is no reason to redo those paint volumes on every stage update. So introduce caching and invalidation logic for the visible_paint_volume that allows us to avoid a ton of matrix multiplications that right now are happening for the whole mapped actor tree on every redraw. Note that this removes two places where the visible paint volume is set to an empty paint volume: This is a compromise so that we can keep around the cached pv when hiding and showing an actor, it does "regress" one case though: When hiding -> moving -> showing an actor, we'll now include the old paint volume of the actor in the redraw clip on show (even though redrawing that old region is not necessary, the actor was hidden after all). This results in a bit of overpaint in this very specific case, but for the sake of simplicity let's not care about that. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2679>
This commit is contained in:
parent
64feb2e5f0
commit
4cad96ed24
1 changed files with 17 additions and 19 deletions
|
@ -843,6 +843,7 @@ struct _ClutterActorPrivate
|
|||
guint needs_x_expand : 1;
|
||||
guint needs_y_expand : 1;
|
||||
guint needs_paint_volume_update : 1;
|
||||
guint needs_visible_paint_volume_update : 1;
|
||||
guint had_effects_on_last_paint_volume_update : 1;
|
||||
guint needs_update_stage_views : 1;
|
||||
guint clear_stage_views_needs_stage_views_changed : 1;
|
||||
|
@ -1506,6 +1507,7 @@ queue_update_paint_volume (ClutterActor *actor)
|
|||
while (actor)
|
||||
{
|
||||
actor->priv->needs_paint_volume_update = TRUE;
|
||||
actor->priv->needs_visible_paint_volume_update = TRUE;
|
||||
actor = actor->priv->parent;
|
||||
}
|
||||
}
|
||||
|
@ -1653,12 +1655,6 @@ clutter_actor_real_unmap (ClutterActor *self)
|
|||
|
||||
if (priv->unmapped_paint_branch_counter == 0)
|
||||
{
|
||||
/* clear the contents of the visible paint volume, so that hiding + moving +
|
||||
* showing will not result in the wrong area being repainted
|
||||
*/
|
||||
_clutter_paint_volume_init_static (&priv->visible_paint_volume, NULL);
|
||||
priv->visible_paint_volume_valid = TRUE;
|
||||
|
||||
if (priv->parent && !CLUTTER_ACTOR_IN_DESTRUCTION (priv->parent))
|
||||
{
|
||||
if (G_UNLIKELY (priv->parent->flags & CLUTTER_ACTOR_NO_LAYOUT))
|
||||
|
@ -2482,6 +2478,7 @@ static void
|
|||
absolute_geometry_changed (ClutterActor *actor)
|
||||
{
|
||||
actor->priv->needs_update_stage_views = TRUE;
|
||||
actor->priv->needs_visible_paint_volume_update = TRUE;
|
||||
}
|
||||
|
||||
static ClutterActorTraverseVisitFlags
|
||||
|
@ -7566,6 +7563,7 @@ clutter_actor_init (ClutterActor *self)
|
|||
priv->needs_height_request = TRUE;
|
||||
priv->needs_allocation = TRUE;
|
||||
priv->needs_paint_volume_update = TRUE;
|
||||
priv->needs_visible_paint_volume_update = TRUE;
|
||||
priv->needs_update_stage_views = TRUE;
|
||||
|
||||
priv->cached_width_age = 1;
|
||||
|
@ -7574,10 +7572,6 @@ clutter_actor_init (ClutterActor *self)
|
|||
priv->opacity_override = -1;
|
||||
priv->enable_model_view_transform = TRUE;
|
||||
|
||||
/* We're not visible yet, so the visible_paint_volume is empty */
|
||||
_clutter_paint_volume_init_static (&priv->visible_paint_volume, NULL);
|
||||
priv->visible_paint_volume_valid = TRUE;
|
||||
|
||||
priv->transform_valid = FALSE;
|
||||
|
||||
/* the default is to stretch the content, to match the
|
||||
|
@ -15474,17 +15468,21 @@ clutter_actor_finish_layout (ClutterActor *self,
|
|||
CLUTTER_ACTOR_IN_DESTRUCTION (self))
|
||||
return;
|
||||
|
||||
ensure_paint_volume (self);
|
||||
|
||||
if (priv->has_paint_volume)
|
||||
if (priv->needs_visible_paint_volume_update)
|
||||
{
|
||||
_clutter_paint_volume_copy_static (&priv->paint_volume,
|
||||
&priv->visible_paint_volume);
|
||||
_clutter_paint_volume_transform_relative (&priv->visible_paint_volume,
|
||||
NULL); /* eye coordinates */
|
||||
}
|
||||
ensure_paint_volume (self);
|
||||
|
||||
priv->visible_paint_volume_valid = priv->has_paint_volume;
|
||||
if (priv->has_paint_volume)
|
||||
{
|
||||
_clutter_paint_volume_copy_static (&priv->paint_volume,
|
||||
&priv->visible_paint_volume);
|
||||
_clutter_paint_volume_transform_relative (&priv->visible_paint_volume,
|
||||
NULL); /* eye coordinates */
|
||||
}
|
||||
|
||||
priv->visible_paint_volume_valid = priv->has_paint_volume;
|
||||
priv->needs_visible_paint_volume_update = FALSE;
|
||||
}
|
||||
|
||||
if (priv->needs_update_stage_views)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue