Bug 1343753 - Part 4: Introduce AnimationValue::IsInterpolableWith. draft
authorBoris Chiou <boris.chiou@gmail.com>
Wed, 12 Apr 2017 16:26:59 +0800
changeset 561126 5372efd7341b75961ded0ac56e81015d1d7fa9b8
parent 561125 e8fd2bcb0b849735014835603f832964a8edfc8a
child 561127 bea62c1372c2c5b434feb356570ec2bcd12f1d1d
push id53643
push userbmo:boris.chiou@gmail.com
push dateWed, 12 Apr 2017 08:51:47 +0000
bugs1343753
milestone55.0a1
Bug 1343753 - Part 4: Introduce AnimationValue::IsInterpolableWith. We have different interpolation implementations on Gecko and Servo, so wrap the "Can be Interpolated" in AnimationValue. This patch also introduces the FFI, Servo_Animationvalues_IsInterpolable. MozReview-Commit-ID: 92Yf1u84A3c
layout/style/ServoBindingList.h
layout/style/StyleAnimationValue.cpp
layout/style/StyleAnimationValue.h
layout/style/nsTransitionManager.cpp
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -145,16 +145,19 @@ SERVO_BINDING_FUNC(Servo_ComputedValues_
                    nsCSSPropertyID property)
 
 // AnimationValues handling
 SERVO_BINDING_FUNC(Servo_AnimationValues_Interpolate,
                    RawServoAnimationValueStrong,
                    RawServoAnimationValueBorrowed from,
                    RawServoAnimationValueBorrowed to,
                    double progress)
+SERVO_BINDING_FUNC(Servo_AnimationValues_IsInterpolable, bool,
+                   RawServoAnimationValueBorrowed from,
+                   RawServoAnimationValueBorrowed to)
 SERVO_BINDING_FUNC(Servo_AnimationValue_Serialize, void,
                    RawServoAnimationValueBorrowed value,
                    nsCSSPropertyID property,
                    nsAString* buffer)
 SERVO_BINDING_FUNC(Servo_AnimationValue_GetOpacity, float,
                    RawServoAnimationValueBorrowed value)
 SERVO_BINDING_FUNC(Servo_AnimationValue_GetTransform, void,
                    RawServoAnimationValueBorrowed value,
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -5244,8 +5244,32 @@ AnimationValue::SerializeSpecifiedValue(
     Servo_AnimationValue_Serialize(mServo, aProperty, &aString);
     return;
   }
 
   DebugOnly<bool> uncomputeResult =
     StyleAnimationValue::UncomputeValue(aProperty, mGecko, aString);
   MOZ_ASSERT(uncomputeResult, "failed to uncompute StyleAnimationValue");
 }
+
+bool
+AnimationValue::IsInterpolableWith(nsCSSPropertyID aProperty,
+                                   const AnimationValue& aToValue) const
+{
+  if (IsNull() || aToValue.IsNull()) {
+    return false;
+  }
+
+  MOZ_ASSERT(!mServo != mGecko.IsNull());
+  MOZ_ASSERT(mGecko.IsNull() == aToValue.mGecko.IsNull() &&
+             !mServo == !aToValue.mServo,
+             "Animation values should have the same style engine");
+
+  if (mServo) {
+    return Servo_AnimationValues_IsInterpolable(mServo, aToValue.mServo);
+  }
+
+  // If this is ever a performance problem, we could add a
+  // StyleAnimationValue::IsInterpolatable method, but it seems fine for now.
+  StyleAnimationValue dummy;
+  return StyleAnimationValue::Interpolate(
+           aProperty, mGecko, aToValue.mGecko, 0.5, dummy);
+}
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -587,16 +587,20 @@ struct AnimationValue
 
   // Returns the scale for mGecko or mServo, which are calculated with
   // reference to aFrame.
   gfxSize GetScaleValue(const nsIFrame* aFrame) const;
 
   // Uncompute this AnimationValue and then serialize it.
   void SerializeSpecifiedValue(nsCSSPropertyID aProperty,
                                nsAString& aString) const;
+
+  // Check if |*this| and |aToValue| can be interpolated.
+  bool IsInterpolableWith(nsCSSPropertyID aProperty,
+                          const AnimationValue& aToValue) const;
 };
 
 struct PropertyStyleAnimationValuePair
 {
   nsCSSPropertyID mProperty;
   AnimationValue mValue;
 };
 } // namespace mozilla
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -815,36 +815,29 @@ nsTransitionManager::ConsiderInitiatingT
   }
 
   if (nsCSSProps::kAnimTypeTable[aProperty] == eStyleAnimType_None) {
     return;
   }
 
   dom::DocumentTimeline* timeline = aElement->OwnerDoc()->Timeline();
 
-  AnimationValue startValue, endValue, dummyValue;
+  AnimationValue startValue, endValue;
   bool haveValues =
     ExtractNonDiscreteComputedValue(aProperty, aOldStyleContext,
                                     startValue.mGecko) &&
     ExtractNonDiscreteComputedValue(aProperty, aNewStyleContext,
                                     endValue.mGecko);
 
   bool haveChange = startValue != endValue;
 
   bool shouldAnimate =
     haveValues &&
     haveChange &&
-    // 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.)
-    StyleAnimationValue::Interpolate(aProperty,
-                                     startValue.mGecko,
-                                     endValue.mGecko,
-                                     0.5,
-                                     dummyValue.mGecko);
+    startValue.IsInterpolableWith(aProperty, endValue);
 
   bool haveCurrentTransition = false;
   size_t currentIndex = nsTArray<ElementPropertyTransition>::NoIndex;
   const ElementPropertyTransition *oldPT = nullptr;
   if (aElementTransitions) {
     OwningCSSTransitionPtrArray& animations = aElementTransitions->mAnimations;
     for (size_t i = 0, i_end = animations.Length(); i < i_end; ++i) {
       if (animations[i]->TransitionProperty() == aProperty) {