Bug 589114 - Use frame scheduling for animated Fullscreen toolbar hiding. r=dietrich
authorDão Gottwald <dao@mozilla.com>
Fri, 06 Jan 2012 20:03:57 +0100
changeset 85225 2843998a1579174c158432e02700695a21238c54
parent 85224 840ffcc76aa3935e813a3def527ebae63b543775
child 85226 1a4ef8ec3f5af2a2dbd2259aee2f03fb42e2654f
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdietrich
bugs589114
milestone12.0a1
Bug 589114 - Use frame scheduling for animated Fullscreen toolbar hiding. r=dietrich
browser/base/content/browser.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3900,17 +3900,18 @@ var FullScreen = {
       this._shouldAnimate = !document.mozFullScreen;
       this.mouseoverToggle(false);
 
       // Autohide prefs
       gPrefService.addObserver("browser.fullscreen", this, false);
     }
     else {
       // The user may quit fullscreen during an animation
-      clearInterval(this._animationInterval);
+      window.mozCancelAnimationFrame(this._animationHandle);
+      this._animationHandle = 0;
       clearTimeout(this._animationTimeout);
       gNavToolbox.style.marginTop = "";
       if (this._isChromeCollapsed)
         this.mouseoverToggle(true);
       this._isAnimating = false;
       // This is needed if they use the context menu to quit fullscreen
       this._isPopupOpen = false;
 
@@ -4091,43 +4092,50 @@ var FullScreen = {
   setAutohide: function()
   {
     gPrefService.setBoolPref("browser.fullscreen.autohide", !gPrefService.getBoolPref("browser.fullscreen.autohide"));
   },
 
   // Animate the toolbars disappearing
   _shouldAnimate: true,
   _isAnimating: false,
-  _animationTimeout: null,
-  _animationInterval: null,
-  _animateUp: function()
-  {
+  _animationTimeout: 0,
+  _animationHandle: 0,
+  _animateUp: function() {
     // check again, the user may have done something before the animation was due to start
-    if (!window.fullScreen || !FullScreen._safeToCollapse(false)) {
-      FullScreen._isAnimating = false;
-      FullScreen._shouldAnimate = true;
+    if (!window.fullScreen || !this._safeToCollapse(false)) {
+      this._isAnimating = false;
+      this._shouldAnimate = true;
       return;
     }
 
-    var animateFrameAmount = 2;
-    function animateUpFrame() {
-      animateFrameAmount *= 2;
-      if (animateFrameAmount >= gNavToolbox.boxObject.height) {
-        // We've animated enough
-        clearInterval(FullScreen._animationInterval);
-        gNavToolbox.style.marginTop = "";
-        FullScreen._isAnimating = false;
-        FullScreen._shouldAnimate = false; // Just to make sure
-        FullScreen.mouseoverToggle(false);
-        return;
-      }
-      gNavToolbox.style.marginTop = (animateFrameAmount * -1) + "px";
-    }
-
-    FullScreen._animationInterval = setInterval(animateUpFrame, 70);
+    this._animateStartTime = window.mozAnimationStartTime;
+    if (!this._animationHandle)
+      this._animationHandle = window.mozRequestAnimationFrame(this);
+  },
+
+  sample: function (timeStamp) {
+    const duration = 1500;
+    const timePassed = timeStamp - this._animateStartTime;
+    const pos = timePassed >= duration ? 1 :
+                1 - Math.pow(1 - timePassed / duration, 4);
+
+    if (pos >= 1) {
+      // We've animated enough
+      window.mozCancelAnimationFrame(this._animationHandle);
+      gNavToolbox.style.marginTop = "";
+      this._animationHandle = 0;
+      this._isAnimating = false;
+      this._shouldAnimate = false; // Just to make sure
+      this.mouseoverToggle(false);
+      return;
+    }
+
+    gNavToolbox.style.marginTop = (gNavToolbox.boxObject.height * pos * -1) + "px";
+    this._animationHandle = window.mozRequestAnimationFrame(this);
   },
 
   cancelWarning: function(event) {
     if (!this.warningBox) {
       return;
     }
     if (this.onWarningHidden) {
       this.warningBox.removeEventListener("transitionend", this.onWarningHidden, false);
@@ -4218,17 +4226,17 @@ var FullScreen = {
     // 1 - animate only for first collapse after entering fullscreen (default for perf's sake)
     // 2 - animate every time it collapses
     if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 0)
       this._shouldAnimate = false;
 
     if (!aShow && this._shouldAnimate) {
       this._isAnimating = true;
       this._shouldAnimate = false;
-      this._animationTimeout = setTimeout(this._animateUp, 800);
+      this._animationTimeout = setTimeout(this._animateUp.bind(this), 800);
       return;
     }
 
     // The chrome is collapsed so don't spam needless mousemove events
     if (aShow) {
       gBrowser.mPanelContainer.addEventListener("mousemove",
                                                 this._collapseCallback, false);
     }