Bug 1340005 - Part 5: Implement SampleValue for Servo backend. draft
authorBoris Chiou <boris.chiou@gmail.com>
Fri, 27 Oct 2017 21:09:11 +0200
changeset 687790 51351e4877f110d86c4e2eb7e37cc3ada8f96f8f
parent 687789 f8345ee25f6b61cbc2c51d9558d7ce37220f1c79
child 687791 5fde0912aee04c4f2d3d5d3bf31c140d9b0957cc
push id86604
push userbmo:boris.chiou@gmail.com
push dateFri, 27 Oct 2017 19:27:11 +0000
bugs1340005
milestone58.0a1
Bug 1340005 - Part 5: Implement SampleValue for Servo backend. Use the new added FFI, Servo_ComposeAnimationSegment, to compose an animation segment from Servo backend on the compositor. MozReview-Commit-ID: LNgpCSIlDl9
gfx/layers/AnimationHelper.cpp
layout/style/ServoBindingList.h
--- a/gfx/layers/AnimationHelper.cpp
+++ b/gfx/layers/AnimationHelper.cpp
@@ -13,21 +13,16 @@
 #include "mozilla/layers/LayerAnimationUtils.h" // for TimingFunctionToComputedTimingFunction
 #include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
 #include "nsDeviceContext.h"            // for AppUnitsPerCSSPixel
 #include "nsDisplayList.h"              // for nsDisplayTransform, etc
 
 namespace mozilla {
 namespace layers {
 
-struct StyleAnimationValueCompositePair {
-  StyleAnimationValue mValue;
-  dom::CompositeOperation mComposite;
-};
-
 void
 CompositorAnimationStorage::Clear()
 {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
 
   mAnimatedValues.Clear();
   mAnimations.Clear();
 }
@@ -134,36 +129,37 @@ CompositorAnimationStorage::SetAnimation
 {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   AnimationArray* value = new AnimationArray(aValue);
   mAnimations.Put(aId, value);
 }
 
 static StyleAnimationValue
 SampleValue(double aPortion, const layers::Animation& aAnimation,
-            const StyleAnimationValueCompositePair& aStart,
-            const StyleAnimationValueCompositePair& aEnd,
+            const AnimationPropertySegment&& aSegment,
             const StyleAnimationValue& aLastValue,
             uint64_t aCurrentIteration,
             const StyleAnimationValue& aUnderlyingValue)
 {
-  NS_ASSERTION(aStart.mValue.IsNull() || aEnd.mValue.IsNull() ||
-               aStart.mValue.GetUnit() == aEnd.mValue.GetUnit(),
+  NS_ASSERTION(aSegment.mFromValue.mGecko.IsNull() ||
+               aSegment.mToValue.mGecko.IsNull() ||
+               aSegment.mFromValue.mGecko.GetUnit() ==
+                 aSegment.mToValue.mGecko.GetUnit(),
                "Must have same unit");
 
   StyleAnimationValue startValue =
     dom::KeyframeEffectReadOnly::CompositeValue(aAnimation.property(),
-                                                aStart.mValue,
+                                                aSegment.mFromValue.mGecko,
                                                 aUnderlyingValue,
-                                                aStart.mComposite);
+                                                aSegment.mFromComposite);
   StyleAnimationValue endValue =
     dom::KeyframeEffectReadOnly::CompositeValue(aAnimation.property(),
-                                                aEnd.mValue,
+                                                aSegment.mToValue.mGecko,
                                                 aUnderlyingValue,
-                                                aEnd.mComposite);
+                                                aSegment.mToComposite);
 
   // Iteration composition for accumulate
   if (static_cast<dom::IterationCompositeOperation>
         (aAnimation.iterationComposite()) ==
           dom::IterationCompositeOperation::Accumulate &&
       aCurrentIteration > 0) {
     // FIXME: Bug 1293492: Add a utility function to calculate both of
     // below StyleAnimationValues.
@@ -264,32 +260,51 @@ AnimationHelper::SampleAnimationForEachN
       (computedTiming.mProgress.Value() - segment->startPortion()) /
       (segment->endPortion() - segment->startPortion());
 
     double portion =
       ComputedTimingFunction::GetPortion(animData.mFunctions[segmentIndex],
                                          positionInSegment,
                                      computedTiming.mBeforeFlag);
 
-    StyleAnimationValueCompositePair from {
-      animData.mStartValues[segmentIndex].mGecko,
-      static_cast<dom::CompositeOperation>(segment->startComposite())
-    };
-    StyleAnimationValueCompositePair to {
-      animData.mEndValues[segmentIndex].mGecko,
-      static_cast<dom::CompositeOperation>(segment->endComposite())
-    };
+    AnimationPropertySegment animSegment;
+    animSegment.mFromKey = 0.0;
+    animSegment.mToKey = 1.0;
+    animSegment.mFromValue = animData.mStartValues[segmentIndex];
+    animSegment.mToValue = animData.mEndValues[segmentIndex];
+    animSegment.mFromComposite =
+      static_cast<dom::CompositeOperation>(segment->startComposite());
+    animSegment.mToComposite =
+      static_cast<dom::CompositeOperation>(segment->endComposite());
+
     // interpolate the property
-    aAnimationValue.mGecko =
-      SampleValue(portion,
-                  animation,
-                  from, to,
-                  animData.mEndValues.LastElement().mGecko,
-                  computedTiming.mCurrentIteration,
-                  aAnimationValue.mGecko);
+    bool isServo = animSegment.mFromValue.mServo ||
+                   animSegment.mToValue.mServo;
+    if (isServo) {
+      dom::IterationCompositeOperation iterCompositeOperation =
+          static_cast<dom::IterationCompositeOperation>(
+            animation.iterationComposite());
+
+      aAnimationValue.mServo =
+        Servo_ComposeAnimationSegment(
+          &animSegment,
+          aAnimationValue.mServo,
+          animData.mEndValues.LastElement().mServo,
+          iterCompositeOperation,
+          portion,
+          computedTiming.mCurrentIteration).Consume();
+    } else {
+      aAnimationValue.mGecko =
+        SampleValue(portion,
+                    animation,
+                    Move(animSegment),
+                    animData.mEndValues.LastElement().mGecko,
+                    computedTiming.mCurrentIteration,
+                    aAnimationValue.mGecko);
+    }
     aHasInEffectAnimations = true;
   }
 
 #ifdef DEBUG
   // Sanity check that all of animation data are the same.
   const AnimationData& lastData = aAnimations.LastElement().data();
   for (const Animation& animation : aAnimations) {
     const AnimationData& data = animation.data();
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -449,25 +449,41 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_RemovePropertyById, bool,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsCSSPropertyID property)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_HasCSSWideKeyword, bool,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsCSSPropertyID property)
 // Compose animation value for a given property.
 // |base_values| is nsRefPtrHashtable<nsUint32HashKey, RawServoAnimationValue>.
-// We use RawServoAnimationValueTableBorrowed to avoid exposing nsRefPtrHashtable in FFI.
+// We use RawServoAnimationValueTableBorrowed to avoid exposing
+// nsRefPtrHashtable in FFI.
 SERVO_BINDING_FUNC(Servo_AnimationCompose, void,
                    RawServoAnimationValueMapBorrowedMut animation_values,
                    RawServoAnimationValueTableBorrowed base_values,
                    nsCSSPropertyID property,
                    RawGeckoAnimationPropertySegmentBorrowed animation_segment,
                    RawGeckoAnimationPropertySegmentBorrowed last_segment,
                    RawGeckoComputedTimingBorrowed computed_timing,
-                   mozilla::dom::IterationCompositeOperation iteration_composite)
+                   mozilla::dom::IterationCompositeOperation iter_composite)
+// Calculate the result of interpolating given animation segment at the given
+// progress and current iteration.
+// This includes combining the segment endpoints with the underlying value
+// and/or last value depending the composite modes specified on the
+// segment endpoints and the supplied iteration composite mode.
+// The caller is responsible for providing an underlying value and
+// last value in all situations where there are needed.
+SERVO_BINDING_FUNC(Servo_ComposeAnimationSegment,
+                   RawServoAnimationValueStrong,
+                   RawGeckoAnimationPropertySegmentBorrowed animation_segment,
+                   RawServoAnimationValueBorrowedOrNull underlying_value,
+                   RawServoAnimationValueBorrowedOrNull last_value,
+                   mozilla::dom::IterationCompositeOperation iter_composite,
+                   double progress,
+                   uint64_t current_iteration)
 
 // presentation attributes
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_PropertyIsSet, bool,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsCSSPropertyID property)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetIdentStringValue, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsCSSPropertyID property,