--- a/dom/smil/nsSMILCSSValueType.cpp
+++ b/dom/smil/nsSMILCSSValueType.cpp
@@ -31,47 +31,57 @@ using mozilla::StyleAnimationValue;
/*static*/ nsSMILCSSValueType nsSMILCSSValueType::sSingleton;
struct ValueWrapper {
ValueWrapper(nsCSSPropertyID aPropID, const AnimationValue& aValue)
: mPropID(aPropID)
{
if (aValue.mServo) {
- mServoValue = aValue.mServo;
+ mServoValues.AppendElement(aValue.mServo);
return;
}
mGeckoValue = aValue.mGecko;
}
ValueWrapper(nsCSSPropertyID aPropID, const StyleAnimationValue& aValue)
: mPropID(aPropID), mGeckoValue(aValue) {}
ValueWrapper(nsCSSPropertyID aPropID,
const RefPtr<RawServoAnimationValue>& aValue)
- : mPropID(aPropID), mServoValue(aValue) {}
+ : mPropID(aPropID), mServoValues{(aValue)} {}
bool operator==(const ValueWrapper& aOther) const
{
if (mPropID != aOther.mPropID) {
return false;
}
- if (mServoValue && aOther.mServoValue) {
- return Servo_AnimationValue_DeepEqual(mServoValue, aOther.mServoValue);
+ if (!mServoValues.IsEmpty()) {
+ size_t len = mServoValues.Length();
+ if (len != aOther.mServoValues.Length()) {
+ return false;
+ }
+ for (size_t i = 0; i < len; i++) {
+ if (!Servo_AnimationValue_DeepEqual(mServoValues[i],
+ aOther.mServoValues[i])) {
+ return false;
+ }
+ }
+ return true;
}
- return !mServoValue && !aOther.mServoValue &&
- mGeckoValue == aOther.mGeckoValue;
+
+ return mGeckoValue == aOther.mGeckoValue;
}
bool operator!=(const ValueWrapper& aOther) const
{
return !(*this == aOther);
}
nsCSSPropertyID mPropID;
- RefPtr<RawServoAnimationValue> mServoValue;
+ AutoTArray<RefPtr<RawServoAnimationValue>, 1> mServoValues;
StyleAnimationValue mGeckoValue;
};
// Helper Methods
// --------------
static const StyleAnimationValue*
GetZeroValueForUnit(StyleAnimationValue::Unit aUnit)
@@ -275,47 +285,47 @@ AddOrAccumulateForServo(nsSMILValue& aDe
CompositeOperation aCompositeOp,
uint64_t aCount)
{
nsCSSPropertyID property = aValueToAddWrapper
? aValueToAddWrapper->mPropID
: aDestWrapper->mPropID;
const RefPtr<RawServoAnimationValue>* valueToAdd =
aValueToAddWrapper
- ? &aValueToAddWrapper->mServoValue
+ ? &aValueToAddWrapper->mServoValues[0]
: nullptr;
const RefPtr<RawServoAnimationValue>* destValue =
aDestWrapper
- ? &aDestWrapper->mServoValue
+ ? &aDestWrapper->mServoValues[0]
: nullptr;
RefPtr<RawServoAnimationValue> zeroValueStorage;
if (!FinalizeServoAnimationValues(valueToAdd, destValue, zeroValueStorage)) {
return false;
}
// FinalizeServoAnimationValues may have updated destValue so we should make
// sure the aDest and aDestWrapper outparams are up-to-date.
if (aDestWrapper) {
- aDestWrapper->mServoValue = *destValue;
+ aDestWrapper->mServoValues[0] = *destValue;
} else {
// aDest may be a barely-initialized "zero" destination.
aDest.mU.mPtr = aDestWrapper = new ValueWrapper(property, *destValue);
}
RefPtr<RawServoAnimationValue> result;
if (aCompositeOp == CompositeOperation::Add) {
result = Servo_AnimationValues_Add(*destValue, *valueToAdd).Consume();
} else {
result = Servo_AnimationValues_Accumulate(*destValue,
*valueToAdd,
aCount).Consume();
}
if (result) {
- aDestWrapper->mServoValue = result;
+ aDestWrapper->mServoValues[0] = result;
}
return result;
}
static bool
AddOrAccumulate(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
CompositeOperation aCompositeOp, uint64_t aCount)
{
@@ -340,18 +350,18 @@ AddOrAccumulate(nsSMILValue& aDest, cons
// 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 false;
}
bool isServo = valueToAddWrapper
- ? valueToAddWrapper->mServoValue
- : destWrapper->mServoValue;
+ ? valueToAddWrapper->mServoValues[0]
+ : destWrapper->mServoValues[0];
if (isServo) {
return AddOrAccumulateForServo(aDest,
valueToAddWrapper,
destWrapper,
aCompositeOp,
aCount);
}
@@ -403,18 +413,18 @@ nsSMILCSSValueType::Add(nsSMILValue& aDe
}
static nsresult
ComputeDistanceForServo(const ValueWrapper* aFromWrapper,
const ValueWrapper& aToWrapper,
double& aDistance)
{
const RefPtr<RawServoAnimationValue>* fromValue =
- aFromWrapper ? &aFromWrapper->mServoValue : nullptr;
- const RefPtr<RawServoAnimationValue>* toValue = &aToWrapper.mServoValue;
+ aFromWrapper ? &aFromWrapper->mServoValues[0] : nullptr;
+ const RefPtr<RawServoAnimationValue>* toValue = &aToWrapper.mServoValues[0];
RefPtr<RawServoAnimationValue> zeroValueStorage;
if (!FinalizeServoAnimationValues(fromValue, toValue, zeroValueStorage)) {
return NS_ERROR_FAILURE;
}
aDistance = Servo_AnimationValues_ComputeDistance(*fromValue, *toValue);
return NS_OK;
@@ -428,17 +438,17 @@ nsSMILCSSValueType::ComputeDistance(cons
MOZ_ASSERT(aFrom.mType == aTo.mType,
"Trying to compare different types");
MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
const ValueWrapper* fromWrapper = ExtractValueWrapper(aFrom);
const ValueWrapper* toWrapper = ExtractValueWrapper(aTo);
MOZ_ASSERT(toWrapper, "expecting non-null endpoint");
- if (toWrapper->mServoValue) {
+ if (!toWrapper->mServoValues.IsEmpty()) {
return ComputeDistanceForServo(fromWrapper, *toWrapper, aDistance);
}
const StyleAnimationValue* fromCSSValue = fromWrapper ?
&fromWrapper->mGeckoValue : nullptr;
const StyleAnimationValue* toCSSValue = &toWrapper->mGeckoValue;
if (!FinalizeStyleAnimationValues(fromCSSValue, toCSSValue)) {
return NS_ERROR_FAILURE;
@@ -481,19 +491,19 @@ InterpolateForGecko(const ValueWrapper*
static nsresult
InterpolateForServo(const ValueWrapper* aStartWrapper,
const ValueWrapper& aEndWrapper,
double aUnitDistance,
nsSMILValue& aResult)
{
const RefPtr<RawServoAnimationValue>*
startValue = aStartWrapper
- ? &aStartWrapper->mServoValue
+ ? &aStartWrapper->mServoValues[0]
: nullptr;
- const RefPtr<RawServoAnimationValue>* endValue = &aEndWrapper.mServoValue;
+ const RefPtr<RawServoAnimationValue>* endValue = &aEndWrapper.mServoValues[0];
RefPtr<RawServoAnimationValue> zeroValueStorage;
if (!FinalizeServoAnimationValues(startValue, endValue, zeroValueStorage)) {
return NS_ERROR_FAILURE;
}
RefPtr<RawServoAnimationValue> result =
Servo_AnimationValues_Interpolate(*startValue,
*endValue,
@@ -520,17 +530,17 @@ nsSMILCSSValueType::Interpolate(const ns
MOZ_ASSERT(aUnitDistance >= 0.0 && aUnitDistance <= 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");
- if (endWrapper->mServoValue) {
+ if (!endWrapper->mServoValues.IsEmpty()) {
return InterpolateForServo(startWrapper,
*endWrapper,
aUnitDistance,
aResult);
}
return InterpolateForGecko(startWrapper,
*endWrapper,
@@ -776,18 +786,18 @@ nsSMILCSSValueType::ValueToString(const
{
MOZ_ASSERT(aValue.mType == &nsSMILCSSValueType::sSingleton,
"Unexpected SMIL value type");
const ValueWrapper* wrapper = ExtractValueWrapper(aValue);
if (!wrapper) {
return;
}
- if (wrapper->mServoValue) {
- Servo_AnimationValue_Serialize(wrapper->mServoValue,
+ if (!wrapper->mServoValues.IsEmpty()) {
+ Servo_AnimationValue_Serialize(wrapper->mServoValues[0],
wrapper->mPropID,
&aString);
return;
}
DebugOnly<bool> uncomputeResult =
StyleAnimationValue::UncomputeValue(wrapper->mPropID,
wrapper->mGeckoValue,