60 lines
2.4 KiB
Diff
60 lines
2.4 KiB
Diff
From f820bb35067f1e6b54d56f7652ee333ac8c8c35b Mon Sep 17 00:00:00 2001
|
|
From: Carlos Garnacho <carlosg@gnome.org>
|
|
Date: Wed, 30 Mar 2022 21:02:18 +0200
|
|
Subject: [PATCH 2/2] clutter: Keep actors dirty if a redraw was queued up
|
|
during paint()
|
|
|
|
In the right combination of circumstances, and given 2 actors (parent
|
|
actor P with an offscreen effect and child actor C), we may have the
|
|
following situation happening:
|
|
|
|
- A redraw is queued on the actor C, actors C and P are marked as
|
|
priv->is_dirty and priv->propagated_one_redraw.
|
|
- During paint() handling we paint actor P, priv->propagated_one_redraw
|
|
is turned off.
|
|
- We recurse into child actor C, priv->propagated_one_redraw is turned
|
|
off.
|
|
- A new redraw is queued on actor C, actors C and P are marked as
|
|
priv->is_dirty and priv->propagated_one_redraw.
|
|
- The paint() method recurses back, actors C and P get priv->is_dirty
|
|
disabled, priv->propagated_one_redraw remains set.
|
|
- At this point queueing up more redraws on actor C will not propagate
|
|
up, because actor C has priv->propagated_one_redraw set, but the
|
|
parent actor P has priv->is_dirty unset, so the offscreen effect will
|
|
not get CLUTTER_EFFECT_PAINT_ACTOR_DIRTY and will avoid repainting
|
|
actor C.
|
|
|
|
The end result is that actor C does not redraw again, despite requesting
|
|
redraws. This situation eventually resolves itself through e.g. relayouts
|
|
on actor P, but may take some time to happen.
|
|
|
|
In order to fix this, consider actors that did get a further redraw
|
|
request still dirty after paint().
|
|
|
|
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2188
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2353>
|
|
---
|
|
clutter/clutter/clutter-actor.c | 6 ++++--
|
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
|
|
index 2e4b30effc..23ef03dc1f 100644
|
|
--- a/clutter/clutter/clutter-actor.c
|
|
+++ b/clutter/clutter/clutter-actor.c
|
|
@@ -3840,8 +3840,10 @@ clutter_actor_paint (ClutterActor *self,
|
|
clutter_paint_node_paint (root_node, paint_context);
|
|
|
|
/* If we make it here then the actor has run through a complete
|
|
- paint run including all the effects so it's no longer dirty */
|
|
- priv->is_dirty = FALSE;
|
|
+ * paint run including all the effects so it's no longer dirty,
|
|
+ * unless a new redraw was queued up.
|
|
+ */
|
|
+ priv->is_dirty = priv->propagated_one_redraw;
|
|
}
|
|
|
|
/**
|
|
--
|
|
2.35.1
|
|
|