Bug 1358966 - Make aUnitDistance for Interpolate an array. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Tue, 06 Jun 2017 12:54:57 +0900
changeset 589370 f3e0a29fc1d293ec973a8e9b7d5ae00a287e0a75
parent 589369 d6ab3ce4236442ce3845b94c2dd7c669597bb699
child 589371 92424585ccde69dba085aac6c9f618c30786a031
push id62344
push userhikezoe@mozilla.com
push dateTue, 06 Jun 2017 03:58:54 +0000
reviewersbirtles
bugs1358966
milestone55.0a1
Bug 1358966 - Make aUnitDistance for Interpolate an array. r?birtles MozReview-Commit-ID: G2JWf22UIyb
dom/smil/SMILBoolType.cpp
dom/smil/SMILBoolType.h
dom/smil/SMILEnumType.cpp
dom/smil/SMILEnumType.h
dom/smil/SMILIntegerType.cpp
dom/smil/SMILIntegerType.h
dom/smil/SMILStringType.cpp
dom/smil/SMILStringType.h
dom/smil/nsISMILType.h
dom/smil/nsSMILAnimationFunction.cpp
dom/smil/nsSMILCSSValueType.cpp
dom/smil/nsSMILCSSValueType.h
dom/smil/nsSMILFloatType.cpp
dom/smil/nsSMILFloatType.h
dom/smil/nsSMILNullType.cpp
dom/smil/nsSMILNullType.h
dom/smil/nsSMILValue.cpp
dom/smil/nsSMILValue.h
dom/svg/SVGIntegerPairSMILType.cpp
dom/svg/SVGIntegerPairSMILType.h
dom/svg/SVGLengthListSMILType.cpp
dom/svg/SVGLengthListSMILType.h
dom/svg/SVGMotionSMILType.cpp
dom/svg/SVGMotionSMILType.h
dom/svg/SVGNumberListSMILType.cpp
dom/svg/SVGNumberListSMILType.h
dom/svg/SVGNumberPairSMILType.cpp
dom/svg/SVGNumberPairSMILType.h
dom/svg/SVGOrientSMILType.cpp
dom/svg/SVGOrientSMILType.h
dom/svg/SVGPathSegListSMILType.cpp
dom/svg/SVGPathSegListSMILType.h
dom/svg/SVGPointListSMILType.cpp
dom/svg/SVGPointListSMILType.h
dom/svg/SVGTransformListSMILType.cpp
dom/svg/SVGTransformListSMILType.h
dom/svg/SVGViewBoxSMILType.cpp
dom/svg/SVGViewBoxSMILType.h
--- a/dom/smil/SMILBoolType.cpp
+++ b/dom/smil/SMILBoolType.cpp
@@ -64,17 +64,17 @@ SMILBoolType::ComputeDistance(const nsSM
   NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
   NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
   return NS_ERROR_FAILURE; // there is no concept of distance between bool values
 }
 
 nsresult
 SMILBoolType::Interpolate(const nsSMILValue& aStartVal,
                           const nsSMILValue& aEndVal,
-                          double aUnitDistance,
+                          AutoTArray<double, 1>& aUnitDistances,
                           nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
       "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
       "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType   == this, "Unexpected result type");
   return NS_ERROR_FAILURE; // bool values do not interpolate
--- a/dom/smil/SMILBoolType.h
+++ b/dom/smil/SMILBoolType.h
@@ -32,17 +32,17 @@ protected:
                        uint32_t aCount) const override;
   virtual bool IsEqual(const nsSMILValue& aLeft,
                        const nsSMILValue& aRight) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SMILBoolType() {}
 };
 
 } // namespace mozilla
--- a/dom/smil/SMILEnumType.cpp
+++ b/dom/smil/SMILEnumType.cpp
@@ -64,17 +64,17 @@ SMILEnumType::ComputeDistance(const nsSM
   NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
   NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
   return NS_ERROR_FAILURE; // there is no concept of distance between enum values
 }
 
 nsresult
 SMILEnumType::Interpolate(const nsSMILValue& aStartVal,
                           const nsSMILValue& aEndVal,
-                          double aUnitDistance,
+                          AutoTArray<double, 1>& aUnitDistances,
                           nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
       "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
       "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType   == this, "Unexpected result type");
   return NS_ERROR_FAILURE; // enum values do not interpolate
--- a/dom/smil/SMILEnumType.h
+++ b/dom/smil/SMILEnumType.h
@@ -33,17 +33,17 @@ protected:
                        const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SMILEnumType() {}
 };
 
 } // namespace mozilla
--- a/dom/smil/SMILIntegerType.cpp
+++ b/dom/smil/SMILIntegerType.cpp
@@ -67,28 +67,28 @@ SMILIntegerType::ComputeDistance(const n
   MOZ_ASSERT(aDistances.IsEmpty());
   aDistances.AppendElement(fabs(double(aTo.mU.mInt - aFrom.mU.mInt)));
   return NS_OK;
 }
 
 nsresult
 SMILIntegerType::Interpolate(const nsSMILValue& aStartVal,
                              const nsSMILValue& aEndVal,
-                             double aUnitDistance,
+                             AutoTArray<double, 1>& aUnitDistances,
                              nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
                   "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
                   "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType   == this, "Unexpected result type");
 
   const double startVal   = double(aStartVal.mU.mInt);
   const double endVal     = double(aEndVal.mU.mInt);
-  const double currentVal = startVal + (endVal - startVal) * aUnitDistance;
+  const double currentVal = startVal + (endVal - startVal) * aUnitDistances[0];
 
   // When currentVal is exactly midway between its two nearest integers, we
   // jump to the "next" integer to provide simple, easy to remember and
   // consistent behaviour (from the SMIL author's point of view).
 
   if (startVal < endVal) {
     aResult.mU.mInt = int64_t(floor(currentVal + 0.5)); // round mid up
   } else {
--- a/dom/smil/SMILIntegerType.h
+++ b/dom/smil/SMILIntegerType.h
@@ -22,17 +22,17 @@ public:
                        const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
   static SMILIntegerType*
   Singleton()
   {
     static SMILIntegerType sSingleton;
     return &sSingleton;
   }
--- a/dom/smil/SMILStringType.cpp
+++ b/dom/smil/SMILStringType.cpp
@@ -72,17 +72,17 @@ SMILStringType::ComputeDistance(const ns
   NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
   NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
   return NS_ERROR_FAILURE; // there is no concept of distance between string values
 }
 
 nsresult
 SMILStringType::Interpolate(const nsSMILValue& aStartVal,
                             const nsSMILValue& aEndVal,
-                            double aUnitDistance,
+                            AutoTArray<double, 1>& aUnitDistances,
                             nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
       "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
       "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType   == this, "Unexpected result type");
   return NS_ERROR_FAILURE; // string values do not interpolate
--- a/dom/smil/SMILStringType.h
+++ b/dom/smil/SMILStringType.h
@@ -33,17 +33,17 @@ protected:
                        const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SMILStringType() {}
 };
 
 } // namespace mozilla
--- a/dom/smil/nsISMILType.h
+++ b/dom/smil/nsISMILType.h
@@ -187,29 +187,29 @@ protected:
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const = 0;
 
   /**
    * Calculates an interpolated value between two values using the specified
    * proportion.
    *
-   * @param   aStartVal     The value defining the start of the interval of
-   *                        interpolation.
-   * @param   aEndVal       The value defining the end of the interval of
-   *                        interpolation.
-   * @param   aUnitDistance A number between 0.0 and 1.0 (inclusive) defining
-   *                        the distance of the interpolated value in the
-   *                        interval.
-   * @param   aResult       The interpolated value.
+   * @param   aStartVal      The value defining the start of the interval of
+   *                         interpolation.
+   * @param   aEndVal        The value defining the end of the interval of
+   *                         interpolation.
+   * @param   aUnitDistances Numbers between 0.0 and 1.0 (inclusive) defining
+   *                         the distance of the interpolated value in the
+   *                         interval.
+   * @param   aResult        The interpolated value.
    * @return  NS_OK on success, NS_ERROR_FAILURE if this data type cannot be
    *          interpolated or NS_ERROR_OUT_OF_MEMORY if insufficient memory was
    *          available for storing the result.
    *
    * @pre aStartVal.mType == aEndVal.mType == aResult.mType == this
    */
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double,1 >& aUnitDistances,
                                nsSMILValue& aResult) const = 0;
 };
 
 #endif // NS_ISMILTYPE_H_
--- a/dom/smil/nsSMILAnimationFunction.cpp
+++ b/dom/smil/nsSMILAnimationFunction.cpp
@@ -430,17 +430,17 @@ nsSMILAnimationFunction::InterpolateResu
       intervalProgress[0] = ScaleIntervalProgress(intervalProgress[0], index);
     }
 
     if (NS_SUCCEEDED(rv)) {
       MOZ_ASSERT(from, "NULL from-value during interpolation");
       MOZ_ASSERT(to, "NULL to-value during interpolation");
       MOZ_ASSERT(0.0f <= intervalProgress[0] && intervalProgress[0] < 1.0f,
                  "Interval progress should be in the range [0, 1)");
-      rv = from->Interpolate(*to, intervalProgress[0], aResult);
+      rv = from->Interpolate(*to, intervalProgress, aResult);
     }
   }
 
   // Discrete-CalcMode case
   // Note: If interpolation failed (isn't supported for this type), the SVG
   // spec says to force discrete mode.
   if (calcMode == CALC_DISCRETE || NS_FAILED(rv)) {
     double scaledSimpleProgress =
--- a/dom/smil/nsSMILCSSValueType.cpp
+++ b/dom/smil/nsSMILCSSValueType.cpp
@@ -408,108 +408,110 @@ nsSMILCSSValueType::ComputeDistance(cons
   }
   aDistances.AppendElement(distance);
   return NS_OK;
 }
 
 static nsresult
 InterpolateForGecko(const ValueWrapper* aStartWrapper,
                     const ValueWrapper* aEndWrapper,
-                    double aUnitDistance,
+                    AutoTArray<double, 1>& aUnitDistances,
                     nsSMILValue& aResult)
 {
   const AnimationValue* startCSSValue = aStartWrapper
                                         ? &aStartWrapper->mCSSValues[0]
                                         : nullptr;
   const AnimationValue* endCSSValue = &aEndWrapper->mCSSValues[0];
   AnimationValue zeroValueStorage;
   if (!FinalizeStyleAnimationValues(startCSSValue, endCSSValue,
                                     zeroValueStorage)) {
     return NS_ERROR_FAILURE;
   }
 
   StyleAnimationValue resultValue;
   if (StyleAnimationValue::Interpolate(aEndWrapper->mPropID,
                                        startCSSValue->mGecko,
                                        endCSSValue->mGecko,
-                                       aUnitDistance, resultValue)) {
+                                       aUnitDistances[0], resultValue)) {
     aResult.mU.mPtr = new ValueWrapper(aEndWrapper->mPropID, resultValue);
     return NS_OK;
   }
   return NS_ERROR_FAILURE;
 }
 
 static nsresult
 InterpolateForServo(const ValueWrapper* aStartWrapper,
                     const ValueWrapper* aEndWrapper,
-                    double aUnitDistance,
+                    AutoTArray<double, 1>& aUnitDistances,
                     nsSMILValue& aResult)
 {
+  bool is_same_distance = aUnitDistances.Length() == 1;
   AutoTArray<AnimationValue, 1> results;
   AnimationValue zeroValueStorage;
   for (size_t i = 0, len = aEndWrapper->mCSSValues.Length(); i < len; i++) {
     const AnimationValue* startCSSValue = aStartWrapper
                                           ? &aStartWrapper->mCSSValues[i]
                                           : nullptr;
     const AnimationValue* endCSSValue = &aEndWrapper->mCSSValues[i];
     if (!FinalizeStyleAnimationValues(startCSSValue, endCSSValue,
                                       zeroValueStorage)) {
       // XXX: Should we continue?
       return NS_ERROR_FAILURE;
     }
     MOZ_ASSERT(!startCSSValue ||
                !startCSSValue->mServo == !endCSSValue->mServo,
                "Start and end values should use the same style system");
+    double distance = is_same_distance ? aUnitDistances[0] : aUnitDistances[i];
     RefPtr<RawServoAnimationValue> resultValue =
       Servo_AnimationValues_Interpolate(startCSSValue->mServo,
                                         endCSSValue->mServo,
-                                        aUnitDistance).Consume();
+                                        distance).Consume();
     if (!resultValue) {
       // XXX: Should we continue?
       return NS_ERROR_FAILURE;
     }
     results.AppendElement(AnimationValue(resultValue));
   }
   aResult.mU.mPtr = new ValueWrapper(aEndWrapper->mPropID, Move(results));
 
   return NS_OK;
 }
 
 nsresult
 nsSMILCSSValueType::Interpolate(const nsSMILValue& aStartVal,
                                 const nsSMILValue& aEndVal,
-                                double aUnitDistance,
+                                AutoTArray<double, 1>& aUnitDistances,
                                 nsSMILValue& aResult) const
 {
   MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
              "Trying to interpolate different types");
   MOZ_ASSERT(aStartVal.mType == this,
              "Unexpected types for interpolation");
   MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
-  MOZ_ASSERT(aUnitDistance >= 0.0 && aUnitDistance <= 1.0,
+  MOZ_ASSERT(aUnitDistances[0] >= 0.0 && aUnitDistances[0] <= 1.0,
              "unit distance value out of bounds");
   MOZ_ASSERT(!aResult.mU.mPtr, "expecting barely-initialized outparam");
 
   const ValueWrapper* startWrapper = ExtractValueWrapper(aStartVal);
   const ValueWrapper* endWrapper = ExtractValueWrapper(aEndVal);
   MOZ_ASSERT(endWrapper, "expecting non-null endpoint");
   MOZ_ASSERT(
     !startWrapper ||
     startWrapper->mCSSValues.Length() == endWrapper->mCSSValues.Length(),
     "");
 
   bool isServo = endWrapper->mCSSValues[0].mServo != nullptr;
   if (isServo) {
     return InterpolateForServo(startWrapper,
                                endWrapper,
-                               aUnitDistance,
+                               aUnitDistances,
                                aResult);
   }
 
-  return InterpolateForGecko(startWrapper, endWrapper, aUnitDistance, aResult);
+  return InterpolateForGecko(startWrapper, endWrapper, aUnitDistances, aResult);
 }
 
 // Helper function to extract presContext
 static nsPresContext*
 GetPresContextForElement(Element* aElem)
 {
   nsIDocument* doc = aElem->GetUncomposedDoc();
   if (!doc) {
--- a/dom/smil/nsSMILCSSValueType.h
+++ b/dom/smil/nsSMILCSSValueType.h
@@ -48,17 +48,17 @@ protected:
                uint32_t aCount) const override;
   nsresult SandwichAdd(nsSMILValue& aDest,
                        const nsSMILValue& aValueToAdd) const override;
   nsresult ComputeDistance(const nsSMILValue& aFrom,
                            const nsSMILValue& aTo,
                            AutoTArray<double, 1>& aDistances) const override;
   nsresult Interpolate(const nsSMILValue& aStartVal,
                        const nsSMILValue& aEndVal,
-                       double aUnitDistance,
+                       AutoTArray<double, 1>& aUnitDistances,
                        nsSMILValue& aResult) const override;
 
 public:
   // Helper Methods
   // --------------
   /**
    * Sets up the given nsSMILValue to represent the given string value.  The
    * string is interpreted as a value for the given property on the given
--- a/dom/smil/nsSMILFloatType.cpp
+++ b/dom/smil/nsSMILFloatType.cpp
@@ -70,24 +70,24 @@ nsSMILFloatType::ComputeDistance(const n
   aDistances.AppendElement(fabs(to - from));
 
   return NS_OK;
 }
 
 nsresult
 nsSMILFloatType::Interpolate(const nsSMILValue& aStartVal,
                              const nsSMILValue& aEndVal,
-                             double aUnitDistance,
+                             AutoTArray<double, 1>& aUnitDistances,
                              nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
       "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
       "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType   == this, "Unexpected result type");
 
   const double &startVal = aStartVal.mU.mDouble;
   const double &endVal   = aEndVal.mU.mDouble;
 
-  aResult.mU.mDouble = (startVal + (endVal - startVal) * aUnitDistance);
+  aResult.mU.mDouble = (startVal + (endVal - startVal) * aUnitDistances[0]);
 
   return NS_OK;
 }
--- a/dom/smil/nsSMILFloatType.h
+++ b/dom/smil/nsSMILFloatType.h
@@ -31,17 +31,17 @@ protected:
                        const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr nsSMILFloatType() {}
 };
 
 #endif // NS_SMILFLOATTYPE_H_
--- a/dom/smil/nsSMILNullType.cpp
+++ b/dom/smil/nsSMILNullType.cpp
@@ -43,14 +43,14 @@ nsSMILNullType::ComputeDistance(const ns
 {
   NS_NOTREACHED("Computing distance for NULL type");
   return NS_ERROR_FAILURE;
 }
 
 nsresult
 nsSMILNullType::Interpolate(const nsSMILValue& aStartVal,
                             const nsSMILValue& aEndVal,
-                            double aUnitDistance,
+                            AutoTArray<double, 1>& aUnitDistances,
                             nsSMILValue& aResult) const
 {
   NS_NOTREACHED("Interpolating NULL type");
   return NS_ERROR_FAILURE;
 }
--- a/dom/smil/nsSMILNullType.h
+++ b/dom/smil/nsSMILNullType.h
@@ -34,17 +34,17 @@ protected:
                            const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr nsSMILNullType() {}
 };
 
 #endif // NS_SMILNULLTYPE_H_
--- a/dom/smil/nsSMILValue.cpp
+++ b/dom/smil/nsSMILValue.cpp
@@ -113,30 +113,30 @@ nsSMILValue::ComputeDistance(const nsSMI
     return NS_ERROR_FAILURE;
   }
 
   return mType->ComputeDistance(*this, aTo, aDistances);
 }
 
 nsresult
 nsSMILValue::Interpolate(const nsSMILValue& aEndVal,
-                         double aUnitDistance,
+                         AutoTArray<double, 1>& aUnitDistances,
                          nsSMILValue& aResult) const
 {
   if (aEndVal.mType != mType) {
     NS_ERROR("Trying to interpolate between incompatible types");
     return NS_ERROR_FAILURE;
   }
 
   if (aResult.mType != mType) {
     // Outparam has wrong type
     aResult.DestroyAndReinit(mType);
   }
 
-  return mType->Interpolate(*this, aEndVal, aUnitDistance, aResult);
+  return mType->Interpolate(*this, aEndVal, aUnitDistances, aResult);
 }
 
 //----------------------------------------------------------------------
 // Helper methods
 
 // Wrappers for nsISMILType::Init & ::Destroy that verify their postconditions
 void
 nsSMILValue::InitAndCheckPostcondition(const nsISMILType* aNewType)
--- a/dom/smil/nsSMILValue.h
+++ b/dom/smil/nsSMILValue.h
@@ -49,17 +49,17 @@ public:
     return (mType == nsSMILNullType::Singleton());
   }
 
   nsresult Add(const nsSMILValue& aValueToAdd, uint32_t aCount = 1);
   nsresult SandwichAdd(const nsSMILValue& aValueToAdd);
   nsresult ComputeDistance(const nsSMILValue& aTo,
                            AutoTArray<double, 1>& aDistances) const;
   nsresult Interpolate(const nsSMILValue& aEndVal,
-                       double aUnitDistance,
+                       AutoTArray<double, 1>& aUnitDistances,
                        nsSMILValue& aResult) const;
 
   union {
     bool mBool;
     uint64_t mUint;
     int64_t mInt;
     double mDouble;
     struct {
--- a/dom/svg/SVGIntegerPairSMILType.cpp
+++ b/dom/svg/SVGIntegerPairSMILType.cpp
@@ -81,29 +81,29 @@ SVGIntegerPairSMILType::ComputeDistance(
   MOZ_ASSERT(aDistances.IsEmpty());
   aDistances.AppendElement(NS_hypot(delta[0], delta[1]));
   return NS_OK;
 }
 
 nsresult
 SVGIntegerPairSMILType::Interpolate(const nsSMILValue& aStartVal,
                                     const nsSMILValue& aEndVal,
-                                    double aUnitDistance,
+                                    AutoTArray<double, 1>& aUnitDistances,
                                     nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
                   "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
                   "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
 
   double currentVal[2];
   currentVal[0] = aStartVal.mU.mIntPair[0] +
-                  (aEndVal.mU.mIntPair[0] - aStartVal.mU.mIntPair[0]) * aUnitDistance;
+                  (aEndVal.mU.mIntPair[0] - aStartVal.mU.mIntPair[0]) * aUnitDistances[0];
   currentVal[1] = aStartVal.mU.mIntPair[1] +
-                  (aEndVal.mU.mIntPair[1] - aStartVal.mU.mIntPair[1]) * aUnitDistance;
+                  (aEndVal.mU.mIntPair[1] - aStartVal.mU.mIntPair[1]) * aUnitDistances[0];
 
   aResult.mU.mIntPair[0] = NS_lround(currentVal[0]);
   aResult.mU.mIntPair[1] = NS_lround(currentVal[1]);
   return NS_OK;
 }
 
 } // namespace mozilla
--- a/dom/svg/SVGIntegerPairSMILType.h
+++ b/dom/svg/SVGIntegerPairSMILType.h
@@ -35,17 +35,17 @@ protected:
                            const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SVGIntegerPairSMILType() {}
 };
 
 } // namespace mozilla
--- a/dom/svg/SVGLengthListSMILType.cpp
+++ b/dom/svg/SVGLengthListSMILType.cpp
@@ -224,17 +224,17 @@ SVGLengthListSMILType::ComputeDistance(c
   MOZ_ASSERT(aDistances.IsEmpty());
   aDistances.AppendElement(distance);
   return NS_OK;
 }
 
 nsresult
 SVGLengthListSMILType::Interpolate(const nsSMILValue& aStartVal,
                                    const nsSMILValue& aEndVal,
-                                   double aUnitDistance,
+                                   AutoTArray<double, 1>& aUnitDistances,
                                    nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
                   "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
                   "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
 
@@ -271,29 +271,29 @@ SVGLengthListSMILType::Interpolate(const
     if (start[i].GetUnit() == end[i].GetUnit()) {
       s = start[i].GetValueInCurrentUnits();
     } else {
       // If units differ, we use the unit of the item in 'end'.
       // We leave it to the frame code to check that values are finite.
       s = start[i].GetValueInSpecifiedUnit(end[i].GetUnit(), end.Element(), end.Axis());
     }
     float e = end[i].GetValueInCurrentUnits();
-    result[i].SetValueAndUnit(s + (e - s) * aUnitDistance, end[i].GetUnit());
+    result[i].SetValueAndUnit(s + (e - s) * aUnitDistances[0], end[i].GetUnit());
   }
 
   // In the case that start.Length() != end.Length(), one of the following
   // loops will run. (Okay, since CanZeroPadList()==true for the other list.)
 
   for (; i < start.Length(); ++i) {
     result[i].SetValueAndUnit(start[i].GetValueInCurrentUnits() -
-                              start[i].GetValueInCurrentUnits() * aUnitDistance,
+                              start[i].GetValueInCurrentUnits() * aUnitDistances[0],
                               start[i].GetUnit());
   }
   for (; i < end.Length(); ++i) {
-    result[i].SetValueAndUnit(end[i].GetValueInCurrentUnits() * aUnitDistance,
+    result[i].SetValueAndUnit(end[i].GetValueInCurrentUnits() * aUnitDistances[0],
                               end[i].GetUnit());
   }
 
   // propagate target element info!
   result.SetInfo(end.Element(), end.Axis(),
                  start.CanZeroPadList() && end.CanZeroPadList());
 
   return NS_OK;
--- a/dom/svg/SVGLengthListSMILType.h
+++ b/dom/svg/SVGLengthListSMILType.h
@@ -83,17 +83,17 @@ protected:
                            const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SVGLengthListSMILType() {}
 };
 
 } // namespace mozilla
--- a/dom/svg/SVGMotionSMILType.cpp
+++ b/dom/svg/SVGMotionSMILType.cpp
@@ -378,25 +378,25 @@ InterpolateFloat(const float& aStartFlt,
                  const double& aUnitDistance)
 {
   return aStartFlt + aUnitDistance * (aEndFlt - aStartFlt);
 }
 
 nsresult
 SVGMotionSMILType::Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const
 {
   MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
              "Trying to interpolate different types");
   MOZ_ASSERT(aStartVal.mType == this,
              "Unexpected types for interpolation");
   MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
-  MOZ_ASSERT(aUnitDistance >= 0.0 && aUnitDistance <= 1.0,
+  MOZ_ASSERT(aUnitDistances[0] >= 0.0 && aUnitDistances[0] <= 1.0,
              "unit distance value out of bounds");
 
   const MotionSegmentArray& startArr = ExtractMotionSegmentArray(aStartVal);
   const MotionSegmentArray& endArr = ExtractMotionSegmentArray(aEndVal);
   MotionSegmentArray& resultArr = ExtractMotionSegmentArray(aResult);
 
   MOZ_ASSERT(startArr.Length() <= 1,
              "Invalid start-point for animateMotion interpolation");
@@ -430,17 +430,17 @@ SVGMotionSMILType::Interpolate(const nsS
                "unexpected angle mismatch");
     MOZ_ASSERT(startParams.mPath == endParams.mPath,
                "unexpected path mismatch");
     startDist = startParams.mDistToPoint;
   }
 
   // Get the interpolated distance along our path.
   float resultDist = InterpolateFloat(startDist, endParams.mDistToPoint,
-                                      aUnitDistance);
+                                      aUnitDistances[0]);
 
   // Construct the intermediate result segment, and put it in our outparam.
   // AppendElement has guaranteed success here, since Init() allocates 1 slot.
   MOZ_ALWAYS_TRUE(resultArr.AppendElement(MotionSegment(path, resultDist,
                                                         rotateType,
                                                         rotateAngle),
                                           fallible));
   return NS_OK;
--- a/dom/svg/SVGMotionSMILType.h
+++ b/dom/svg/SVGMotionSMILType.h
@@ -58,17 +58,17 @@ protected:
                        uint32_t aCount) const override;
   virtual nsresult SandwichAdd(nsSMILValue& aDest,
                                const nsSMILValue& aValueToAdd) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 public:
   // Used to generate a transform matrix from an <animateMotion> nsSMILValue.
   static gfx::Matrix CreateMatrix(const nsSMILValue& aSMILVal);
 
   // Used to generate a nsSMILValue for the point at the given distance along
   // the given path.
   static nsSMILValue ConstructSMILValue(Path* aPath,
--- a/dom/svg/SVGNumberListSMILType.cpp
+++ b/dom/svg/SVGNumberListSMILType.cpp
@@ -164,17 +164,17 @@ SVGNumberListSMILType::ComputeDistance(c
   aDistances.AppendElement(distance);
 
   return NS_OK;
 }
 
 nsresult
 SVGNumberListSMILType::Interpolate(const nsSMILValue& aStartVal,
                                    const nsSMILValue& aEndVal,
-                                   double aUnitDistance,
+                                   AutoTArray<double, 1>& aUnitDistances,
                                    nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
                   "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
                   "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
 
@@ -199,19 +199,19 @@ SVGNumberListSMILType::Interpolate(const
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   result.SetInfo(end.Element()); // propagate target element info!
 
   if (start.Length() != end.Length()) {
     MOZ_ASSERT(start.Length() == 0, "Not an identity value");
     for (uint32_t i = 0; i < end.Length(); ++i) {
-      result[i] = aUnitDistance * end[i];
+      result[i] = aUnitDistances[0] * end[i];
     }
     return NS_OK;
   }
   for (uint32_t i = 0; i < end.Length(); ++i) {
-    result[i] = start[i] + (end[i] - start[i]) * aUnitDistance;
+    result[i] = start[i] + (end[i] - start[i]) * aUnitDistances[0];
   }
   return NS_OK;
 }
 
 } // namespace mozilla
--- a/dom/svg/SVGNumberListSMILType.h
+++ b/dom/svg/SVGNumberListSMILType.h
@@ -37,17 +37,17 @@ protected:
                            const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SVGNumberListSMILType() {}
 };
 
 } // namespace mozilla
--- a/dom/svg/SVGNumberPairSMILType.cpp
+++ b/dom/svg/SVGNumberPairSMILType.cpp
@@ -83,27 +83,27 @@ SVGNumberPairSMILType::ComputeDistance(c
   MOZ_ASSERT(aDistances.IsEmpty());
   aDistances.AppendElement(NS_hypot(delta[0], delta[1]));
   return NS_OK;
 }
 
 nsresult
 SVGNumberPairSMILType::Interpolate(const nsSMILValue& aStartVal,
                                    const nsSMILValue& aEndVal,
-                                   double aUnitDistance,
+                                   AutoTArray<double, 1>& aUnitDistances,
                                    nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
                   "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
                   "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
 
   aResult.mU.mNumberPair[0] =
     float(aStartVal.mU.mNumberPair[0] +
-          (aEndVal.mU.mNumberPair[0] - aStartVal.mU.mNumberPair[0]) * aUnitDistance);
+          (aEndVal.mU.mNumberPair[0] - aStartVal.mU.mNumberPair[0]) * aUnitDistances[0]);
   aResult.mU.mNumberPair[1] =
     float(aStartVal.mU.mNumberPair[1] +
-          (aEndVal.mU.mNumberPair[1] - aStartVal.mU.mNumberPair[1]) * aUnitDistance);
+          (aEndVal.mU.mNumberPair[1] - aStartVal.mU.mNumberPair[1]) * aUnitDistances[0]);
   return NS_OK;
 }
 
 } // namespace mozilla
--- a/dom/svg/SVGNumberPairSMILType.h
+++ b/dom/svg/SVGNumberPairSMILType.h
@@ -30,17 +30,17 @@ protected:
                            const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SVGNumberPairSMILType() {}
 };
 
 } // namespace mozilla
--- a/dom/svg/SVGOrientSMILType.cpp
+++ b/dom/svg/SVGOrientSMILType.cpp
@@ -114,17 +114,17 @@ SVGOrientSMILType::ComputeDistance(const
   aDistances.AppendElement(fabs(to - from));
 
   return NS_OK;
 }
 
 nsresult
 SVGOrientSMILType::Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
                   "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
                   "Unexpected types for interpolation.");
   NS_PRECONDITION(aResult.mType   == this, "Unexpected result type.");
 
@@ -133,17 +133,17 @@ SVGOrientSMILType::Interpolate(const nsS
     // TODO: it would be nice to be able to handle auto angles too.
     return NS_ERROR_FAILURE;
   }
 
   float start  = aStartVal.mU.mOrient.mAngle *
                    nsSVGAngle::GetDegreesPerUnit(aStartVal.mU.mOrient.mUnit);
   float end    = aEndVal.mU.mOrient.mAngle *
                    nsSVGAngle::GetDegreesPerUnit(aEndVal.mU.mOrient.mUnit);
-  float result = (start + (end - start) * aUnitDistance);
+  float result = (start + (end - start) * aUnitDistances[0]);
 
   // Again, we use the unit of the to/by value for the result:
   aResult.mU.mOrient.mAngle = result /
     nsSVGAngle::GetDegreesPerUnit(aEndVal.mU.mOrient.mUnit);
   aResult.mU.mOrient.mUnit = aEndVal.mU.mOrient.mUnit;
 
   return NS_OK;
 }
--- a/dom/svg/SVGOrientSMILType.h
+++ b/dom/svg/SVGOrientSMILType.h
@@ -50,17 +50,17 @@ protected:
                            const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SVGOrientSMILType() {}
 };
 
 } // namespace mozilla
--- a/dom/svg/SVGPathSegListSMILType.cpp
+++ b/dom/svg/SVGPathSegListSMILType.cpp
@@ -447,17 +447,17 @@ SVGPathSegListSMILType::ComputeDistance(
 
   // SVGContentUtils::ReportToConsole
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
 SVGPathSegListSMILType::Interpolate(const nsSMILValue& aStartVal,
                                     const nsSMILValue& aEndVal,
-                                    double aUnitDistance,
+                                    AutoTArray<double, 1>& aUnitDistances,
                                     nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
                   "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
                   "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
 
@@ -489,13 +489,13 @@ SVGPathSegListSMILType::Interpolate(cons
     result.SetElement(end.Element()); // propagate target element info!
 
     ConvertAllPathSegmentData(start.begin(), start.end(),
                               end.begin(), end.end(),
                               result.begin());
     startListToUse = &result;
   }
 
-  return AddWeightedPathSegLists(1.0 - aUnitDistance, *startListToUse,
-                                 aUnitDistance, end, result);
+  return AddWeightedPathSegLists(1.0 - aUnitDistances[0], *startListToUse,
+                                 aUnitDistances[0], end, result);
 }
 
 } // namespace mozilla
--- a/dom/svg/SVGPathSegListSMILType.h
+++ b/dom/svg/SVGPathSegListSMILType.h
@@ -41,17 +41,17 @@ protected:
                            const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SVGPathSegListSMILType() {}
 };
 
 } // namespace mozilla
--- a/dom/svg/SVGPointListSMILType.cpp
+++ b/dom/svg/SVGPointListSMILType.cpp
@@ -144,17 +144,17 @@ SVGPointListSMILType::ComputeDistance(co
   aDistances.AppendElement(distance);
 
   return NS_OK;
 }
 
 nsresult
 SVGPointListSMILType::Interpolate(const nsSMILValue& aStartVal,
                                   const nsSMILValue& aEndVal,
-                                  double aUnitDistance,
+                                  AutoTArray<double, 1>& aUnitDistances,
                                   nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
                   "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
                   "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
 
@@ -179,19 +179,19 @@ SVGPointListSMILType::Interpolate(const 
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   result.SetInfo(end.Element()); // propagate target element info!
 
   if (start.Length() != end.Length()) {
     MOZ_ASSERT(start.Length() == 0, "Not an identity value");
     for (uint32_t i = 0; i < end.Length(); ++i) {
-      result[i] = aUnitDistance * end[i];
+      result[i] = aUnitDistances[0] * end[i];
     }
     return NS_OK;
   }
   for (uint32_t i = 0; i < end.Length(); ++i) {
-    result[i] = start[i] + (end[i] - start[i]) * aUnitDistance;
+    result[i] = start[i] + (end[i] - start[i]) * aUnitDistances[0];
   }
   return NS_OK;
 }
 
 } // namespace mozilla
--- a/dom/svg/SVGPointListSMILType.h
+++ b/dom/svg/SVGPointListSMILType.h
@@ -37,17 +37,17 @@ protected:
                            const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SVGPointListSMILType() {}
 };
 
 } // namespace mozilla
--- a/dom/svg/SVGTransformListSMILType.cpp
+++ b/dom/svg/SVGTransformListSMILType.cpp
@@ -238,17 +238,17 @@ SVGTransformListSMILType::ComputeDistanc
   }
 
   return NS_OK;
 }
 
 nsresult
 SVGTransformListSMILType::Interpolate(const nsSMILValue& aStartVal,
                                       const nsSMILValue& aEndVal,
-                                      double aUnitDistance,
+                                      AutoTArray<double, 1>& aUnitDistances,
                                       nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
       "Can't interpolate between different SMIL types");
   NS_PRECONDITION(aStartVal.mType == this,
       "Unexpected type for interpolation");
   NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
 
@@ -287,17 +287,17 @@ SVGTransformListSMILType::Interpolate(co
 
   const float* endParams = endTransform.mParams;
 
   // Interpolate between the params
   float newParams[3];
   for (int i = 0; i <= 2; ++i) {
     const float& a = startParams[i];
     const float& b = endParams[i];
-    newParams[i] = static_cast<float>(a + (b - a) * aUnitDistance);
+    newParams[i] = static_cast<float>(a + (b - a) * aUnitDistances[0]);
   }
 
   // Make the result
   SVGTransformSMILData resultTransform(endTransform.mTransformType, newParams);
 
   // Clear the way for it in the result array
   TransformArray& dstTransforms =
     (*static_cast<TransformArray*>(aResult.mU.mPtr));
--- a/dom/svg/SVGTransformListSMILType.h
+++ b/dom/svg/SVGTransformListSMILType.h
@@ -102,17 +102,17 @@ protected:
                        uint32_t aCount) const override;
   virtual nsresult SandwichAdd(nsSMILValue& aDest,
                                const nsSMILValue& aValueToAdd) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 public:
   // Transform array accessors
   // -------------------------
   static nsresult AppendTransform(const SVGTransformSMILData& aTransform,
                                   nsSMILValue& aValue);
   static bool AppendTransforms(const SVGTransformList& aList,
--- a/dom/svg/SVGViewBoxSMILType.cpp
+++ b/dom/svg/SVGViewBoxSMILType.cpp
@@ -104,17 +104,17 @@ SVGViewBoxSMILType::ComputeDistance(cons
     sqrt(dLeft*dLeft + dTop*dTop + dRight*dRight + dBottom*dBottom));
 
   return NS_OK;
 }
 
 nsresult
 SVGViewBoxSMILType::Interpolate(const nsSMILValue& aStartVal,
                                 const nsSMILValue& aEndVal,
-                                double aUnitDistance,
+                                AutoTArray<double, 1>& aUnitDistances,
                                 nsSMILValue& aResult) const
 {
   NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
                   "Trying to interpolate different types");
   NS_PRECONDITION(aStartVal.mType == this,
                   "Unexpected types for interpolation");
   NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
 
@@ -122,19 +122,19 @@ SVGViewBoxSMILType::Interpolate(const ns
   const nsSVGViewBoxRect* end = static_cast<const nsSVGViewBoxRect*>(aEndVal.mU.mPtr);
 
   if (start->none || end->none) {
     return NS_ERROR_FAILURE;
   }
 
   nsSVGViewBoxRect* current = static_cast<nsSVGViewBoxRect*>(aResult.mU.mPtr);
 
-  float x = (start->x + (end->x - start->x) * aUnitDistance);
-  float y = (start->y + (end->y - start->y) * aUnitDistance);
-  float width = (start->width + (end->width - start->width) * aUnitDistance);
-  float height = (start->height + (end->height - start->height) * aUnitDistance);
+  float x = (start->x + (end->x - start->x) * aUnitDistances[0]);
+  float y = (start->y + (end->y - start->y) * aUnitDistances[0]);
+  float width = (start->width + (end->width - start->width) * aUnitDistances[0]);
+  float height = (start->height + (end->height - start->height) * aUnitDistances[0]);
 
   *current = nsSVGViewBoxRect(x, y, width, height);
   
   return NS_OK;
 }
 
 } // namespace mozilla
--- a/dom/svg/SVGViewBoxSMILType.h
+++ b/dom/svg/SVGViewBoxSMILType.h
@@ -30,17 +30,17 @@ protected:
                            const nsSMILValue& aRight) const override;
   virtual nsresult Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const override;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    AutoTArray<double, 1>& aDistances) const override;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
-                               double aUnitDistance,
+                               AutoTArray<double, 1>& aUnitDistances,
                                nsSMILValue& aResult) const override;
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SVGViewBoxSMILType() {}
 };
 
 } // namespace mozilla