iconGrid: Defer and group animation cleanup
The `reactive` property of icon actors was being restored 24 times over the course of the spring animation, all at slightly different times as each icon finished animating at different times. The problem is that toggling `reactive` on an `StWidget` incurs a style change of the `insensitive` pseudo class, and style changes would quickly queue relayouts incurring full stage reallocation. This occurred many times during a spring animation hogging the CPU and limiting the frame rate. The solution is defer and batch the cleanup for all icons until after the last icon has finished animating. This way the CPU impact of the style change and stage relayout isn't felt during the animation so the frame rate remains higher and smoother. The overall CPU usage of the animation is also reduced as the remaining relayouts are much more likely to be grouped into a single frame. Icon spring animation performance on an i7-7700: Before: 83% CPU and 47 FPS After : 78% CPU and 54 FPS which is about a 22% increase in performance per clock (FPS/CPU). https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/253
This commit is contained in:
parent
14953041cc
commit
a5e6dd52d2
@ -439,6 +439,11 @@ var IconGrid = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_animationDone() {
|
_animationDone() {
|
||||||
|
this._clonesAnimating.forEach(clone => {
|
||||||
|
clone.source.reactive = true;
|
||||||
|
clone.source.opacity = 255;
|
||||||
|
clone.destroy();
|
||||||
|
});
|
||||||
this._clonesAnimating = [];
|
this._clonesAnimating = [];
|
||||||
this.emit('animation-done');
|
this.emit('animation-done');
|
||||||
},
|
},
|
||||||
@ -559,10 +564,6 @@ var IconGrid = new Lang.Class({
|
|||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
if (isLastItem)
|
if (isLastItem)
|
||||||
this._animationDone();
|
this._animationDone();
|
||||||
|
|
||||||
actor.opacity = 255;
|
|
||||||
actor.reactive = true;
|
|
||||||
actorClone.destroy();
|
|
||||||
}};
|
}};
|
||||||
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
|
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
|
||||||
transition: 'easeInOutQuad',
|
transition: 'easeInOutQuad',
|
||||||
@ -583,12 +584,8 @@ var IconGrid = new Lang.Class({
|
|||||||
scale_x: scaleX,
|
scale_x: scaleX,
|
||||||
scale_y: scaleY,
|
scale_y: scaleY,
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
if (isLastItem) {
|
if (isLastItem)
|
||||||
this._animationDone();
|
this._animationDone();
|
||||||
this._restoreItemsOpacity();
|
|
||||||
}
|
|
||||||
actor.reactive = true;
|
|
||||||
actorClone.destroy();
|
|
||||||
}};
|
}};
|
||||||
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
|
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
|
||||||
transition: 'easeInOutQuad',
|
transition: 'easeInOutQuad',
|
||||||
@ -602,12 +599,6 @@ var IconGrid = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_restoreItemsOpacity() {
|
|
||||||
for (let index = 0; index < this._items.length; index++) {
|
|
||||||
this._items[index].actor.opacity = 255;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getAllocatedChildSizeAndSpacing(child) {
|
_getAllocatedChildSizeAndSpacing(child) {
|
||||||
let [,, natWidth, natHeight] = child.get_preferred_size();
|
let [,, natWidth, natHeight] = child.get_preferred_size();
|
||||||
let width = Math.min(this._getHItemSize(), natWidth);
|
let width = Math.min(this._getHItemSize(), natWidth);
|
||||||
|
Loading…
Reference in New Issue
Block a user