[gnome-shell] iconGrid: Defer and group animation cleanup



commit a5e6dd52d20981066ffb8e64a8537ba3a3f7044c
Author: Daniel van Vugt <daniel van vugt canonical com>
Date:   Fri Oct 5 17:09:22 2018 +0800

    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

 js/ui/iconGrid.js | 21 ++++++---------------
 1 file changed, 6 insertions(+), 15 deletions(-)
---
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index cbfeb05f4..5aff02784 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -439,6 +439,11 @@ var IconGrid = new Lang.Class({
     },
 
     _animationDone() {
+        this._clonesAnimating.forEach(clone => {
+            clone.source.reactive = true;
+            clone.source.opacity = 255;
+            clone.destroy();
+        });
         this._clonesAnimating = [];
         this.emit('animation-done');
     },
@@ -559,10 +564,6 @@ var IconGrid = new Lang.Class({
                                    onComplete: () => {
                                        if (isLastItem)
                                            this._animationDone();
-
-                                       actor.opacity = 255;
-                                       actor.reactive = true;
-                                       actorClone.destroy();
                                    }};
                 fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
                                transition: 'easeInOutQuad',
@@ -583,12 +584,8 @@ var IconGrid = new Lang.Class({
                                    scale_x: scaleX,
                                    scale_y: scaleY,
                                    onComplete: () => {
-                                       if (isLastItem) {
+                                       if (isLastItem)
                                            this._animationDone();
-                                           this._restoreItemsOpacity();
-                                       }
-                                       actor.reactive = true;
-                                       actorClone.destroy();
                                    }};
                 fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
                                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) {
         let [,, natWidth, natHeight] = child.get_preferred_size();
         let width = Math.min(this._getHItemSize(), natWidth);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]