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
This commit is contained in:
parent
12de4e67f8
commit
e781e1fdba
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user