Bug 1338087 - Part 3: Append PropertyStyleAnimationValuePair from Servo side. draft
authorBoris Chiou <boris.chiou@gmail.com>
Sun, 12 Feb 2017 19:21:24 +0800
changeset 482526 df978e8e13872a743b292b0eac6eea3cf49dac9c
parent 482525 2f2e98121a46fcd8a20e87cbfdb4f0476143049c
child 545440 4498ff107c33607a7a5e457990a839669b3ce44f
push id45091
push userbmo:boris.chiou@gmail.com
push dateMon, 13 Feb 2017 03:23:13 +0000
bugs1338087
milestone54.0a1
Bug 1338087 - Part 3: Append PropertyStyleAnimationValuePair from Servo side. MozReview-Commit-ID: 8J4USSUmziu
dom/animation/KeyframeUtils.cpp
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
servo/components/style/build_gecko.rs
servo/components/style/gecko_bindings/bindings.rs
servo/components/style/properties/properties.mako.rs
servo/ports/geckolib/glue.rs
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -627,32 +627,16 @@ KeyframeUtils::GetComputedKeyframeValues
         continue;
       }
 
       // Expand each value into the set of longhands and produce
       // a KeyframeValueEntry for each value.
       nsTArray<PropertyStyleAnimationValuePair> values;
 
       if (styleBackend == StyleBackendType::Servo) {
-        // TODO: Append PropertyStyleAnimationPair from servo.
-        if (nsCSSProps::IsShorthand(pair.mProperty)) {
-          CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, pair.mProperty,
-                                               CSSEnabledState::eForAllContent) {
-            if (nsCSSProps::kAnimTypeTable[*p] == eStyleAnimType_None) {
-              // Skip non-animatable component longhands.
-              continue;
-            }
-            PropertyStyleAnimationValuePair* valuePair = values.AppendElement();
-            valuePair->mProperty = *p;
-          }
-        } else {
-          PropertyStyleAnimationValuePair* valuePair = values.AppendElement();
-          valuePair->mProperty = pair.mProperty;
-        }
-
         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.
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -397,16 +397,22 @@ Gecko_GetAnimationRule(RawGeckoElementBo
     presContext->EffectCompositor()
                ->GetServoAnimationRule(aElement, pseudoType, aCascadeLevel);
   if (!rule) {
     return emptyDeclarationBlock;
   }
   return rule->GetValues();
 }
 
+mozilla::PropertyStyleAnimationValuePair*
+Gecko_AppendAnimationValuePair(RawGeckoAnimationValueListBorrowedMut aArray)
+{
+  return aArray->AppendElement();
+}
+
 void
 Gecko_FillAllBackgroundLists(nsStyleImageLayers* aLayers, uint32_t aMaxLen)
 {
   nsRuleNode::FillAllBackgroundLists(*aLayers, aMaxLen);
 }
 
 void
 Gecko_FillAllMaskLists(nsStyleImageLayers* aLayers, uint32_t aMaxLen)
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -30,16 +30,17 @@ class nsIAtom;
 class nsIPrincipal;
 class nsIURI;
 struct nsFont;
 namespace mozilla {
   class ServoStyleSheet;
   class FontFamilyList;
   enum FontFamilyType : uint32_t;
   struct Keyframe;
+  struct PropertyStyleAnimationValuePair;
 }
 using mozilla::FontFamilyList;
 using mozilla::FontFamilyType;
 using mozilla::ServoElementSnapshot;
 struct nsMediaFeature;
 struct nsStyleList;
 struct nsStyleImage;
 struct nsStyleGradientStop;
@@ -162,16 +163,19 @@ RawServoDeclarationBlockStrongBorrowedOr
 Gecko_GetHTMLPresentationAttrDeclarationBlock(RawGeckoElementBorrowed element);
 
 // Animations
 RawServoDeclarationBlockStrong
 Gecko_GetAnimationRule(RawGeckoElementBorrowed aElement,
                        nsIAtom* aPseudoTag,
                        mozilla::EffectCompositor::CascadeLevel aCascadeLevel);
 
+mozilla::PropertyStyleAnimationValuePair*
+Gecko_AppendAnimationValuePair(RawGeckoAnimationValueListBorrowedMut aArray);
+
 // Atoms.
 nsIAtom* Gecko_Atomize(const char* aString, uint32_t aLength);
 void Gecko_AddRefAtom(nsIAtom* aAtom);
 void Gecko_ReleaseAtom(nsIAtom* aAtom);
 const uint16_t* Gecko_GetAtomAsUTF16(nsIAtom* aAtom, uint32_t* aLength);
 bool Gecko_AtomEqualsUTF8(nsIAtom* aAtom, const char* aString, uint32_t aLength);
 bool Gecko_AtomEqualsUTF8IgnoreCase(nsIAtom* aAtom, const char* aString, uint32_t aLength);
 
--- a/servo/components/style/build_gecko.rs
+++ b/servo/components/style/build_gecko.rs
@@ -569,16 +569,17 @@ mod bindings {
             "nsStyleXUL",
             "nsTimingFunction",
             "nscoord",
             "nsresult",
             "Loader",
             "ServoStyleSheet",
             "EffectCompositor_CascadeLevel",
             "RawServoAnimationValueBorrowedListBorrowed",
+            "PropertyStyleAnimationValuePair",
         ];
         struct ArrayType {
             cpp_type: &'static str,
             rust_type: &'static str
         }
         let array_types = [
             ArrayType { cpp_type: "uintptr_t", rust_type: "usize" },
         ];
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -7,16 +7,17 @@ use gecko_bindings::structs::RawGeckoDoc
 use gecko_bindings::structs::RawGeckoElement;
 use gecko_bindings::structs::RawGeckoKeyframeList;
 use gecko_bindings::structs::RawGeckoNode;
 use gecko_bindings::structs::RawGeckoAnimationValueList;
 use gecko_bindings::structs::RawServoAnimationValue;
 use gecko_bindings::structs::RawServoDeclarationBlock;
 use gecko_bindings::structs::RawGeckoPresContext;
 use gecko_bindings::structs::RawGeckoPresContextOwned;
+use gecko_bindings::structs::RefPtr;
 use gecko_bindings::structs::ThreadSafeURIHolder;
 use gecko_bindings::structs::ThreadSafePrincipalHolder;
 use gecko_bindings::structs::CSSPseudoClassType;
 use gecko_bindings::structs::TraversalRootBehavior;
 use gecko_bindings::structs::FontFamilyList;
 use gecko_bindings::structs::FontFamilyType;
 use gecko_bindings::structs::Keyframe;
 use gecko_bindings::structs::ServoElementSnapshot;
@@ -151,17 +152,17 @@ unsafe impl Send for nsStyleXUL {}
 unsafe impl Sync for nsStyleXUL {}
 use gecko_bindings::structs::nsTimingFunction;
 use gecko_bindings::structs::nscoord;
 use gecko_bindings::structs::nsresult;
 use gecko_bindings::structs::Loader;
 use gecko_bindings::structs::ServoStyleSheet;
 use gecko_bindings::structs::EffectCompositor_CascadeLevel;
 use gecko_bindings::structs::RawServoAnimationValueBorrowedListBorrowed;
-use gecko_bindings::structs::RefPtr;
+use gecko_bindings::structs::PropertyStyleAnimationValuePair;
 pub type nsTArrayBorrowed_uintptr_t<'a> = &'a mut ::gecko_bindings::structs::nsTArray<usize>;
 pub type ServoComputedValuesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoComputedValues>;
 pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues;
 pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>;
 enum ServoComputedValuesVoid { }
 pub struct ServoComputedValues(ServoComputedValuesVoid);
 pub type ServoCssRulesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoCssRules>;
 pub type ServoCssRulesBorrowed<'a> = &'a ServoCssRules;
@@ -510,16 +511,21 @@ extern "C" {
 extern "C" {
     pub fn Gecko_GetAnimationRule(aElement: RawGeckoElementBorrowed,
                                   aPseudoTag: *mut nsIAtom,
                                   aCascadeLevel:
                                       EffectCompositor_CascadeLevel)
      -> RawServoDeclarationBlockStrong;
 }
 extern "C" {
+    pub fn Gecko_AppendAnimationValuePair(aArray:
+                                              RawGeckoAnimationValueListBorrowedMut)
+     -> *mut PropertyStyleAnimationValuePair;
+}
+extern "C" {
     pub fn Gecko_Atomize(aString: *const ::std::os::raw::c_char, aLength: u32)
      -> *mut nsIAtom;
 }
 extern "C" {
     pub fn Gecko_AddRefAtom(aAtom: *mut nsIAtom);
 }
 extern "C" {
     pub fn Gecko_ReleaseAtom(aAtom: *mut nsIAtom);
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -714,16 +714,28 @@ impl<'a> PropertyDeclarationId<'a> {
     /// Whether a given declaration id is a longhand belonging to this
     /// shorthand.
     pub fn is_longhand_of(&self, shorthand: ShorthandId) -> bool {
         match *self {
             PropertyDeclarationId::Longhand(ref id) => shorthand.longhands().contains(id),
             _ => false,
         }
     }
+
+    /// Returns a nsCSSPropertyID.
+    #[cfg(feature = "gecko")]
+    #[allow(non_upper_case_globals)]
+    pub fn to_nscsspropertyid(&self) -> Result<nsCSSPropertyID, ()> {
+        match *self {
+            PropertyDeclarationId::Longhand(id) => {
+                PropertyId::Longhand(id).to_nscsspropertyid()
+            },
+            _ => Err(()),
+        }
+    }
 }
 
 /// Servo's representation of a CSS property, that is, either a longhand, a
 /// shorthand, or a custom property.
 #[derive(Eq, PartialEq, Clone)]
 pub enum PropertyId {
     /// A longhand property.
     Longhand(LonghandId),
@@ -800,17 +812,17 @@ impl PropertyId {
                         Ok(PropertyId::Shorthand(ShorthandId::${property.camel_case}))
                     }
                 % endfor
             % endfor
             _ => Err(())
         }
     }
 
-    /// Returns a property id from Gecko's nsCSSPropertyID.
+    /// Returns a Gecko's nsCSSPropertyID from the property id.
     #[cfg(feature = "gecko")]
     #[allow(non_upper_case_globals)]
     pub fn to_nscsspropertyid(&self) -> Result<nsCSSPropertyID, ()> {
         use gecko_bindings::structs::*;
 
         match *self {
             PropertyId::Longhand(id) => match id {
                 % for property in data.longhands:
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -32,16 +32,17 @@ use style::gecko_bindings::bindings;
 use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong};
 use style::gecko_bindings::bindings::{RawServoStyleRuleBorrowed, RawServoStyleRuleStrong};
 use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned};
 use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
 use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
 use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
 use style::gecko_bindings::bindings::{nsACString, nsCSSValueBorrowedMut, nsAString};
 use style::gecko_bindings::bindings::Gecko_AnimationAppendKeyframe;
+use style::gecko_bindings::bindings::Gecko_AppendAnimationValuePair;
 use style::gecko_bindings::bindings::RawGeckoAnimationValueListBorrowedMut;
 use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
 use style::gecko_bindings::bindings::RawGeckoKeyframeListBorrowedMut;
 use style::gecko_bindings::bindings::RawGeckoPresContextBorrowed;
 use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
 use style::gecko_bindings::bindings::RawServoAnimationValueStrong;
 use style::gecko_bindings::bindings::RawServoImportRuleBorrowed;
 use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
@@ -291,37 +292,29 @@ pub extern "C" fn Servo_AnimationValues_
         style: (**style).clone(),
         font_metrics_provider: None,
     };
 
     let mut iter = guard.declarations
                     .iter()
                     .filter_map(|&(ref decl, imp)| {
                         if imp == Importance::Normal {
-                            AnimationValue::from_declaration(decl, &context, &init)
+                            match AnimationValue::from_declaration(decl, &context, &init) {
+                                Some(v) => Some((decl.id().to_nscsspropertyid(), v)),
+                                None => None,
+                            }
                         } else {
                             None
                         }
                     });
 
-    let mut geckoiter = anim.iter_mut();
-    {
-        // we reborrow to scope the consumed mutable borrow
-        // we need to be able to ensure geckoiter is empty later on
-        // and thus can't directly use `geckoiter`
-        let local_geckoiter = &mut geckoiter;
-        for (gecko, servo) in local_geckoiter.zip(&mut iter) {
-            gecko.mValue.mServo.set_arc_leaky(Arc::new(servo));
-        }
-    }
-
-    // we should have gone through both iterators
-    if iter.next().is_some() || geckoiter.next().is_some() {
-        error!("stylo: Mismatched sizes of Gecko and Servo \
-                array during animation value construction");
+    for (id, value) in &mut iter {
+        let mut pair = unsafe { &mut *Gecko_AppendAnimationValuePair(anim) };
+        pair.mProperty = id.expect("Invalid animated css property");
+        pair.mValue.mServo.set_arc_leaky(Arc::new(value));
     }
 }
 
 
 #[no_mangle]
 pub extern "C" fn Servo_AnimationValue_AddRef(anim: RawServoAnimationValueBorrowed) -> () {
     unsafe { AnimationValue::addref(anim) };
 }