Bug 1317208 - Stylo: Store servo computed values for animation properties; r?birtles,heycam draft
authorManish Goregaokar <manishearth@gmail.com>
Wed, 30 Nov 2016 17:34:54 -0800
changeset 459411 7c9b22a2ea2bebd7a0886cbd63af1e47a548cbb7
parent 459259 63ad56438630b389efdb01632e153143cf3008ec
child 541890 ae1936bfb3298f746c9c8e3352baac55b2665ecb
push id41216
push userbmo:manishearth@gmail.com
push dateWed, 11 Jan 2017 22:29:31 +0000
reviewersbirtles, heycam
bugs1317208
milestone53.0a1
Bug 1317208 - Stylo: Store servo computed values for animation properties; r?birtles,heycam MozReview-Commit-ID: IoQLN5tdIBw
dom/animation/KeyframeEffectReadOnly.h
dom/animation/KeyframeUtils.cpp
layout/style/ServoArcTypeList.h
layout/style/ServoBindingList.h
layout/style/ServoBindingTypes.h
layout/style/StyleAnimationValue.h
--- a/dom/animation/KeyframeEffectReadOnly.h
+++ b/dom/animation/KeyframeEffectReadOnly.h
@@ -15,18 +15,18 @@
 #include "nsTArray.h"
 #include "nsWrapperCache.h"
 #include "mozilla/AnimationPerformanceWarning.h"
 #include "mozilla/AnimationTarget.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ComputedTimingFunction.h"
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/KeyframeEffectParams.h"
-#include "mozilla/ServoBindingTypes.h" // RawServoDeclarationBlock and
-                                       // associated RefPtrTraits
+// RawServoDeclarationBlock and associated RefPtrTraits
+#include "mozilla/ServoBindingTypes.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/dom/AnimationEffectReadOnly.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/Element.h"
 
 struct JSContext;
 class JSObject;
 class nsIContent;
@@ -118,16 +118,19 @@ struct Keyframe
 };
 
 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;
+
   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 &&
            mToKey == aOther.mToKey &&
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -5,28 +5,30 @@
 
 #include "mozilla/KeyframeUtils.h"
 
 #include "mozilla/AnimationUtils.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/Move.h"
 #include "mozilla/RangedArray.h"
 #include "mozilla/ServoBindings.h"
+#include "mozilla/ServoBindingTypes.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/TimingParams.h"
 #include "mozilla/dom/BaseKeyframeTypesBinding.h" // For FastBaseKeyframe etc.
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/KeyframeEffectBinding.h"
 #include "mozilla/dom/KeyframeEffectReadOnly.h" // For PropertyValuesPair etc.
 #include "jsapi.h" // For ForOfIterator etc.
 #include "nsClassHashtable.h"
 #include "nsCSSParser.h"
 #include "nsCSSPropertyIDSet.h"
 #include "nsCSSProps.h"
 #include "nsCSSPseudoElements.h" // For CSSPseudoElementType
+#include "nsStyleContext.h"
 #include "nsTArray.h"
 #include <algorithm> // For std::stable_sort
 
 namespace mozilla {
 
 // ------------------------------------------------------------------
 //
 // Internal data types
@@ -265,16 +267,18 @@ struct AdditionalProperty
  *
  * KeyframeValueEntry is used in GetAnimationPropertiesFromKeyframes
  * to gather data for each individual segment.
  */
 struct KeyframeValueEntry
 {
   nsCSSPropertyID mProperty;
   StyleAnimationValue mValue;
+  RefPtr<RawServoAnimationValue> mServoValue;
+
   float mOffset;
   Maybe<ComputedTimingFunction> mTimingFunction;
   dom::CompositeOperation mComposite;
 
   struct PropertyOffsetComparator
   {
     static bool Equals(const KeyframeValueEntry& aLhs,
                        const KeyframeValueEntry& aRhs)
@@ -595,16 +599,26 @@ KeyframeUtils::GetComputedKeyframeValues
   MOZ_ASSERT(aStyleContext);
   MOZ_ASSERT(aElement);
 
   StyleBackendType styleBackend = aElement->OwnerDoc()->GetStyleBackendType();
 
   const size_t len = aKeyframes.Length();
   nsTArray<ComputedKeyframeValues> result(len);
 
+  const ServoComputedValues* currentStyle = nullptr;
+  const ServoComputedValues* parentStyle = nullptr;
+
+  if (styleBackend == StyleBackendType::Servo) {
+    currentStyle = aStyleContext->StyleSource().AsServoComputedValues();
+    if (aStyleContext->GetParent()) {
+      parentStyle = aStyleContext->GetParent()->StyleSource().AsServoComputedValues();
+    }
+  }
+
   for (const Keyframe& frame : aKeyframes) {
     nsCSSPropertyIDSet propertiesOnThisKeyframe;
     ComputedKeyframeValues* computedValues = result.AppendElement();
     for (const PropertyValuePair& pair :
            PropertyPriorityIterator(frame.mPropertyValues)) {
       MOZ_ASSERT(!pair.mServoDeclarationBlock ||
                  styleBackend == StyleBackendType::Servo,
                  "Animation values were parsed using Servo backend but target"
@@ -619,16 +633,21 @@ KeyframeUtils::GetComputedKeyframeValues
       nsTArray<PropertyStyleAnimationValuePair> values;
 
       if (styleBackend == StyleBackendType::Servo) {
         if (!StyleAnimationValue::ComputeValues(pair.mProperty,
               CSSEnabledState::eForAllContent, aStyleContext,
               *pair.mServoDeclarationBlock, values)) {
           continue;
         }
+        Servo_AnimationValues_Populate(&values,
+                                       pair.mServoDeclarationBlock,
+                                       currentStyle,
+                                       parentStyle,
+                                       aStyleContext->PresContext());
       } else {
         // For shorthands, we store the string as a token stream so we need to
         // extract that first.
         if (nsCSSProps::IsShorthand(pair.mProperty)) {
           nsCSSValueTokenStream* tokenStream = pair.mValue.GetTokenStreamValue();
           if (!StyleAnimationValue::ComputeValues(pair.mProperty,
                 CSSEnabledState::eForAllContent, aElement, aStyleContext,
                 tokenStream->mTokenStream, /* aUseSVGMode */ false, values) ||
@@ -648,18 +667,18 @@ KeyframeUtils::GetComputedKeyframeValues
       }
 
       for (auto& value : values) {
         // If we already got a value for this property on the keyframe,
         // skip this one.
         if (propertiesOnThisKeyframe.HasProperty(value.mProperty)) {
           continue;
         }
-        computedValues->AppendElement(value);
         propertiesOnThisKeyframe.AddProperty(value.mProperty);
+        computedValues->AppendElement(Move(value));
       }
     }
   }
 
   MOZ_ASSERT(result.Length() == aKeyframes.Length(), "Array length mismatch");
   return result;
 }
 
@@ -680,16 +699,17 @@ KeyframeUtils::GetAnimationPropertiesFro
     const Keyframe& frame = aKeyframes[i];
     for (auto& value : aComputedValues[i]) {
       MOZ_ASSERT(frame.mComputedOffset != Keyframe::kComputedOffsetNotSet,
                  "Invalid computed offset");
       KeyframeValueEntry* entry = entries.AppendElement();
       entry->mOffset = frame.mComputedOffset;
       entry->mProperty = value.mProperty;
       entry->mValue = value.mValue;
+      entry->mServoValue = value.mServoValue;
       entry->mTimingFunction = frame.mTimingFunction;
       entry->mComposite =
         frame.mComposite ? frame.mComposite.value() : aEffectComposite;
     }
   }
 
   nsTArray<AnimationProperty> result;
   BuildSegmentsFromValueEntries(entries, result);
@@ -1366,23 +1386,25 @@ BuildSegmentsFromValueEntries(nsTArray<K
       lastProperty = aEntries[i].mProperty;
     }
 
     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;
-    segment->mToValue   = aEntries[j].mValue;
+    segment->mFromKey        = aEntries[i].mOffset;
+    segment->mToKey          = aEntries[j].mOffset;
+    segment->mFromValue      = aEntries[i].mValue;
+    segment->mToValue        = aEntries[j].mValue;
+    segment->mServoFromValue = aEntries[i].mServoValue;
+    segment->mServoToValue   = aEntries[j].mServoValue;
     segment->mTimingFunction = aEntries[i].mTimingFunction;
-    segment->mFromComposite = aEntries[i].mComposite;
-    segment->mToComposite = aEntries[j].mComposite;
+    segment->mFromComposite  = aEntries[i].mComposite;
+    segment->mToComposite    = aEntries[j].mComposite;
 
     i = j;
   }
 }
 
 /**
  * Converts a JS object representing a property-indexed keyframe into
  * an array of Keyframe objects.
--- a/layout/style/ServoArcTypeList.h
+++ b/layout/style/ServoArcTypeList.h
@@ -7,8 +7,9 @@
 /* a list of all Servo Arc types used in stylo bindings for preprocessing */
 
 SERVO_ARC_TYPE(CssRules, ServoCssRules)
 SERVO_ARC_TYPE(StyleSheet, RawServoStyleSheet)
 SERVO_ARC_TYPE(ComputedValues, ServoComputedValues)
 SERVO_ARC_TYPE(DeclarationBlock, RawServoDeclarationBlock)
 SERVO_ARC_TYPE(StyleRule, RawServoStyleRule)
 SERVO_ARC_TYPE(ImportRule, RawServoImportRule)
+SERVO_ARC_TYPE(AnimationValue, RawServoAnimationValue)
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -102,16 +102,24 @@ SERVO_BINDING_FUNC(Servo_ParseProperty,
                    ThreadSafeURIHolder* referrer,
                    ThreadSafePrincipalHolder* principal)
 SERVO_BINDING_FUNC(Servo_RestyleWithAddedDeclaration,
                    ServoComputedValuesStrong,
                    RawServoStyleSetBorrowed set,
                    RawServoDeclarationBlockBorrowed declarations,
                    ServoComputedValuesBorrowed previous_style)
 
+// AnimationValues handling
+SERVO_BINDING_FUNC(Servo_AnimationValues_Populate, void,
+                   RawGeckoAnimationValueListBorrowedMut,
+                   RawServoDeclarationBlockBorrowed,
+                   ServoComputedValuesBorrowed,
+                   ServoComputedValuesBorrowedOrNull,
+                   RawGeckoPresContextBorrowed)
+
 // Style attribute
 SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, RawServoDeclarationBlockStrong,
                    const nsACString* data)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_CreateEmpty,
                    RawServoDeclarationBlockStrong)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_Clone, RawServoDeclarationBlockStrong,
                    RawServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_Equals, bool,
--- a/layout/style/ServoBindingTypes.h
+++ b/layout/style/ServoBindingTypes.h
@@ -3,44 +3,49 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_ServoBindingTypes_h
 #define mozilla_ServoBindingTypes_h
 
 #include "mozilla/RefPtr.h"
+#include "mozilla/ServoTypes.h"
 #include "mozilla/UniquePtr.h"
+#include "nsTArray.h"
 
+struct RawServoAnimationValue;
 struct RawServoStyleSet;
 
 #define SERVO_ARC_TYPE(name_, type_) struct type_;
 #include "mozilla/ServoArcTypeList.h"
 #undef SERVO_ARC_TYPE
 
 namespace mozilla {
   class ServoElementSnapshot;
 namespace dom {
 class Element;
 class StyleChildrenIterator;
 } // namespace dom
+struct PropertyStyleAnimationValuePair;
 } // namespace mozilla
 
 class nsCSSValue;
 class nsIDocument;
 class nsINode;
 class nsPresContext;
 
 using mozilla::dom::StyleChildrenIterator;
 using mozilla::ServoElementSnapshot;
 
 typedef nsINode RawGeckoNode;
 typedef mozilla::dom::Element RawGeckoElement;
 typedef nsIDocument RawGeckoDocument;
 typedef nsPresContext RawGeckoPresContext;
+typedef nsTArray<mozilla::PropertyStyleAnimationValuePair> RawGeckoAnimationValueList;
 
 // We have these helper types so that we can directly generate
 // things like &T or Borrowed<T> on the Rust side in the function, providing
 // additional safety benefits.
 //
 // FFI has a problem with templated types, so we just use raw pointers here.
 //
 // The "Borrowed" types generate &T or Borrowed<T> in the nullable case.
@@ -98,16 +103,17 @@ DECL_BORROWED_REF_TYPE_FOR(RawGeckoEleme
 DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoElement)
 DECL_BORROWED_REF_TYPE_FOR(RawGeckoDocument)
 DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoDocument)
 DECL_BORROWED_MUT_REF_TYPE_FOR(StyleChildrenIterator)
 DECL_BORROWED_MUT_REF_TYPE_FOR(ServoElementSnapshot)
 DECL_BORROWED_REF_TYPE_FOR(nsCSSValue)
 DECL_BORROWED_MUT_REF_TYPE_FOR(nsCSSValue)
 DECL_BORROWED_REF_TYPE_FOR(RawGeckoPresContext)
+DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoAnimationValueList)
 
 #undef DECL_ARC_REF_TYPE_FOR
 #undef DECL_OWNED_REF_TYPE_FOR
 #undef DECL_NULLABLE_OWNED_REF_TYPE_FOR
 #undef DECL_BORROWED_REF_TYPE_FOR
 #undef DECL_NULLABLE_BORROWED_REF_TYPE_FOR
 #undef DECL_BORROWED_MUT_REF_TYPE_FOR
 #undef DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR
@@ -125,23 +131,27 @@ DECL_BORROWED_REF_TYPE_FOR(RawGeckoPresC
     static void Release(type_* aPtr) {               \
       Servo_##name_##_Release(aPtr);                 \
     }                                                \
   };                                                 \
   }
 #include "mozilla/ServoArcTypeList.h"
 #undef SERVO_ARC_TYPE
 
-extern "C" void Servo_StyleSet_Drop(RawServoStyleSetOwned ptr);
+#define DEFINE_BOXED_TYPE(name_, type_)                     \
+  extern "C" void Servo_##name_##_Drop(type_##Owned ptr);   \
+  namespace mozilla {                                       \
+  template<>                                                \
+  class DefaultDelete<type_>                                \
+  {                                                         \
+  public:                                                   \
+    void operator()(type_* aPtr) const                      \
+    {                                                       \
+      Servo_##name_##_Drop(aPtr);                           \
+    }                                                       \
+  };                                                        \
+  }
 
-namespace mozilla {
-template<>
-class DefaultDelete<RawServoStyleSet>
-{
-public:
-  void operator()(RawServoStyleSet* aPtr) const
-  {
-    Servo_StyleSet_Drop(aPtr);
-  }
-};
-}
+DEFINE_BOXED_TYPE(StyleSet, RawServoStyleSet);
+
+#undef DEFINE_BOXED_TYPE
 
 #endif // mozilla_ServoBindingTypes_h
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Utilities for animation of computed style values */
 
 #ifndef mozilla_StyleAnimationValue_h_
 #define mozilla_StyleAnimationValue_h_
 
 #include "mozilla/gfx/MatrixFwd.h"
+#include "mozilla/ServoBindingTypes.h"
 #include "mozilla/UniquePtr.h"
 #include "nsStringFwd.h"
 #include "nsStringBuffer.h"
 #include "nsCoord.h"
 #include "nsColor.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 #include "nsStyleCoord.h"
@@ -580,12 +581,13 @@ private:
     return aUnit == eUnit_UnparsedString;
   }
 };
 
 struct PropertyStyleAnimationValuePair
 {
   nsCSSPropertyID mProperty;
   StyleAnimationValue mValue;
+  RefPtr<RawServoAnimationValue> mServoValue;
 };
 } // namespace mozilla
 
 #endif