Don't cancel transitions that are almost completed (and round to their final value) when we get an unrelated style change. (Bug 613888) r=bzbarsky a2.0=blocking
authorL. David Baron <dbaron@dbaron.org>
Fri, 14 Jan 2011 19:57:53 -0800
changeset 60638 ea7bedcd069cea4e676deb43e5f788447269ed04
parent 60637 4275fce7591ba790bdfb2dc069759a492c2636b4
child 60639 fe3f812af314da1e34eab655acb88326d4716516
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs613888
milestone2.0b10pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Don't cancel transitions that are almost completed (and round to their final value) when we get an unrelated style change. (Bug 613888) r=bzbarsky a2.0=blocking
layout/style/nsTransitionManager.cpp
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -583,19 +583,21 @@ nsTransitionManager::ConsiderStartingTra
   }
 
   if (nsCSSProps::kAnimTypeTable[aProperty] == eStyleAnimType_None) {
     return;
   }
 
   ElementPropertyTransition pt;
   nsStyleAnimation::Value dummyValue;
-  PRBool shouldAnimate =
+  PRBool haveValues =
     TransExtractComputedValue(aProperty, aOldStyleContext, pt.mStartValue) &&
-    TransExtractComputedValue(aProperty, aNewStyleContext, pt.mEndValue) &&
+    TransExtractComputedValue(aProperty, aNewStyleContext, pt.mEndValue);
+  PRBool shouldAnimate =
+    haveValues &&
     pt.mStartValue != pt.mEndValue &&
     // Check that we can interpolate between these values
     // (If this is ever a performance problem, we could add a
     // CanInterpolate method, but it seems fine for now.)
     nsStyleAnimation::Interpolate(aProperty, pt.mStartValue, pt.mEndValue,
                                   0.5, dummyValue);
 
   PRUint32 currentIndex = nsTArray<ElementPropertyTransition>::NoIndex;
@@ -608,23 +610,29 @@ nsTransitionManager::ConsiderStartingTra
         break;
       }
     }
   }
 
   nsPresContext *presContext = aNewStyleContext->PresContext();
 
   if (!shouldAnimate) {
-    if (currentIndex != nsTArray<ElementPropertyTransition>::NoIndex) {
+    nsTArray<ElementPropertyTransition> &pts =
+      aElementTransitions->mPropertyTransitions;
+    if (currentIndex != nsTArray<ElementPropertyTransition>::NoIndex &&
+        (!haveValues || pts[currentIndex].mEndValue != pt.mEndValue)) {
       // We're in the middle of a transition, but just got a
       // non-transition style change changing to exactly the
       // current in-progress value.   (This is quite easy to cause
       // using 'transition-delay'.)
-      nsTArray<ElementPropertyTransition> &pts =
-        aElementTransitions->mPropertyTransitions;
+      //
+      // We also check that this current in-progress value is different
+      // from the end value; we don't want to cancel a transition that
+      // is almost done (and whose current value rounds to its end
+      // value) just because we got an unrelated style change.
       pts.RemoveElementAt(currentIndex);
       if (pts.IsEmpty()) {
         aElementTransitions->Destroy();
         // |aElementTransitions| is now a dangling pointer!
         aElementTransitions = nsnull;
       }
       // WalkTransitionRule already called RestyleForAnimation.
     }