Bug 1355349 - Call Servo's add and accumulate methods for SMIL animations; r?hiro draft
authorBrian Birtles <birtles@gmail.com>
Fri, 02 Jun 2017 15:18:47 +0900
changeset 588800 0942e4068913293f2dd52f133262ab65509cad25
parent 588799 fd53d495599effbe706066a5b23a97ebbdeff0c1
child 588801 1c38f3f7b5467541d2fa5dcf78d9ae9d881b27ab
push id62159
push userbbirtles@mozilla.com
push dateMon, 05 Jun 2017 03:26:35 +0000
reviewershiro
bugs1355349
milestone55.0a1
Bug 1355349 - Call Servo's add and accumulate methods for SMIL animations; r?hiro MozReview-Commit-ID: 1vREV73V0Wo
dom/smil/nsSMILCSSValueType.cpp
dom/smil/nsSMILCSSValueType.h
--- a/dom/smil/nsSMILCSSValueType.cpp
+++ b/dom/smil/nsSMILCSSValueType.cpp
@@ -15,16 +15,17 @@
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 #include "nsColor.h"
 #include "nsPresContext.h"
 #include "mozilla/Keyframe.h" // For PropertyValuePair
 #include "mozilla/ServoBindings.h"
 #include "mozilla/StyleAnimationValue.h" // For AnimationValue
 #include "mozilla/StyleSetHandleInlines.h"
+#include "mozilla/dom/BaseKeyframeTypesBinding.h" // For CompositeOperation
 #include "mozilla/dom/Element.h"
 #include "nsDebug.h"
 #include "nsStyleUtil.h"
 #include "nsIDocument.h"
 
 using namespace mozilla::dom;
 using mozilla::StyleAnimationValue;
 
@@ -242,70 +243,108 @@ nsSMILCSSValueType::IsEqual(const nsSMIL
   if (rightWrapper) {
     // Left null, right non-null
     return false;
   }
   // Both null
   return true;
 }
 
-nsresult
-nsSMILCSSValueType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
-                        uint32_t aCount) const
+static bool
+AddOrAccumulate(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
+                CompositeOperation aCompositeOp, uint64_t aCount)
 {
   MOZ_ASSERT(aValueToAdd.mType == aDest.mType,
-             "Trying to add invalid types");
-  MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
+             "Trying to add mismatching types");
+  MOZ_ASSERT(aValueToAdd.mType == &nsSMILCSSValueType::sSingleton,
+             "Unexpected SMIL value type");
+  MOZ_ASSERT(aCompositeOp == CompositeOperation::Add ||
+             aCompositeOp == CompositeOperation::Accumulate,
+             "Composite operation should be add or accumulate");
+  MOZ_ASSERT(aCompositeOp != CompositeOperation::Add || aCount == 1,
+             "Count should be 1 if composite operation is add");
 
   ValueWrapper* destWrapper = ExtractValueWrapper(aDest);
   const ValueWrapper* valueToAddWrapper = ExtractValueWrapper(aValueToAdd);
   MOZ_ASSERT(destWrapper || valueToAddWrapper,
              "need at least one fully-initialized value");
 
   nsCSSPropertyID property = valueToAddWrapper
                              ? valueToAddWrapper->mPropID
                              : destWrapper->mPropID;
   // Special case: font-size-adjust and stroke-dasharray are explicitly
   // non-additive (even though StyleAnimationValue *could* support adding them)
   if (property == eCSSProperty_font_size_adjust ||
       property == eCSSProperty_stroke_dasharray) {
-    return NS_ERROR_FAILURE;
+    return false;
   }
 
   const AnimationValue* valueToAdd = valueToAddWrapper
                                      ? &valueToAddWrapper->mCSSValue
                                      : nullptr;
   const AnimationValue* destValue = destWrapper
                                     ? &destWrapper->mCSSValue
                                     : nullptr;
   AnimationValue zeroValueStorage;
   if (!FinalizeStyleAnimationValues(valueToAdd, destValue,
                                     zeroValueStorage)) {
-    return NS_ERROR_FAILURE;
+    return false;
   }
   // Did FinalizeStyleAnimationValues change destValue?
   // If so, update outparam to use the new value.
   if (destWrapper && &destWrapper->mCSSValue != destValue) {
     destWrapper->mCSSValue = *destValue;
   }
 
   // Handle barely-initialized "zero" destination.
   if (!destWrapper) {
     aDest.mU.mPtr = destWrapper = new ValueWrapper(property, *destValue);
   }
 
-  // Bug 1355349: Implement additive animation for Stylo
   if (destWrapper->mCSSValue.mServo) {
-    NS_WARNING("stylo: Additive animation not supported yet (bug 1355349)");
-    return NS_ERROR_FAILURE;
+    RefPtr<RawServoAnimationValue> result;
+    if (aCompositeOp == CompositeOperation::Add) {
+      result = Servo_AnimationValues_Add(destWrapper->mCSSValue.mServo,
+                                         valueToAdd->mServo).Consume();
+    } else {
+      result = Servo_AnimationValues_Accumulate(destWrapper->mCSSValue.mServo,
+                                                valueToAdd->mServo,
+                                                aCount).Consume();
+    }
+
+    if (result) {
+      destWrapper->mCSSValue.mServo = result;
+    }
+    return result;
   }
 
-  return StyleAnimationValue::Add(property,
-                                  destWrapper->mCSSValue.mGecko,
-                                  valueToAdd->mGecko, aCount)
+  // For Gecko, we currently call Add for either composite mode.
+  //
+  // This is not ideal, but it doesn't make any difference for the set of
+  // properties we currently allow adding in SMIL and this code path will
+  // hopefully become obsolete before we expand that set.
+  return StyleAnimationValue::Add(property, destWrapper->mCSSValue.mGecko,
+                                  valueToAdd->mGecko, aCount);
+}
+
+nsresult
+nsSMILCSSValueType::SandwichAdd(nsSMILValue& aDest,
+                                const nsSMILValue& aValueToAdd) const
+{
+  return AddOrAccumulate(aDest, aValueToAdd, CompositeOperation::Add, 1)
+         ? NS_OK
+         : NS_ERROR_FAILURE;
+}
+
+nsresult
+nsSMILCSSValueType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
+                        uint32_t aCount) const
+{
+  return AddOrAccumulate(aDest, aValueToAdd, CompositeOperation::Accumulate,
+                         aCount)
          ? NS_OK
          : NS_ERROR_FAILURE;
 }
 
 nsresult
 nsSMILCSSValueType::ComputeDistance(const nsSMILValue& aFrom,
                                     const nsSMILValue& aTo,
                                     double& aDistance) const
--- a/dom/smil/nsSMILCSSValueType.h
+++ b/dom/smil/nsSMILCSSValueType.h
@@ -41,16 +41,18 @@ protected:
   void     Destroy(nsSMILValue&) const override;
   nsresult Assign(nsSMILValue& aDest,
                   const nsSMILValue& aSrc) const override;
   bool     IsEqual(const nsSMILValue& aLeft,
                    const nsSMILValue& aRight) const override;
   nsresult Add(nsSMILValue& aDest,
                const nsSMILValue& aValueToAdd,
                uint32_t aCount) const override;
+  nsresult SandwichAdd(nsSMILValue& aDest,
+                       const nsSMILValue& aValueToAdd) const override;
   nsresult ComputeDistance(const nsSMILValue& aFrom,
                            const nsSMILValue& aTo,
                            double& aDistance) const override;
   nsresult Interpolate(const nsSMILValue& aStartVal,
                        const nsSMILValue& aEndVal,
                        double aUnitDistance,
                        nsSMILValue& aResult) const override;