Bug 1305325 - Part 10: Make SampleValue return StyleAnimationValue. r=birtles
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Sun, 04 Dec 2016 08:07:40 +0900
changeset 325232 6cf6c430f5a02058ec4acb28e690129306aab6be
parent 325231 60857c37bcfac0cac3609b146de0306b7699ba49
child 325233 b02732a3873018fd8fe09efd6bb4ffb8bf0ab5da
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersbirtles
bugs1305325
milestone53.0a1
Bug 1305325 - Part 10: Make SampleValue return StyleAnimationValue. r=birtles MozReview-Commit-ID: Izr6Cvee96Q
gfx/layers/composite/AsyncCompositionManager.cpp
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -571,21 +571,20 @@ AsyncCompositionManager::AlignFixedAndSt
       AlignFixedAndStickyLayers(aTransformedSubtreeRoot, child, aTransformScrollId,
           aPreviousTransformForRoot, newTransform, aFixedLayerMargins, aClipPartsCache);
     }
   }
 
   return;
 }
 
-static void
+static StyleAnimationValue
 SampleValue(float aPortion, Animation& aAnimation,
             const StyleAnimationValue& aStart, const StyleAnimationValue& aEnd,
-            const StyleAnimationValue& aLastValue, uint64_t aCurrentIteration,
-            Animatable* aValue, Layer* aLayer)
+            const StyleAnimationValue& aLastValue, uint64_t aCurrentIteration)
 {
   NS_ASSERTION(aStart.GetUnit() == aEnd.GetUnit() ||
                aStart.GetUnit() == StyleAnimationValue::eUnit_None ||
                aEnd.GetUnit() == StyleAnimationValue::eUnit_None,
                "Must have same unit");
 
   StyleAnimationValue startValue = aStart;
   StyleAnimationValue endValue = aEnd;
@@ -611,62 +610,90 @@ SampleValue(float aPortion, Animation& a
   StyleAnimationValue interpolatedValue;
   // This should never fail because we only pass transform and opacity values
   // to the compositor and they should never fail to interpolate.
   DebugOnly<bool> uncomputeResult =
     StyleAnimationValue::Interpolate(aAnimation.property(),
                                      startValue, endValue,
                                      aPortion, interpolatedValue);
   MOZ_ASSERT(uncomputeResult, "could not uncompute value");
-
-  if (aAnimation.property() == eCSSProperty_opacity) {
-    *aValue = interpolatedValue.GetFloatValue();
-    return;
-  }
+  return interpolatedValue;
+}
 
-  nsCSSValueSharedList* interpolatedList =
-    interpolatedValue.GetCSSValueSharedListValue();
-
-  TransformData& data = aAnimation.data().get_TransformData();
-  nsPoint origin = data.origin();
-  // we expect all our transform data to arrive in device pixels
-  Point3D transformOrigin = data.transformOrigin();
-  nsDisplayTransform::FrameTransformProperties props(interpolatedList,
-                                                     transformOrigin);
+static void
+ApplyAnimatedValue(Layer* aLayer,
+                   nsCSSPropertyID aProperty,
+                   const AnimationData& aAnimationData,
+                   const StyleAnimationValue& aValue)
+{
+  HostLayer* layerCompositor = aLayer->AsHostLayer();
+  switch (aProperty) {
+    case eCSSProperty_opacity: {
+      MOZ_ASSERT(aValue.GetUnit() == StyleAnimationValue::eUnit_Float,
+                 "Interpolated value for opacity should be float");
+      layerCompositor->SetShadowOpacity(aValue.GetFloatValue());
+      layerCompositor->SetShadowOpacitySetByAnimation(true);
+      break;
+    }
+    case eCSSProperty_transform: {
+      MOZ_ASSERT(aValue.GetUnit() == StyleAnimationValue::eUnit_Transform,
+                 "The unit of interpolated value for transform should be "
+                 "transform");
+      nsCSSValueSharedList* list = aValue.GetCSSValueSharedListValue();
 
-  // If our parent layer is a perspective layer, then the offset into reference
-  // frame coordinates is already on that layer. If not, then we need to ask
-  // for it to be added here.
-  uint32_t flags = 0;
-  if (!aLayer->GetParent() || !aLayer->GetParent()->GetTransformIsPerspective()) {
-    flags = nsDisplayTransform::OFFSET_BY_ORIGIN;
-  }
+      const TransformData& transformData = aAnimationData.get_TransformData();
+      nsPoint origin = transformData.origin();
+      // we expect all our transform data to arrive in device pixels
+      Point3D transformOrigin = transformData.transformOrigin();
+      nsDisplayTransform::FrameTransformProperties props(list,
+                                                         transformOrigin);
+
+      // If our parent layer is a perspective layer, then the offset into reference
+      // frame coordinates is already on that layer. If not, then we need to ask
+      // for it to be added here.
+      uint32_t flags = 0;
+      if (!aLayer->GetParent() ||
+          !aLayer->GetParent()->GetTransformIsPerspective()) {
+        flags = nsDisplayTransform::OFFSET_BY_ORIGIN;
+      }
 
-  Matrix4x4 transform =
-    nsDisplayTransform::GetResultingTransformMatrix(props, origin,
-                                                    data.appUnitsPerDevPixel(),
-                                                    flags, &data.bounds());
+      Matrix4x4 transform =
+        nsDisplayTransform::GetResultingTransformMatrix(props, origin,
+                                                        transformData.appUnitsPerDevPixel(),
+                                                        flags, &transformData.bounds());
 
-  InfallibleTArray<TransformFunction> functions;
-  functions.AppendElement(TransformMatrix(transform));
-  *aValue = functions;
+      if (ContainerLayer* c = aLayer->AsContainerLayer()) {
+        transform.PostScale(c->GetInheritedXScale(), c->GetInheritedYScale(), 1);
+      }
+      layerCompositor->SetShadowBaseTransform(transform);
+      layerCompositor->SetShadowTransformSetByAnimation(true);
+      break;
+    }
+    default:
+      MOZ_ASSERT_UNREACHABLE("Unhandled animated property");
+  }
 }
 
 static bool
 SampleAnimations(Layer* aLayer, TimeStamp aPoint)
 {
   bool activeAnimations = false;
 
   ForEachNode<ForwardIterator>(
       aLayer,
       [&activeAnimations, &aPoint] (Layer* layer)
       {
         AnimationArray& animations = layer->GetAnimations();
+        if (animations.IsEmpty()) {
+          return;
+        }
+
         InfallibleTArray<AnimData>& animationData = layer->GetAnimationData();
 
+        StyleAnimationValue interpolatedValue;
         // Process in order, since later animations override earlier ones.
         for (size_t i = 0, iEnd = animations.Length(); i < iEnd; ++i) {
           Animation& animation = animations[i];
           AnimData& animData = animationData[i];
 
           activeAnimations = true;
 
           MOZ_ASSERT(!animation.startTime().IsNull() ||
@@ -714,44 +741,53 @@ SampleAnimations(Layer* aLayer, TimeStam
             (segment->endPortion() - segment->startPortion());
 
           double portion =
             ComputedTimingFunction::GetPortion(animData.mFunctions[segmentIndex],
                                                positionInSegment,
                                            computedTiming.mBeforeFlag);
 
           // interpolate the property
-          Animatable interpolatedValue;
-          SampleValue(portion, animation,
-                      animData.mStartValues[segmentIndex],
-                      animData.mEndValues[segmentIndex],
-                      animData.mEndValues.LastElement(),
-                      computedTiming.mCurrentIteration,
-                      &interpolatedValue, layer);
-          HostLayer* layerCompositor = layer->AsHostLayer();
-          switch (animation.property()) {
-          case eCSSProperty_opacity:
-          {
-            layerCompositor->SetShadowOpacity(interpolatedValue.get_float());
-            layerCompositor->SetShadowOpacitySetByAnimation(true);
-            break;
+          interpolatedValue =
+            SampleValue(portion, animation,
+                        animData.mStartValues[segmentIndex],
+                        animData.mEndValues[segmentIndex],
+                        animData.mEndValues.LastElement(),
+                        computedTiming.mCurrentIteration);
+        }
+
+#ifdef DEBUG
+        // Sanity check that all of animation data are the same.
+        const AnimationData& lastData = animations.LastElement().data();
+        for (const Animation& animation : animations) {
+          const AnimationData& data = animation.data();
+          MOZ_ASSERT(data.type() == lastData.type(),
+                     "The type of AnimationData should be the same");
+          if (data.type() == AnimationData::Tnull_t) {
+            continue;
           }
-          case eCSSProperty_transform:
-          {
-            Matrix4x4 matrix = interpolatedValue.get_ArrayOfTransformFunction()[0].get_TransformMatrix().value();
-            if (ContainerLayer* c = layer->AsContainerLayer()) {
-              matrix.PostScale(c->GetInheritedXScale(), c->GetInheritedYScale(), 1);
-            }
-            layerCompositor->SetShadowBaseTransform(matrix);
-            layerCompositor->SetShadowTransformSetByAnimation(true);
-            break;
-          }
-          default:
-            NS_WARNING("Unhandled animated property");
-          }
+
+          MOZ_ASSERT(data.type() == AnimationData::TTransformData);
+          const TransformData& transformData = data.get_TransformData();
+          const TransformData& lastTransformData = lastData.get_TransformData();
+          MOZ_ASSERT(transformData.origin() == lastTransformData.origin() &&
+                     transformData.transformOrigin() ==
+                       lastTransformData.transformOrigin() &&
+                     transformData.bounds() == lastTransformData.bounds() &&
+                     transformData.appUnitsPerDevPixel() ==
+                       lastTransformData.appUnitsPerDevPixel(),
+                     "All of members of TransformData should be the same");
+        }
+#endif
+        if (!interpolatedValue.IsNull()) {
+          Animation& animation = animations.LastElement();
+          ApplyAnimatedValue(layer,
+                             animation.property(),
+                             animation.data(),
+                             interpolatedValue);
         }
       });
   return activeAnimations;
 }
 
 static bool
 SampleAPZAnimations(const LayerMetricsWrapper& aLayer, TimeStamp aSampleTime)
 {