Bug 1302949 - Compute StyleAnimationValue objects from servo declaration blocks; r=heycam draft
authorBrian Birtles <birtles@gmail.com>
Fri, 16 Sep 2016 11:08:44 +0900
changeset 421002 570ed28437ecaa22ac7571a9b47388e8abd0cb96
parent 421001 d2dc5162ff6331dd4613e00ddb0bca9ed5f54ff0
child 421003 c0330b104afb4b970569c0cb650315e633b7e796
push id31345
push userbbirtles@mozilla.com
push dateWed, 05 Oct 2016 02:47:30 +0000
reviewersheycam
bugs1302949
milestone52.0a1
Bug 1302949 - Compute StyleAnimationValue objects from servo declaration blocks; r=heycam MozReview-Commit-ID: 6Am1FRC9uV0
dom/animation/KeyframeUtils.cpp
layout/style/ServoBindingList.h
layout/style/StyleAnimationValue.cpp
layout/style/StyleAnimationValue.h
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -611,35 +611,43 @@ KeyframeUtils::GetComputedKeyframeValues
       if (IsInvalidValuePair(pair, styleBackend)) {
         continue;
       }
 
       // Expand each value into the set of longhands and produce
       // a KeyframeValueEntry for each value.
       nsTArray<PropertyStyleAnimationValuePair> values;
 
-      // 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 (styleBackend == StyleBackendType::Servo) {
         if (!StyleAnimationValue::ComputeValues(pair.mProperty,
-              CSSEnabledState::eForAllContent, aElement, aStyleContext,
-              tokenStream->mTokenStream, /* aUseSVGMode */ false, values) ||
-            IsComputeValuesFailureKey(pair)) {
+              CSSEnabledState::eForAllContent, aStyleContext,
+              *pair.mServoDeclarationBlock, values)) {
           continue;
         }
       } else {
-        if (!StyleAnimationValue::ComputeValues(pair.mProperty,
-              CSSEnabledState::eForAllContent, aElement, aStyleContext,
-              pair.mValue, /* aUseSVGMode */ false, values)) {
-          continue;
+        // 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) ||
+              IsComputeValuesFailureKey(pair)) {
+            continue;
+          }
+        } else {
+          if (!StyleAnimationValue::ComputeValues(pair.mProperty,
+                CSSEnabledState::eForAllContent, aElement, aStyleContext,
+                pair.mValue, /* aUseSVGMode */ false, values)) {
+            continue;
+          }
+          MOZ_ASSERT(values.Length() == 1,
+                    "Longhand properties should produce a single"
+                    " StyleAnimationValue");
         }
-        MOZ_ASSERT(values.Length() == 1,
-                   "Longhand properties should produce a single"
-                   " StyleAnimationValue");
       }
 
       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;
         }
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -54,16 +54,20 @@ SERVO_BINDING_FUNC(Servo_ParseProperty,
                    uint32_t property_length,
                    const uint8_t* value_bytes,
                    uint32_t value_length,
                    const uint8_t* base_bytes,
                    uint32_t base_length,
                    ThreadSafeURIHolder* base,
                    ThreadSafeURIHolder* referrer,
                    ThreadSafePrincipalHolder* principal)
+SERVO_BINDING_FUNC(Servo_RestyleWithAddedDeclaration,
+                   ServoComputedValuesStrong,
+                   ServoDeclarationBlockBorrowed declarations,
+                   ServoComputedValuesBorrowed previous_style)
 
 // Style attribute
 SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, ServoDeclarationBlockStrong,
                    const uint8_t* bytes, uint32_t length,
                    nsHTMLCSSStyleSheet* cache)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_AddRef, void,
                    ServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_Release, void,
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -22,16 +22,17 @@
 #include "nsStyleSet.h"
 #include "nsComputedDOMStyle.h"
 #include "nsCSSParser.h"
 #include "nsCSSPseudoElements.h"
 #include "mozilla/css/Declaration.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/Likely.h"
+#include "mozilla/ServoBindings.h" // ServoDeclarationBlock
 #include "gfxMatrix.h"
 #include "gfxQuaternion.h"
 #include "nsIDocument.h"
 #include "nsIFrame.h"
 #include "gfx2DGlue.h"
 
 using namespace mozilla;
 using namespace mozilla::css;
@@ -3032,16 +3033,47 @@ BuildStyleRule(nsCSSPropertyID aProperty
   declaration->ValueAppended(aProperty);
   declaration->CompressFrom(&block);
 
   RefPtr<css::StyleRule> rule = new css::StyleRule(nullptr, declaration, 0, 0);
   return rule.forget();
 }
 
 static bool
+ComputeValuesFromStyleContext(
+  nsCSSPropertyID aProperty,
+  CSSEnabledState aEnabledState,
+  nsStyleContext* aStyleContext,
+  nsTArray<PropertyStyleAnimationValuePair>& aValues)
+{
+  // Extract computed value of our property (or all longhand components, if
+  // aProperty is a shorthand) from the temporary style context
+  if (nsCSSProps::IsShorthand(aProperty)) {
+    CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty, aEnabledState) {
+      if (nsCSSProps::kAnimTypeTable[*p] == eStyleAnimType_None) {
+        // Skip non-animatable component longhands.
+        continue;
+      }
+      PropertyStyleAnimationValuePair* pair = aValues.AppendElement();
+      pair->mProperty = *p;
+      if (!StyleAnimationValue::ExtractComputedValue(*p, aStyleContext,
+                                                     pair->mValue)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  PropertyStyleAnimationValuePair* pair = aValues.AppendElement();
+  pair->mProperty = aProperty;
+  return StyleAnimationValue::ExtractComputedValue(aProperty, aStyleContext,
+                                                   pair->mValue);
+}
+
+static bool
 ComputeValuesFromStyleRule(nsCSSPropertyID aProperty,
                            CSSEnabledState aEnabledState,
                            nsStyleContext* aStyleContext,
                            css::StyleRule* aStyleRule,
                            nsTArray<PropertyStyleAnimationValuePair>& aValues,
                            bool* aIsContextSensitive)
 {
   MOZ_ASSERT(aStyleContext);
@@ -3094,38 +3126,18 @@ ComputeValuesFromStyleRule(nsCSSProperty
     declaration->SetImmutable();
     tmpStyleContext =
       styleSet->ResolveStyleByAddingRules(aStyleContext, ruleArray);
     if (!tmpStyleContext) {
       return false;
     }
   }
 
-  // Extract computed value of our property (or all longhand components, if
-  // aProperty is a shorthand) from the temporary style rule
-  if (nsCSSProps::IsShorthand(aProperty)) {
-    CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty, aEnabledState) {
-      if (nsCSSProps::kAnimTypeTable[*p] == eStyleAnimType_None) {
-        // Skip non-animatable component longhands.
-        continue;
-      }
-      PropertyStyleAnimationValuePair* pair = aValues.AppendElement();
-      pair->mProperty = *p;
-      if (!StyleAnimationValue::ExtractComputedValue(*p, tmpStyleContext,
-                                                     pair->mValue)) {
-        return false;
-      }
-    }
-    return true;
-  } else {
-    PropertyStyleAnimationValuePair* pair = aValues.AppendElement();
-    pair->mProperty = aProperty;
-    return StyleAnimationValue::ExtractComputedValue(aProperty, tmpStyleContext,
-                                                     pair->mValue);
-  }
+  return ComputeValuesFromStyleContext(aProperty, aEnabledState,
+                                       tmpStyleContext, aValues);
 }
 
 /* static */ bool
 StyleAnimationValue::ComputeValue(nsCSSPropertyID aProperty,
                                   dom::Element* aTargetElement,
                                   nsStyleContext* aStyleContext,
                                   const nsAString& aSpecifiedValue,
                                   bool aUseSVGMode,
@@ -3228,16 +3240,55 @@ StyleAnimationValue::ComputeValues(
     nsTArray<PropertyStyleAnimationValuePair>& aResult)
 {
   return ComputeValuesFromSpecifiedValue(aProperty, aEnabledState,
                                          aTargetElement, aStyleContext,
                                          aSpecifiedValue, aUseSVGMode,
                                          aResult);
 }
 
+/* static */ bool
+StyleAnimationValue::ComputeValues(
+  nsCSSPropertyID aProperty,
+  CSSEnabledState aEnabledState,
+  nsStyleContext* aStyleContext,
+  const ServoDeclarationBlock& aDeclarations,
+  nsTArray<PropertyStyleAnimationValuePair>& aValues)
+{
+  MOZ_ASSERT(aStyleContext->PresContext()->StyleSet()->IsServo(),
+             "Should be using ServoStyleSet if we have a"
+             " ServoDeclarationBlock");
+
+  if (!nsCSSProps::IsEnabled(aProperty, aEnabledState)) {
+    return false;
+  }
+
+  RefPtr<ServoComputedValues> previousStyle =
+    aStyleContext->StyleSource().AsServoComputedValues();
+
+  // FIXME: Servo bindings don't yet represent const-ness so we just
+  // cast it away for now.
+  auto declarations = const_cast<ServoDeclarationBlock*>(&aDeclarations);
+  RefPtr<ServoComputedValues> computedValues =
+    Servo_RestyleWithAddedDeclaration(declarations, previousStyle).Consume();
+  if (!computedValues) {
+    return false;
+  }
+
+  RefPtr<nsStyleContext> tmpStyleContext =
+    NS_NewStyleContext(aStyleContext, aStyleContext->PresContext(),
+                       aStyleContext->GetPseudo(),
+                       aStyleContext->GetPseudoType(),
+                       computedValues.forget(),
+                       false /* skipFixup */);
+
+  return ComputeValuesFromStyleContext(aProperty, aEnabledState,
+                                       tmpStyleContext, aValues);
+}
+
 bool
 StyleAnimationValue::UncomputeValue(nsCSSPropertyID aProperty,
                                     const StyleAnimationValue& aComputedValue,
                                     nsCSSValue& aSpecifiedValue)
 {
   Unit unit = aComputedValue.GetUnit();
   switch (unit) {
     case eUnit_Normal:
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -15,16 +15,17 @@
 #include "nsCoord.h"
 #include "nsColor.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 
 class nsIFrame;
 class nsStyleContext;
 class gfx3DMatrix;
+struct ServoDeclarationBlock;
 
 namespace mozilla {
 
 namespace css {
 class StyleRule;
 } // namespace css
 
 namespace dom {
@@ -231,16 +232,27 @@ public:
                 mozilla::CSSEnabledState aEnabledState,
                 mozilla::dom::Element* aTargetElement,
                 nsStyleContext* aStyleContext,
                 const nsCSSValue& aSpecifiedValue,
                 bool aUseSVGMode,
                 nsTArray<PropertyStyleAnimationValuePair>& aResult);
 
   /**
+   * A variant of ComputeValues that takes a ServoDeclarationBlock as the
+   * specified value.
+   */
+  static MOZ_MUST_USE bool
+  ComputeValues(nsCSSPropertyID aProperty,
+                mozilla::CSSEnabledState aEnabledState,
+                nsStyleContext* aStyleContext,
+                const ServoDeclarationBlock& aDeclarations,
+                nsTArray<PropertyStyleAnimationValuePair>& aValues);
+
+  /**
    * Creates a specified value for the given computed value.
    *
    * The first two overloads fill in an nsCSSValue object; the third
    * produces a string.  For the overload that takes a const
    * StyleAnimationValue& reference, the nsCSSValue result may depend on
    * objects owned by the |aComputedValue| object, so users of that variant
    * must keep |aComputedValue| alive longer than |aSpecifiedValue|.
    * The overload that takes an rvalue StyleAnimationValue reference