[gnome-shell] iconGrid: Create icon clones in a separate loop
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] iconGrid: Create icon clones in a separate loop
- Date: Wed, 19 Feb 2020 15:47:37 +0000 (UTC)
commit e781e1fdba9faf6a02f8cca33e308070620266eb
Author: Daniel van Vugt <daniel van vugt canonical com>
Date: Fri Feb 14 18:24:58 2020 +0800
iconGrid: Create icon clones in a separate loop
For reasons not yet fully understood, `Main.uiGroup.add_actor` takes around
10 milliseconds to complete.
Because of this, each `actor.opacity = 0` has a good chance of falling
on a different frame. And when it does, `_opacityChangedId` also lands
on multiple different frames each incurring a separate relayout cycle.
It is this excessive number of relayouts that causes stuttering in the
icon grid animation (#2065). But it is the slowness of `uiGroup.add_actor`
that causes the number to be excessive when it should be one.
By creating the clones and adding them to `uiGroup` early, we then enable
the existing loop starting the animation to complete within a single frame.
And by completing within a single frame all the opacity changes land within
the same frame interval, thus incurring only a single relayout instead of
many.
This issue went unnoticed until 004a5e1042 (!704), after which the slow
emissions of `notify::opacity` became a more visible performance problem.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/2065
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1002
js/ui/iconGrid.js | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
---
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 19d019f4db..25cd140992 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -556,15 +556,25 @@ var IconGrid = GObject.registerClass({
}, Infinity);
let normalization = maxDist - minDist;
- for (let index = 0; index < actors.length; index++) {
- let actor = actors[index];
+ actors.forEach(actor => {
+ let clone = new Clutter.Clone({ source: actor });
+ this._clonesAnimating.push(clone);
+ Main.uiGroup.add_actor(clone);
+ });
+
+ /*
+ * ^
+ * | These need to be separate loops because Main.uiGroup.add_actor
+ * | is excessively slow if done inside the below loop and we want the
+ * | below loop to complete within one frame interval (#2065, !1002).
+ * v
+ */
+
+ this._clonesAnimating.forEach(actorClone => {
+ let actor = actorClone.source;
actor.opacity = 0;
actor.reactive = false;
- let actorClone = new Clutter.Clone({ source: actor });
- this._clonesAnimating.push(actorClone);
- Main.uiGroup.add_actor(actorClone);
-
let [width, height] = this._getAllocatedChildSizeAndSpacing(actor);
actorClone.set_size(width, height);
let scaleX = sourceScaledWidth / width;
@@ -631,7 +641,7 @@ var IconGrid = GObject.registerClass({
actorClone.ease(movementParams);
actorClone.ease(fadeParams);
- }
+ });
}
_getAllocatedChildSizeAndSpacing(child) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]