Bug 1335942 - Part 2: Use mozilla::AnimationValue in AnimationPropertySegment. draft
authorBoris Chiou <boris.chiou@gmail.com>
Sat, 04 Feb 2017 13:57:08 +0800
changeset 480415 55d1028e26e423423abb39fec75372de796d86be
parent 480414 69c626cf033df4765d5b14f5bf3def1eb204d081
child 480416 8e2657dae119190bb5d2d6d85797e86a110dc203
push id44527
push userbmo:boris.chiou@gmail.com
push dateWed, 08 Feb 2017 05:25:55 +0000
bugs1335942
milestone54.0a1
Bug 1335942 - Part 2: Use mozilla::AnimationValue in AnimationPropertySegment. MozReview-Commit-ID: L6U1A223jsa
dom/animation/KeyframeEffectReadOnly.cpp
dom/animation/KeyframeEffectReadOnly.h
dom/animation/KeyframeUtils.cpp
layout/base/nsLayoutUtils.cpp
layout/painting/ActiveLayerTracker.cpp
layout/painting/nsDisplayList.cpp
layout/style/StyleAnimationValue.h
layout/style/nsTransitionManager.cpp
layout/style/nsTransitionManager.h
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -537,18 +537,18 @@ KeyframeEffectReadOnly::ComposeStyle(
 
     // Bug 1333311 - We use two branches for Gecko and Stylo. However, it's
     // better to remove the duplicated code.
     if (isServoBackend) {
       // Servo backend
 
       // Bug 1329878 - Stylo: Implement accumulate and addition on Servo
       // AnimationValue.
-      RawServoAnimationValue* servoFromValue = segment->mServoFromValue;
-      RawServoAnimationValue* servoToValue = segment->mServoToValue;
+      RawServoAnimationValue* servoFromValue = segment->mFromValue.mServo;
+      RawServoAnimationValue* servoToValue = segment->mToValue.mServo;
 
       // For unsupported or non-animatable animation types, we get nullptrs.
       if (!servoFromValue || !servoToValue) {
         NS_ERROR("Compose style for unsupported or non-animatable property, "
                  "so get invalid RawServoAnimationValues");
         continue;
       }
 
@@ -594,34 +594,34 @@ KeyframeEffectReadOnly::ComposeStyle(
 
       if (!aStyleRule.mGecko) {
         // Allocate the style rule now that we know we have animation data.
         aStyleRule.mGecko = new AnimValuesStyleRule();
       }
 
       StyleAnimationValue fromValue =
         CompositeValue(prop.mProperty, aStyleRule.mGecko,
-                       segment->mFromValue,
+                       segment->mFromValue.mGecko,
                        segment->mFromComposite);
       StyleAnimationValue toValue =
         CompositeValue(prop.mProperty, aStyleRule.mGecko,
-                       segment->mToValue,
+                       segment->mToValue.mGecko,
                        segment->mToComposite);
 
       // Iteration composition for accumulate
       if (mEffectOptions.mIterationComposite ==
           IterationCompositeOperation::Accumulate &&
           computedTiming.mCurrentIteration > 0) {
         const AnimationPropertySegment& lastSegment =
           prop.mSegments.LastElement();
         // FIXME: Bug 1293492: Add a utility function to calculate both of
         // below StyleAnimationValues.
-        StyleAnimationValue lastValue = lastSegment.mToValue.IsNull()
+        StyleAnimationValue lastValue = lastSegment.mToValue.mGecko.IsNull()
           ? GetUnderlyingStyle(prop.mProperty, aStyleRule.mGecko)
-          : lastSegment.mToValue;
+          : lastSegment.mToValue.mGecko;
         fromValue =
           StyleAnimationValue::Accumulate(prop.mProperty,
                                           lastValue,
                                           Move(fromValue),
                                           computedTiming.mCurrentIteration);
         toValue =
           StyleAnimationValue::Accumulate(prop.mProperty,
                                           lastValue,
@@ -1010,20 +1010,20 @@ KeyframeEffectReadOnly::GetTargetStyleCo
 void
 DumpAnimationProperties(nsTArray<AnimationProperty>& aAnimationProperties)
 {
   for (auto& p : aAnimationProperties) {
     printf("%s\n", nsCSSProps::GetStringValue(p.mProperty).get());
     for (auto& s : p.mSegments) {
       nsString fromValue, toValue;
       Unused << StyleAnimationValue::UncomputeValue(p.mProperty,
-                                                    s.mFromValue,
+                                                    s.mFromValue.mGecko,
                                                     fromValue);
       Unused << StyleAnimationValue::UncomputeValue(p.mProperty,
-                                                    s.mToValue,
+                                                    s.mToValue.mGecko,
                                                     toValue);
       printf("  %f..%f: %s..%s\n", s.mFromKey, s.mToKey,
              NS_ConvertUTF16toUTF8(fromValue).get(),
              NS_ConvertUTF16toUTF8(toValue).get());
     }
   }
 }
 #endif
@@ -1130,37 +1130,38 @@ KeyframeEffectReadOnly::GetProperties(
     for (size_t segmentIdx = 0, segmentLen = property.mSegments.Length();
          segmentIdx < segmentLen;
          segmentIdx++)
     {
       const AnimationPropertySegment& segment = property.mSegments[segmentIdx];
 
       binding_detail::FastAnimationPropertyValueDetails fromValue;
       CreatePropertyValue(property.mProperty, segment.mFromKey,
-                          segment.mTimingFunction, segment.mFromValue,
+                          segment.mTimingFunction, segment.mFromValue.mGecko,
                           segment.mFromComposite, fromValue);
       // We don't apply timing functions for zero-length segments, so
       // don't return one here.
       if (segment.mFromKey == segment.mToKey) {
         fromValue.mEasing.Reset();
       }
       // The following won't fail since we have already allocated the capacity
       // above.
       propertyDetails.mValues.AppendElement(fromValue, mozilla::fallible);
 
       // Normally we can ignore the to-value for this segment since it is
       // identical to the from-value from the next segment. However, we need
       // to add it if either:
       // a) this is the last segment, or
       // b) the next segment's from-value differs.
       if (segmentIdx == segmentLen - 1 ||
-          property.mSegments[segmentIdx + 1].mFromValue != segment.mToValue) {
+          property.mSegments[segmentIdx + 1].mFromValue.mGecko !=
+            segment.mToValue.mGecko) {
         binding_detail::FastAnimationPropertyValueDetails toValue;
         CreatePropertyValue(property.mProperty, segment.mToKey,
-                            Nothing(), segment.mToValue,
+                            Nothing(), segment.mToValue.mGecko,
                             segment.mToComposite, toValue);
         // It doesn't really make sense to have a timing function on the
         // last property value or before a sudden jump so we just drop the
         // easing property altogether.
         toValue.mEasing.Reset();
         propertyDetails.mValues.AppendElement(toValue, mozilla::fallible);
       }
     }
@@ -1616,21 +1617,23 @@ KeyframeEffectReadOnly::CalculateCumulat
       // until we compose it.
       if (segment.mFromComposite != CompositeOperation::Replace ||
           segment.mToComposite != CompositeOperation::Replace) {
         mCumulativeChangeHint = ~nsChangeHint_Hints_CanIgnoreIfNotVisible;
         return;
       }
       RefPtr<nsStyleContext> fromContext =
         CreateStyleContextForAnimationValue(property.mProperty,
-                                            segment.mFromValue, aStyleContext);
+                                            segment.mFromValue.mGecko,
+                                            aStyleContext);
 
       RefPtr<nsStyleContext> toContext =
         CreateStyleContextForAnimationValue(property.mProperty,
-                                            segment.mToValue, aStyleContext);
+                                            segment.mToValue.mGecko,
+                                            aStyleContext);
 
       uint32_t equalStructs = 0;
       uint32_t samePointerStructs = 0;
       nsChangeHint changeHint =
         fromContext->CalcStyleDifference(toContext,
                                          nsChangeHint(0),
                                          &equalStructs,
                                          &samePointerStructs);
--- a/dom/animation/KeyframeEffectReadOnly.h
+++ b/dom/animation/KeyframeEffectReadOnly.h
@@ -55,19 +55,17 @@ enum class CompositeOperation : uint8_t;
 struct AnimationPropertyDetails;
 }
 
 struct AnimationPropertySegment
 {
   float mFromKey, mToKey;
   // NOTE: In the case that no keyframe for 0 or 1 offset is specified
   // the unit of mFromValue or mToValue is eUnit_Null.
-  StyleAnimationValue mFromValue, mToValue;
-  // FIXME add a deep == impl for RawServoAnimationValue
-  RefPtr<RawServoAnimationValue> mServoFromValue, mServoToValue;
+  AnimationValue mFromValue, mToValue;
 
   Maybe<ComputedTimingFunction> mTimingFunction;
   dom::CompositeOperation mFromComposite = dom::CompositeOperation::Replace;
   dom::CompositeOperation mToComposite = dom::CompositeOperation::Replace;
 
   bool operator==(const AnimationPropertySegment& aOther) const
   {
     return mFromKey == aOther.mFromKey &&
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -1161,28 +1161,28 @@ static void
 AppendInitialSegment(AnimationProperty* aAnimationProperty,
                      const KeyframeValueEntry& aFirstEntry)
 {
   AnimationPropertySegment* segment =
     aAnimationProperty->mSegments.AppendElement();
   segment->mFromKey        = 0.0f;
   segment->mFromComposite  = dom::CompositeOperation::Add;
   segment->mToKey          = aFirstEntry.mOffset;
-  segment->mToValue        = aFirstEntry.mValue.mGecko;
+  segment->mToValue        = aFirstEntry.mValue;
   segment->mToComposite    = aFirstEntry.mComposite;
 }
 
 static void
 AppendFinalSegment(AnimationProperty* aAnimationProperty,
                    const KeyframeValueEntry& aLastEntry)
 {
   AnimationPropertySegment* segment =
     aAnimationProperty->mSegments.AppendElement();
   segment->mFromKey        = aLastEntry.mOffset;
-  segment->mFromValue      = aLastEntry.mValue.mGecko;
+  segment->mFromValue      = aLastEntry.mValue;
   segment->mFromComposite  = aLastEntry.mComposite;
   segment->mToKey          = 1.0f;
   segment->mToComposite    = dom::CompositeOperation::Add;
   segment->mTimingFunction = aLastEntry.mTimingFunction;
 }
 
 // Returns a newly created AnimationProperty if one was created to fill-in the
 // missing keyframe, nullptr otherwise (if we decided not to fill the keyframe
@@ -1395,20 +1395,18 @@ BuildSegmentsFromValueEntries(nsTArray<K
 
     MOZ_ASSERT(animationProperty, "animationProperty should be valid pointer.");
 
     // Now generate the segment.
     AnimationPropertySegment* segment =
       animationProperty->mSegments.AppendElement();
     segment->mFromKey        = aEntries[i].mOffset;
     segment->mToKey          = aEntries[j].mOffset;
-    segment->mFromValue      = aEntries[i].mValue.mGecko;
-    segment->mToValue        = aEntries[j].mValue.mGecko;
-    segment->mServoFromValue = aEntries[i].mValue.mServo;
-    segment->mServoToValue   = aEntries[j].mValue.mServo;
+    segment->mFromValue      = aEntries[i].mValue;
+    segment->mToValue        = aEntries[j].mValue;
     segment->mTimingFunction = aEntries[i].mTimingFunction;
     segment->mFromComposite  = aEntries[i].mComposite;
     segment->mToComposite    = aEntries[j].mComposite;
 
     i = j;
   }
 }
 
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -593,20 +593,22 @@ GetMinAndMaxScaleForAnimationProperty(co
         MOZ_ASSERT(!baseStyle.IsNull(), "The base value should be set");
         UpdateMinMaxScale(aFrame, baseStyle, aMinScale, aMaxScale);
       }
 
       for (const AnimationPropertySegment& segment : prop.mSegments) {
         // In case of add or accumulate composite, StyleAnimationValue does
         // not have a valid value.
         if (segment.mFromComposite == dom::CompositeOperation::Replace) {
-          UpdateMinMaxScale(aFrame, segment.mFromValue, aMinScale, aMaxScale);
+          UpdateMinMaxScale(aFrame, segment.mFromValue.mGecko, aMinScale,
+                            aMaxScale);
         }
         if (segment.mToComposite == dom::CompositeOperation::Replace) {
-          UpdateMinMaxScale(aFrame, segment.mToValue, aMinScale, aMaxScale);
+          UpdateMinMaxScale(aFrame, segment.mToValue.mGecko, aMinScale,
+                            aMaxScale);
         }
       }
     }
   }
 }
 
 gfxSize
 nsLayoutUtils::ComputeSuitableScaleForAnimation(const nsIFrame* aFrame,
--- a/layout/painting/ActiveLayerTracker.cpp
+++ b/layout/painting/ActiveLayerTracker.cpp
@@ -483,21 +483,21 @@ ContainsAnimatedScale(EffectSet& aEffect
       continue;
     }
 
     for (const AnimationProperty& prop : effect->Properties()) {
       if (prop.mProperty != eCSSProperty_transform) {
         continue;
       }
       for (AnimationPropertySegment segment : prop.mSegments) {
-        gfxSize from = segment.mFromValue.GetScaleValue(aFrame);
+        gfxSize from = segment.mFromValue.mGecko.GetScaleValue(aFrame);
         if (from != gfxSize(1.0f, 1.0f)) {
           return true;
         }
-        gfxSize to = segment.mToValue.GetScaleValue(aFrame);
+        gfxSize to = segment.mToValue.mGecko.GetScaleValue(aFrame);
         if (to != gfxSize(1.0f, 1.0f)) {
           return true;
         }
       }
     }
   }
 
   return false;
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -552,21 +552,21 @@ AddAnimationForProperty(nsIFrame* aFrame
     animation->baseStyle() = null_t();
   }
 
   for (uint32_t segIdx = 0; segIdx < aProperty.mSegments.Length(); segIdx++) {
     const AnimationPropertySegment& segment = aProperty.mSegments[segIdx];
 
     AnimationSegment* animSegment = animation->segments().AppendElement();
     SetAnimatable(aProperty.mProperty,
-                  segment.mFromValue,
+                  segment.mFromValue.mGecko,
                   aFrame, refBox,
                   animSegment->startState());
     SetAnimatable(aProperty.mProperty,
-                  segment.mToValue,
+                  segment.mToValue.mGecko,
                   aFrame, refBox,
                   animSegment->endState());
 
     animSegment->startPortion() = segment.mFromKey;
     animSegment->endPortion() = segment.mToKey;
     animSegment->startComposite() =
       static_cast<uint8_t>(segment.mFromComposite);
     animSegment->endComposite() =
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -581,16 +581,21 @@ private:
     return aUnit == eUnit_UnparsedString;
   }
 };
 
 struct AnimationValue
 {
   StyleAnimationValue mGecko;
   RefPtr<RawServoAnimationValue> mServo;
+
+  bool operator==(const AnimationValue& aOther) const {
+    // FIXME: Bug 1337229: add a deep == impl for RawServoAnimationValue.
+    return mGecko == aOther.mGecko && mServo == aOther.mServo;
+  }
 };
 
 struct PropertyStyleAnimationValuePair
 {
   nsCSSPropertyID mProperty;
   AnimationValue mValue;
 };
 } // namespace mozilla
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -115,17 +115,17 @@ ElementPropertyTransition::UpdateStartVa
       MOZ_ASSERT(mProperties.Length() == 1 &&
                  mProperties[0].mSegments.Length() == 1,
                  "The transition should have one property and one segment");
       nsCSSValue cssValue;
       DebugOnly<bool> uncomputeResult =
         StyleAnimationValue::UncomputeValue(mProperties[0].mProperty,
                                             startValue,
                                             cssValue);
-      mProperties[0].mSegments[0].mFromValue = Move(startValue);
+      mProperties[0].mSegments[0].mFromValue.mGecko = Move(startValue);
       MOZ_ASSERT(uncomputeResult, "UncomputeValue should not fail");
       MOZ_ASSERT(mKeyframes.Length() == 2,
           "Transitions should have exactly two animation keyframes");
       MOZ_ASSERT(mKeyframes[0].mPropertyValues.Length() == 1,
           "Transitions should have exactly one property in their first "
           "frame");
       mKeyframes[0].mPropertyValues[0].mValue = cssValue;
     }
@@ -984,18 +984,18 @@ nsTransitionManager::ConsiderInitiatingT
       const AnimationPropertySegment& segment =
         oldPT->Properties()[0].mSegments[0];
       pt->mReplacedTransition.emplace(
         ElementPropertyTransition::ReplacedTransitionProperties({
           oldPT->GetAnimation()->GetStartTime().Value(),
           oldPT->GetAnimation()->PlaybackRate(),
           oldPT->SpecifiedTiming(),
           segment.mTimingFunction,
-          segment.mFromValue,
-          segment.mToValue
+          segment.mFromValue.mGecko,
+          segment.mToValue.mGecko
         })
       );
     }
     animations[currentIndex]->CancelFromStyle();
     oldPT = nullptr; // Clear pointer so it doesn't dangle
     animations[currentIndex] = animation;
   } else {
     if (!animations.AppendElement(animation)) {
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -68,17 +68,17 @@ struct ElementPropertyTransition : publi
     // return a null value but also show a warning since we should be
     // detecting that kind of situation in advance and not generating a
     // transition in the first place.
     if (mProperties.Length() < 1 ||
         mProperties[0].mSegments.Length() < 1) {
       NS_WARNING("Failed to generate transition property values");
       return StyleAnimationValue();
     }
-    return mProperties[0].mSegments[0].mToValue;
+    return mProperties[0].mSegments[0].mToValue.mGecko;
   }
 
   // This is the start value to be used for a check for whether a
   // transition is being reversed.  Normally the same as
   // mProperties[0].mSegments[0].mFromValue, except when this transition
   // started as the reversal of another in-progress transition.
   // Needed so we can handle two reverses in a row.
   StyleAnimationValue mStartForReversingTest;