Bug 1343753 - Part 2: Update GetTransitionKeyframes for stylo. draft
authorBoris Chiou <boris.chiou@gmail.com>
Wed, 12 Apr 2017 15:51:55 +0800
changeset 561124 c94ed972ac65869b4024487df7bec785df447067
parent 561123 9a8ba4e4d1206ca43137a103cbc2dc0702855415
child 561125 e8fd2bcb0b849735014835603f832964a8edfc8a
push id53643
push userbmo:boris.chiou@gmail.com
push dateWed, 12 Apr 2017 08:51:47 +0000
bugs1343753
milestone55.0a1
Bug 1343753 - Part 2: Update GetTransitionKeyframes for stylo. Use AnimationValue as arguments, and add one FFI to uncompute the value. Therefore, we can use GetTransitionKeyframes for both Gecko and Servo backends. However, there are many "mGecko"s, which will be removed later. MozReview-Commit-ID: Dg5hrDdlIWb
layout/style/ServoBindingList.h
layout/style/nsTransitionManager.cpp
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -157,16 +157,19 @@ SERVO_BINDING_FUNC(Servo_AnimationValue_
 SERVO_BINDING_FUNC(Servo_AnimationValue_GetOpacity, float,
                    RawServoAnimationValueBorrowed value)
 SERVO_BINDING_FUNC(Servo_AnimationValue_GetTransform, void,
                    RawServoAnimationValueBorrowed value,
                    RefPtr<nsCSSValueSharedList>* list)
 SERVO_BINDING_FUNC(Servo_AnimationValue_DeepEqual, bool,
                    RawServoAnimationValueBorrowed,
                    RawServoAnimationValueBorrowed)
+SERVO_BINDING_FUNC(Servo_AnimationValue_Uncompute,
+                   RawServoDeclarationBlockStrong,
+                   RawServoAnimationValueBorrowed value)
 
 // Style attribute
 SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, RawServoDeclarationBlockStrong,
                    const nsACString* data,
                    RawGeckoURLExtraData* extra_data)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_CreateEmpty,
                    RawServoDeclarationBlockStrong)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_Clone, RawServoDeclarationBlockStrong,
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -720,35 +720,41 @@ nsTransitionManager::UpdateTransitions(
   }
 
   return startedAny;
 }
 
 static Keyframe&
 AppendKeyframe(double aOffset,
                nsCSSPropertyID aProperty,
-               StyleAnimationValue&& aValue,
+               AnimationValue&& aValue,
                nsTArray<Keyframe>& aKeyframes)
 {
   Keyframe& frame = *aKeyframes.AppendElement();
   frame.mOffset.emplace(aOffset);
   PropertyValuePair& pv = *frame.mPropertyValues.AppendElement();
   pv.mProperty = aProperty;
-  DebugOnly<bool> uncomputeResult =
-    StyleAnimationValue::UncomputeValue(aProperty, Move(aValue), pv.mValue);
-  MOZ_ASSERT(uncomputeResult,
-             "Unable to get specified value from computed value");
+
+  if (aValue.mServo) {
+    pv.mServoDeclarationBlock =
+      Servo_AnimationValue_Uncompute(aValue.mServo).Consume();
+  } else {
+    DebugOnly<bool> uncomputeResult =
+      StyleAnimationValue::UncomputeValue(aProperty, Move(aValue.mGecko),
+                                          pv.mValue);
+    MOZ_ASSERT(uncomputeResult,
+               "Unable to get specified value from computed value");
+  }
   return frame;
 }
 
 static nsTArray<Keyframe>
 GetTransitionKeyframes(nsCSSPropertyID aProperty,
-                       nsStyleContext* aStyleContext,
-                       StyleAnimationValue&& aStartValue,
-                       StyleAnimationValue&& aEndValue,
+                       AnimationValue&& aStartValue,
+                       AnimationValue&& aEndValue,
                        const nsTimingFunction& aTimingFunction)
 {
   nsTArray<Keyframe> keyframes(2);
 
   Keyframe& fromFrame = AppendKeyframe(0.0, aProperty, Move(aStartValue),
                                        keyframes);
   if (aTimingFunction.mType != nsTimingFunction::Type::Linear) {
     fromFrame.mTimingFunction.emplace();
@@ -793,31 +799,36 @@ nsTransitionManager::ConsiderInitiatingT
   }
 
   if (nsCSSProps::kAnimTypeTable[aProperty] == eStyleAnimType_None) {
     return;
   }
 
   dom::DocumentTimeline* timeline = aElement->OwnerDoc()->Timeline();
 
-  StyleAnimationValue startValue, endValue, dummyValue;
+  AnimationValue startValue, endValue, dummyValue;
   bool haveValues =
-    ExtractNonDiscreteComputedValue(aProperty, aOldStyleContext, startValue) &&
-    ExtractNonDiscreteComputedValue(aProperty, aNewStyleContext, endValue);
+    ExtractNonDiscreteComputedValue(aProperty, aOldStyleContext,
+                                    startValue.mGecko) &&
+    ExtractNonDiscreteComputedValue(aProperty, aNewStyleContext,
+                                    endValue.mGecko);
 
-  bool haveChange = startValue != endValue;
+  bool haveChange = startValue.mGecko != endValue.mGecko;
 
   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, endValue,
-                                     0.5, dummyValue);
+    StyleAnimationValue::Interpolate(aProperty,
+                                     startValue.mGecko,
+                                     endValue.mGecko,
+                                     0.5,
+                                     dummyValue.mGecko);
 
   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) {
@@ -841,17 +852,18 @@ nsTransitionManager::ConsiderInitiatingT
   // there's no value change), but we need to return early here rather
   // than cancel the running transition because shouldAnimate is false!
   //
   // Likewise, if we got a style change that changed the value to the
   // endpoint of our finished transition, we also don't want to start
   // a new transition for the reasons described in
   // https://lists.w3.org/Archives/Public/www-style/2015Jan/0444.html .
   if (haveCurrentTransition && haveValues &&
-      aElementTransitions->mAnimations[currentIndex]->ToValue() == endValue) {
+      aElementTransitions->mAnimations[currentIndex]->ToValue() ==
+        endValue.mGecko) {
     // GetAnimationRule already called RestyleForAnimation.
     return;
   }
 
   if (!shouldAnimate) {
     if (haveCurrentTransition) {
       // We're in the middle of a transition, and just got a non-transition
       // style change to something that we can't animate.  This might happen
@@ -883,28 +895,28 @@ nsTransitionManager::ConsiderInitiatingT
   const nsTimingFunction &tf = aTransition.GetTimingFunction();
   float delay = aTransition.GetDelay();
   float duration = aTransition.GetDuration();
   if (duration < 0.0) {
     // The spec says a negative duration is treated as zero.
     duration = 0.0;
   }
 
-  StyleAnimationValue startForReversingTest = startValue;
+  AnimationValue startForReversingTest = startValue;
   double reversePortion = 1.0;
 
   // If the new transition reverses an existing one, we'll need to
   // handle the timing differently.
   // FIXME: Move mStartForReversingTest, mReversePortion to CSSTransition,
   //        and set the timing function on transitions as an effect-level
   //        easing (rather than keyframe-level easing). (Bug 1292001)
   if (haveCurrentTransition &&
       aElementTransitions->mAnimations[currentIndex]->HasCurrentEffect() &&
       oldPT &&
-      oldPT->mStartForReversingTest == endValue) {
+      oldPT->mStartForReversingTest == endValue.mGecko) {
     // Compute the appropriate negative transition-delay such that right
     // now we'd end up at the current position.
     double valuePortion =
       oldPT->CurrentValuePortion() * oldPT->mReversePortion +
       (1.0 - oldPT->mReversePortion);
     // A timing function with negative y1 (or y2!) might make
     // valuePortion negative.  In this case, we still want to apply our
     // reversing logic based on relative distances, not make duration
@@ -925,36 +937,36 @@ nsTransitionManager::ConsiderInitiatingT
     // function, so reduce them along with the duration, but don't
     // reduce positive delays.
     if (delay < 0.0f) {
       delay *= valuePortion;
     }
 
     duration *= valuePortion;
 
-    startForReversingTest = oldPT->ToValue();
+    startForReversingTest.mGecko = oldPT->ToValue();
     reversePortion = valuePortion;
   }
 
   TimingParams timing =
     TimingParamsFromCSSParams(duration, delay,
                               1.0 /* iteration count */,
                               dom::PlaybackDirection::Normal,
                               dom::FillMode::Backwards);
 
   // aElement is non-null here, so we emplace it directly.
   Maybe<OwningAnimationTarget> target;
   target.emplace(aElement, aNewStyleContext->GetPseudoType());
   KeyframeEffectParams effectOptions;
   RefPtr<ElementPropertyTransition> pt =
     new ElementPropertyTransition(aElement->OwnerDoc(), target, timing,
-                                  startForReversingTest, reversePortion,
+                                  startForReversingTest.mGecko, reversePortion,
                                   effectOptions);
 
-  pt->SetKeyframes(GetTransitionKeyframes(aNewStyleContext, aProperty,
+  pt->SetKeyframes(GetTransitionKeyframes(aProperty,
                                           Move(startValue), Move(endValue), tf),
                    aNewStyleContext);
 
   MOZ_ASSERT(mPresContext->RestyleManager()->IsGecko(),
              "ServoRestyleManager should not use nsTransitionManager "
              "for transitions");
 
   RefPtr<CSSTransition> animation =