Bug 1425837 - Part 1: Move ToAnimationValue into AnimationValue. r=hiro
authorBoris Chiou <boris.chiou@gmail.com>
Mon, 18 Mar 2019 18:04:44 +0000
changeset 464923 07a1ab95598e298d92faf62534869ea45e8cd979
parent 464922 2db1d305083d4ee0d08104786507706ca8c5ad90
child 464924 5d416b07c9b9886d7456e9e209ed93247e497af8
push id35729
push useropoprus@mozilla.com
push dateTue, 19 Mar 2019 16:30:13 +0000
treeherdermozilla-central@1d783ed68779 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershiro
bugs1425837
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1425837 - Part 1: Move ToAnimationValue into AnimationValue. r=hiro It seems this function uses some FFIs to generate the AnimationValue, We could move it into AnimationValue class, although what we really need is RefPtr<ServoAnimationValue>. Maybe we should use AnimationValue everywhere, instead of the Servo type. This could be done by other patches. Differential Revision: https://phabricator.services.mozilla.com/D22562
gfx/layers/AnimationHelper.cpp
layout/style/StyleAnimationValue.cpp
layout/style/StyleAnimationValue.h
--- a/gfx/layers/AnimationHelper.cpp
+++ b/gfx/layers/AnimationHelper.cpp
@@ -337,193 +337,16 @@ AnimationHelper::SampleResult AnimationH
                        lastTransformData.appUnitsPerDevPixel(),
                "All of members of TransformData should be the same");
   }
 #endif
 
   return hasInEffectAnimations ? SampleResult::Sampled : SampleResult::None;
 }
 
-struct BogusAnimation {};
-
-static inline Result<Ok, BogusAnimation> SetCSSAngle(const CSSAngle& aAngle,
-                                                     nsCSSValue& aValue) {
-  aValue.SetFloatValue(aAngle.value(), nsCSSUnit(aAngle.unit()));
-  if (!aValue.IsAngularUnit()) {
-    NS_ERROR("Bogus animation from IPC");
-    return Err(BogusAnimation{});
-  }
-  return Ok();
-}
-
-static Result<nsCSSValueSharedList*, BogusAnimation> CreateCSSValueList(
-    const InfallibleTArray<TransformFunction>& aFunctions) {
-  nsAutoPtr<nsCSSValueList> result;
-  nsCSSValueList** resultTail = getter_Transfers(result);
-  for (uint32_t i = 0; i < aFunctions.Length(); i++) {
-    RefPtr<nsCSSValue::Array> arr;
-    switch (aFunctions[i].type()) {
-      case TransformFunction::TRotationX: {
-        const CSSAngle& angle = aFunctions[i].get_RotationX().angle();
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_rotatex,
-                                                      resultTail);
-        MOZ_TRY(SetCSSAngle(angle, arr->Item(1)));
-        break;
-      }
-      case TransformFunction::TRotationY: {
-        const CSSAngle& angle = aFunctions[i].get_RotationY().angle();
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_rotatey,
-                                                      resultTail);
-        MOZ_TRY(SetCSSAngle(angle, arr->Item(1)));
-        break;
-      }
-      case TransformFunction::TRotationZ: {
-        const CSSAngle& angle = aFunctions[i].get_RotationZ().angle();
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_rotatez,
-                                                      resultTail);
-        MOZ_TRY(SetCSSAngle(angle, arr->Item(1)));
-        break;
-      }
-      case TransformFunction::TRotation: {
-        const CSSAngle& angle = aFunctions[i].get_Rotation().angle();
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_rotate,
-                                                      resultTail);
-        MOZ_TRY(SetCSSAngle(angle, arr->Item(1)));
-        break;
-      }
-      case TransformFunction::TRotation3D: {
-        float x = aFunctions[i].get_Rotation3D().x();
-        float y = aFunctions[i].get_Rotation3D().y();
-        float z = aFunctions[i].get_Rotation3D().z();
-        const CSSAngle& angle = aFunctions[i].get_Rotation3D().angle();
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_rotate3d,
-                                                      resultTail);
-        arr->Item(1).SetFloatValue(x, eCSSUnit_Number);
-        arr->Item(2).SetFloatValue(y, eCSSUnit_Number);
-        arr->Item(3).SetFloatValue(z, eCSSUnit_Number);
-        MOZ_TRY(SetCSSAngle(angle, arr->Item(4)));
-        break;
-      }
-      case TransformFunction::TScale: {
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_scale3d,
-                                                      resultTail);
-        arr->Item(1).SetFloatValue(aFunctions[i].get_Scale().x(),
-                                   eCSSUnit_Number);
-        arr->Item(2).SetFloatValue(aFunctions[i].get_Scale().y(),
-                                   eCSSUnit_Number);
-        arr->Item(3).SetFloatValue(aFunctions[i].get_Scale().z(),
-                                   eCSSUnit_Number);
-        break;
-      }
-      case TransformFunction::TTranslation: {
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_translate3d,
-                                                      resultTail);
-        arr->Item(1).SetFloatValue(aFunctions[i].get_Translation().x(),
-                                   eCSSUnit_Pixel);
-        arr->Item(2).SetFloatValue(aFunctions[i].get_Translation().y(),
-                                   eCSSUnit_Pixel);
-        arr->Item(3).SetFloatValue(aFunctions[i].get_Translation().z(),
-                                   eCSSUnit_Pixel);
-        break;
-      }
-      case TransformFunction::TSkewX: {
-        const CSSAngle& x = aFunctions[i].get_SkewX().x();
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_skewx,
-                                                      resultTail);
-        MOZ_TRY(SetCSSAngle(x, arr->Item(1)));
-        break;
-      }
-      case TransformFunction::TSkewY: {
-        const CSSAngle& y = aFunctions[i].get_SkewY().y();
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_skewy,
-                                                      resultTail);
-        MOZ_TRY(SetCSSAngle(y, arr->Item(1)));
-        break;
-      }
-      case TransformFunction::TSkew: {
-        const CSSAngle& x = aFunctions[i].get_Skew().x();
-        const CSSAngle& y = aFunctions[i].get_Skew().y();
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_skew,
-                                                      resultTail);
-        MOZ_TRY(SetCSSAngle(x, arr->Item(1)));
-        MOZ_TRY(SetCSSAngle(y, arr->Item(2)));
-        break;
-      }
-      case TransformFunction::TTransformMatrix: {
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_matrix3d,
-                                                      resultTail);
-        const gfx::Matrix4x4& matrix =
-            aFunctions[i].get_TransformMatrix().value();
-        arr->Item(1).SetFloatValue(matrix._11, eCSSUnit_Number);
-        arr->Item(2).SetFloatValue(matrix._12, eCSSUnit_Number);
-        arr->Item(3).SetFloatValue(matrix._13, eCSSUnit_Number);
-        arr->Item(4).SetFloatValue(matrix._14, eCSSUnit_Number);
-        arr->Item(5).SetFloatValue(matrix._21, eCSSUnit_Number);
-        arr->Item(6).SetFloatValue(matrix._22, eCSSUnit_Number);
-        arr->Item(7).SetFloatValue(matrix._23, eCSSUnit_Number);
-        arr->Item(8).SetFloatValue(matrix._24, eCSSUnit_Number);
-        arr->Item(9).SetFloatValue(matrix._31, eCSSUnit_Number);
-        arr->Item(10).SetFloatValue(matrix._32, eCSSUnit_Number);
-        arr->Item(11).SetFloatValue(matrix._33, eCSSUnit_Number);
-        arr->Item(12).SetFloatValue(matrix._34, eCSSUnit_Number);
-        arr->Item(13).SetFloatValue(matrix._41, eCSSUnit_Number);
-        arr->Item(14).SetFloatValue(matrix._42, eCSSUnit_Number);
-        arr->Item(15).SetFloatValue(matrix._43, eCSSUnit_Number);
-        arr->Item(16).SetFloatValue(matrix._44, eCSSUnit_Number);
-        break;
-      }
-      case TransformFunction::TPerspective: {
-        float perspective = aFunctions[i].get_Perspective().value();
-        arr = AnimationValue::AppendTransformFunction(eCSSKeyword_perspective,
-                                                      resultTail);
-        arr->Item(1).SetFloatValue(perspective, eCSSUnit_Pixel);
-        break;
-      }
-      default:
-        NS_ASSERTION(false, "All functions should be implemented?");
-    }
-  }
-  if (aFunctions.Length() == 0) {
-    result = new nsCSSValueList();
-    result->mValue.SetNoneValue();
-  }
-  return new nsCSSValueSharedList(result.forget());
-}
-
-static already_AddRefed<RawServoAnimationValue> ToAnimationValue(
-    nsCSSPropertyID aProperty, const Animatable& aAnimatable) {
-  RefPtr<RawServoAnimationValue> result;
-
-  switch (aAnimatable.type()) {
-    case Animatable::Tnull_t:
-      break;
-    case Animatable::TArrayOfTransformFunction: {
-      const InfallibleTArray<TransformFunction>& transforms =
-          aAnimatable.get_ArrayOfTransformFunction();
-      auto listOrError = CreateCSSValueList(transforms);
-      if (listOrError.isOk()) {
-        RefPtr<nsCSSValueSharedList> list = listOrError.unwrap();
-        MOZ_ASSERT(list, "Transform list should be non null");
-        result = Servo_AnimationValue_Transform(*list).Consume();
-      }
-      break;
-    }
-    case Animatable::Tfloat:
-      result = Servo_AnimationValue_Opacity(aAnimatable.get_float()).Consume();
-      break;
-    case Animatable::Tnscolor:
-      result = Servo_AnimationValue_Color(aProperty, aAnimatable.get_nscolor())
-                   .Consume();
-      break;
-    default:
-      MOZ_ASSERT_UNREACHABLE("Unsupported type");
-  }
-  return result.forget();
-}
-
 void AnimationHelper::SetAnimations(
     AnimationArray& aAnimations, InfallibleTArray<AnimData>& aAnimData,
     RefPtr<RawServoAnimationValue>& aBaseAnimationStyle) {
   for (uint32_t i = 0; i < aAnimations.Length(); i++) {
     Animation& animation = aAnimations[i];
     // Adjust fill mode so that if the main thread is delayed in clearing
     // this animation we don't introduce flicker by jumping back to the old
     // underlying value.
@@ -545,18 +368,18 @@ void AnimationHelper::SetAnimations(
           animation.fillMode() = static_cast<uint8_t>(dom::FillMode::Both);
         }
         break;
       default:
         break;
     }
 
     if (animation.baseStyle().type() != Animatable::Tnull_t) {
-      aBaseAnimationStyle =
-          ToAnimationValue(animation.property(), animation.baseStyle());
+      aBaseAnimationStyle = AnimationValue::FromAnimatable(
+          animation.property(), animation.baseStyle());
     }
 
     AnimData* data = aAnimData.AppendElement();
 
     data->mTiming =
         TimingParams{animation.duration(),
                      animation.delay(),
                      animation.endDelay(),
@@ -570,20 +393,20 @@ void AnimationHelper::SetAnimations(
         data->mFunctions;
     InfallibleTArray<RefPtr<RawServoAnimationValue>>& startValues =
         data->mStartValues;
     InfallibleTArray<RefPtr<RawServoAnimationValue>>& endValues =
         data->mEndValues;
 
     const InfallibleTArray<AnimationSegment>& segments = animation.segments();
     for (const AnimationSegment& segment : segments) {
-      startValues.AppendElement(
-          ToAnimationValue(animation.property(), segment.startState()));
-      endValues.AppendElement(
-          ToAnimationValue(animation.property(), segment.endState()));
+      startValues.AppendElement(AnimationValue::FromAnimatable(
+          animation.property(), segment.startState()));
+      endValues.AppendElement(AnimationValue::FromAnimatable(
+          animation.property(), segment.endState()));
 
       TimingFunction tf = segment.sampleFn();
       Maybe<ComputedTimingFunction> ctf =
           AnimationUtils::TimingFunctionToComputedTimingFunction(tf);
       functions.AppendElement(ctf);
     }
   }
 }
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -25,16 +25,17 @@
 #include "mozilla/ServoBindings.h"  // RawServoDeclarationBlock
 #include "mozilla/ServoCSSParser.h"
 #include "gfxMatrix.h"
 #include "gfxQuaternion.h"
 #include "mozilla/dom/Document.h"
 #include "nsIFrame.h"
 #include "gfx2DGlue.h"
 #include "mozilla/ComputedStyleInlines.h"
+#include "mozilla/layers/LayersMessages.h"
 
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using nsStyleTransformMatrix::Decompose2DMatrix;
 using nsStyleTransformMatrix::Decompose3DMatrix;
 using nsStyleTransformMatrix::ShearType;
@@ -84,16 +85,158 @@ static already_AddRefed<nsCSSValue::Arra
   }
 
   RefPtr<nsCSSValue::Array> arr = nsCSSValue::Array::Create(nargs + 1);
   arr->Item(0).SetIntValue(aTransformFunction, eCSSUnit_Enumerated);
 
   return arr.forget();
 }
 
+static already_AddRefed<nsCSSValue::Array> AppendTransformFunction(
+    nsCSSKeyword aTransformFunction, nsCSSValueList**& aListTail) {
+  RefPtr<nsCSSValue::Array> arr = AppendFunction(aTransformFunction);
+  nsCSSValueList* item = new nsCSSValueList;
+  item->mValue.SetArrayValue(arr, eCSSUnit_Function);
+
+  *aListTail = item;
+  aListTail = &item->mNext;
+
+  return arr.forget();
+}
+
+struct BogusAnimation {};
+
+static inline Result<Ok, BogusAnimation> SetCSSAngle(
+    const layers::CSSAngle& aAngle, nsCSSValue& aValue) {
+  aValue.SetFloatValue(aAngle.value(), nsCSSUnit(aAngle.unit()));
+  if (!aValue.IsAngularUnit()) {
+    NS_ERROR("Bogus animation from IPC");
+    return Err(BogusAnimation{});
+  }
+  return Ok();
+}
+
+static Result<nsCSSValueSharedList*, BogusAnimation> CreateCSSValueList(
+    const InfallibleTArray<layers::TransformFunction>& aFunctions) {
+  nsAutoPtr<nsCSSValueList> result;
+  nsCSSValueList** resultTail = getter_Transfers(result);
+  for (const layers::TransformFunction& function : aFunctions) {
+    RefPtr<nsCSSValue::Array> arr;
+    switch (function.type()) {
+      case layers::TransformFunction::TRotationX: {
+        const layers::CSSAngle& angle = function.get_RotationX().angle();
+        arr = AppendTransformFunction(eCSSKeyword_rotatex, resultTail);
+        MOZ_TRY(SetCSSAngle(angle, arr->Item(1)));
+        break;
+      }
+      case layers::TransformFunction::TRotationY: {
+        const layers::CSSAngle& angle = function.get_RotationY().angle();
+        arr = AppendTransformFunction(eCSSKeyword_rotatey, resultTail);
+        MOZ_TRY(SetCSSAngle(angle, arr->Item(1)));
+        break;
+      }
+      case layers::TransformFunction::TRotationZ: {
+        const layers::CSSAngle& angle = function.get_RotationZ().angle();
+        arr = AppendTransformFunction(eCSSKeyword_rotatez, resultTail);
+        MOZ_TRY(SetCSSAngle(angle, arr->Item(1)));
+        break;
+      }
+      case layers::TransformFunction::TRotation: {
+        const layers::CSSAngle& angle = function.get_Rotation().angle();
+        arr = AppendTransformFunction(eCSSKeyword_rotate, resultTail);
+        MOZ_TRY(SetCSSAngle(angle, arr->Item(1)));
+        break;
+      }
+      case layers::TransformFunction::TRotation3D: {
+        float x = function.get_Rotation3D().x();
+        float y = function.get_Rotation3D().y();
+        float z = function.get_Rotation3D().z();
+        const layers::CSSAngle& angle = function.get_Rotation3D().angle();
+        arr = AppendTransformFunction(eCSSKeyword_rotate3d, resultTail);
+        arr->Item(1).SetFloatValue(x, eCSSUnit_Number);
+        arr->Item(2).SetFloatValue(y, eCSSUnit_Number);
+        arr->Item(3).SetFloatValue(z, eCSSUnit_Number);
+        MOZ_TRY(SetCSSAngle(angle, arr->Item(4)));
+        break;
+      }
+      case layers::TransformFunction::TScale: {
+        arr = AppendTransformFunction(eCSSKeyword_scale3d, resultTail);
+        arr->Item(1).SetFloatValue(function.get_Scale().x(), eCSSUnit_Number);
+        arr->Item(2).SetFloatValue(function.get_Scale().y(), eCSSUnit_Number);
+        arr->Item(3).SetFloatValue(function.get_Scale().z(), eCSSUnit_Number);
+        break;
+      }
+      case layers::TransformFunction::TTranslation: {
+        arr = AppendTransformFunction(eCSSKeyword_translate3d, resultTail);
+        arr->Item(1).SetFloatValue(function.get_Translation().x(),
+                                   eCSSUnit_Pixel);
+        arr->Item(2).SetFloatValue(function.get_Translation().y(),
+                                   eCSSUnit_Pixel);
+        arr->Item(3).SetFloatValue(function.get_Translation().z(),
+                                   eCSSUnit_Pixel);
+        break;
+      }
+      case layers::TransformFunction::TSkewX: {
+        const layers::CSSAngle& x = function.get_SkewX().x();
+        arr = AppendTransformFunction(eCSSKeyword_skewx, resultTail);
+        MOZ_TRY(SetCSSAngle(x, arr->Item(1)));
+        break;
+      }
+      case layers::TransformFunction::TSkewY: {
+        const layers::CSSAngle& y = function.get_SkewY().y();
+        arr = AppendTransformFunction(eCSSKeyword_skewy, resultTail);
+        MOZ_TRY(SetCSSAngle(y, arr->Item(1)));
+        break;
+      }
+      case layers::TransformFunction::TSkew: {
+        const layers::CSSAngle& x = function.get_Skew().x();
+        const layers::CSSAngle& y = function.get_Skew().y();
+        arr = AppendTransformFunction(eCSSKeyword_skew, resultTail);
+        MOZ_TRY(SetCSSAngle(x, arr->Item(1)));
+        MOZ_TRY(SetCSSAngle(y, arr->Item(2)));
+        break;
+      }
+      case layers::TransformFunction::TTransformMatrix: {
+        arr = AppendTransformFunction(eCSSKeyword_matrix3d, resultTail);
+        const gfx::Matrix4x4& matrix = function.get_TransformMatrix().value();
+        arr->Item(1).SetFloatValue(matrix._11, eCSSUnit_Number);
+        arr->Item(2).SetFloatValue(matrix._12, eCSSUnit_Number);
+        arr->Item(3).SetFloatValue(matrix._13, eCSSUnit_Number);
+        arr->Item(4).SetFloatValue(matrix._14, eCSSUnit_Number);
+        arr->Item(5).SetFloatValue(matrix._21, eCSSUnit_Number);
+        arr->Item(6).SetFloatValue(matrix._22, eCSSUnit_Number);
+        arr->Item(7).SetFloatValue(matrix._23, eCSSUnit_Number);
+        arr->Item(8).SetFloatValue(matrix._24, eCSSUnit_Number);
+        arr->Item(9).SetFloatValue(matrix._31, eCSSUnit_Number);
+        arr->Item(10).SetFloatValue(matrix._32, eCSSUnit_Number);
+        arr->Item(11).SetFloatValue(matrix._33, eCSSUnit_Number);
+        arr->Item(12).SetFloatValue(matrix._34, eCSSUnit_Number);
+        arr->Item(13).SetFloatValue(matrix._41, eCSSUnit_Number);
+        arr->Item(14).SetFloatValue(matrix._42, eCSSUnit_Number);
+        arr->Item(15).SetFloatValue(matrix._43, eCSSUnit_Number);
+        arr->Item(16).SetFloatValue(matrix._44, eCSSUnit_Number);
+        break;
+      }
+      case layers::TransformFunction::TPerspective: {
+        float perspective = function.get_Perspective().value();
+        arr = AppendTransformFunction(eCSSKeyword_perspective, resultTail);
+        arr->Item(1).SetFloatValue(perspective, eCSSUnit_Pixel);
+        break;
+      }
+      default:
+        NS_ASSERTION(false, "All functions should be implemented?");
+    }
+  }
+  if (aFunctions.Length() == 0) {
+    result = new nsCSSValueList();
+    result->mValue.SetNoneValue();
+  }
+  return new nsCSSValueSharedList(result.forget());
+}
+
 // AnimationValue Implementation
 
 bool AnimationValue::operator==(const AnimationValue& aOther) const {
   if (mServo && aOther.mServo) {
     return Servo_AnimationValue_DeepEqual(mServo, aOther.mServo);
   }
   if (!mServo && !aOther.mServo) {
     return true;
@@ -205,20 +348,39 @@ AnimationValue AnimationValue::Opacity(f
 
 /* static */
 AnimationValue AnimationValue::Transform(nsCSSValueSharedList& aList) {
   AnimationValue result;
   result.mServo = Servo_AnimationValue_Transform(aList).Consume();
   return result;
 }
 
-/* static */ already_AddRefed<nsCSSValue::Array>
-AnimationValue::AppendTransformFunction(nsCSSKeyword aTransformFunction,
-                                        nsCSSValueList**& aListTail) {
-  RefPtr<nsCSSValue::Array> arr = AppendFunction(aTransformFunction);
-  nsCSSValueList* item = new nsCSSValueList;
-  item->mValue.SetArrayValue(arr, eCSSUnit_Function);
+/* static */ already_AddRefed<RawServoAnimationValue>
+AnimationValue::FromAnimatable(nsCSSPropertyID aProperty,
+                               const layers::Animatable& aAnimatable) {
+  RefPtr<RawServoAnimationValue> result;
 
-  *aListTail = item;
-  aListTail = &item->mNext;
-
-  return arr.forget();
+  switch (aAnimatable.type()) {
+    case layers::Animatable::Tnull_t:
+      break;
+    case layers::Animatable::TArrayOfTransformFunction: {
+      const InfallibleTArray<layers::TransformFunction>& transforms =
+          aAnimatable.get_ArrayOfTransformFunction();
+      auto listOrError = CreateCSSValueList(transforms);
+      if (listOrError.isOk()) {
+        RefPtr<nsCSSValueSharedList> list = listOrError.unwrap();
+        MOZ_ASSERT(list, "Transform list should be non null");
+        result = Servo_AnimationValue_Transform(*list).Consume();
+      }
+      break;
+    }
+    case layers::Animatable::Tfloat:
+      result = Servo_AnimationValue_Opacity(aAnimatable.get_float()).Consume();
+      break;
+    case layers::Animatable::Tnscolor:
+      result = Servo_AnimationValue_Color(aProperty, aAnimatable.get_nscolor())
+                   .Consume();
+      break;
+    default:
+      MOZ_ASSERT_UNREACHABLE("Unsupported type");
+  }
+  return result.forget();
 }
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -32,16 +32,20 @@ class ComputedStyle;
 namespace css {
 class StyleRule;
 }  // namespace css
 
 namespace dom {
 class Element;
 }  // namespace dom
 
+namespace layers {
+class Animatable;
+}  // namespace layers
+
 enum class PseudoStyleType : uint8_t;
 struct PropertyStyleAnimationValuePair;
 
 struct AnimationValue {
   explicit AnimationValue(const RefPtr<RawServoAnimationValue>& aValue)
       : mServo(aValue) {}
   AnimationValue() = default;
 
@@ -100,19 +104,23 @@ struct AnimationValue {
   static AnimationValue FromString(nsCSSPropertyID aProperty,
                                    const nsAString& aValue,
                                    dom::Element* aElement);
 
   // Create an AnimationValue from an opacity value.
   static AnimationValue Opacity(float aOpacity);
   // Create an AnimationValue from a transform list.
   static AnimationValue Transform(nsCSSValueSharedList& aList);
-
-  static already_AddRefed<nsCSSValue::Array> AppendTransformFunction(
-      nsCSSKeyword aTransformFunction, nsCSSValueList**& aListTail);
+  // Create an already_AddRefed<RawServoAnimationValue> from a
+  // layers::Animatable. Basically, this function should return AnimationValue,
+  // but it seems the caller, AnimationHelper, only needs
+  // RawServoAnimationValue, so we return its already_AddRefed<> to avoid
+  // adding/removing a redundant ref-count.
+  static already_AddRefed<RawServoAnimationValue> FromAnimatable(
+      nsCSSPropertyID aProperty, const layers::Animatable& aAnimatable);
 
   RefPtr<RawServoAnimationValue> mServo;
 };
 
 struct PropertyStyleAnimationValuePair {
   nsCSSPropertyID mProperty;
   AnimationValue mValue;
 };