From b21081312411d5dc0ebc0b3779e3ad1845870b0f Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 17 Mar 2017 12:31:38 +0900 Subject: [PATCH] Put computed values into AnimationValueMap instead of hashtable in gecko. Before this patch, we store each computed values in a hashtable, nsRefPtrHashtable, for all KeyframeEffectReadOnly on an element, and convert the ServoAnimationValues of the hashtable into an nsTArray and then convert the ServoAnimationValues of the nsTArray into PropertyDeclarationBlock in rust. This way was really inefficient. In this patch, we store the computed values into AnimationValueMap and convert all AnimationValue in the map into PropertyDeclarationBlock after EffectCompositor::GetAnimationRule. --- components/style/gecko/wrapper.rs | 21 +++++++++++++++---- components/style/gecko_bindings/bindings.rs | 13 ++++++++++-- .../style/gecko_bindings/structs_debug.rs | 3 --- .../style/gecko_bindings/structs_release.rs | 3 --- ports/geckolib/glue.rs | 13 ++++++++++++ 5 files changed, 41 insertions(+), 12 deletions(-) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 4182685ec49..a722677e78f 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -46,6 +46,7 @@ use parking_lot::RwLock; use parser::ParserContextExtraData; use properties::{ComputedValues, parse_style_attribute}; use properties::PropertyDeclarationBlock; +use properties::animated_properties::AnimationValueMap; use rule_tree::CascadeLevel as ServoCascadeLevel; use selector_parser::{ElementExt, Snapshot}; use selectors::Element; @@ -403,6 +404,20 @@ fn selector_flags_to_node_flags(flags: ElementSelectorFlags) -> u32 { gecko_flags } +fn get_animation_rule(element: &GeckoElement, + pseudo: Option<&PseudoElement>, + cascade_level: CascadeLevel) + -> Option>> { + let atom_ptr = PseudoElement::ns_atom_or_null_from_opt(pseudo); + let animation_values = Arc::new(RwLock::new(AnimationValueMap::new())); + if unsafe { Gecko_GetAnimationRule(element.0, atom_ptr, cascade_level, + HasArcFFI::arc_as_borrowed(&animation_values)) } { + Some(Arc::new(RwLock::new(PropertyDeclarationBlock::from_animation_value_map(&animation_values.read())))) + } else { + None + } +} + impl<'le> TElement for GeckoElement<'le> { type ConcreteNode = GeckoNode<'le>; @@ -422,14 +437,12 @@ impl<'le> TElement for GeckoElement<'le> { fn get_animation_rule(&self, pseudo: Option<&PseudoElement>) -> Option>> { - let atom_ptr = PseudoElement::ns_atom_or_null_from_opt(pseudo); - unsafe { Gecko_GetAnimationRule(self.0, atom_ptr, CascadeLevel::Animations).into_arc_opt() } + get_animation_rule(self, pseudo, CascadeLevel::Animations) } fn get_transition_rule(&self, pseudo: Option<&PseudoElement>) -> Option>> { - let atom_ptr = PseudoElement::ns_atom_or_null_from_opt(pseudo); - unsafe { Gecko_GetAnimationRule(self.0, atom_ptr, CascadeLevel::Transitions).into_arc_opt() } + get_animation_rule(self, pseudo, CascadeLevel::Transitions) } fn get_state(&self) -> ElementState { diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko_bindings/bindings.rs index 81d8b2f3ca1..466421556a4 100644 --- a/components/style/gecko_bindings/bindings.rs +++ b/components/style/gecko_bindings/bindings.rs @@ -582,8 +582,10 @@ extern "C" { pub fn Gecko_GetAnimationRule(aElement: RawGeckoElementBorrowed, aPseudoTag: *mut nsIAtom, aCascadeLevel: - EffectCompositor_CascadeLevel) - -> RawServoDeclarationBlockStrong; + EffectCompositor_CascadeLevel, + aAnimationValues: + RawServoAnimationValueMapBorrowed) + -> bool; } extern "C" { pub fn Gecko_StyleAnimationsEquals(arg1: @@ -1496,6 +1498,13 @@ extern "C" { result: RawGeckoComputedKeyframeValuesListBorrowedMut); } +extern "C" { + pub fn Servo_AnimationValueMap_Push(arg1: + RawServoAnimationValueMapBorrowed, + property: nsCSSPropertyID, + value: + RawServoAnimationValueBorrowed); +} extern "C" { pub fn Servo_AnimationValues_Interpolate(from: RawServoAnimationValueBorrowed, diff --git a/components/style/gecko_bindings/structs_debug.rs b/components/style/gecko_bindings/structs_debug.rs index b7631880641..b61e83a8c6f 100644 --- a/components/style/gecko_bindings/structs_debug.rs +++ b/components/style/gecko_bindings/structs_debug.rs @@ -8214,9 +8214,6 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct ServoAnimationRule([u8; 0]); - #[repr(C)] - #[derive(Debug, Copy, Clone)] pub struct AnimationPerformanceWarning([u8; 0]); pub type CSSPseudoClassTypeBase = u8; #[repr(u8)] diff --git a/components/style/gecko_bindings/structs_release.rs b/components/style/gecko_bindings/structs_release.rs index afe41ab3238..c707ea195da 100644 --- a/components/style/gecko_bindings/structs_release.rs +++ b/components/style/gecko_bindings/structs_release.rs @@ -8026,9 +8026,6 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct ServoAnimationRule([u8; 0]); - #[repr(C)] - #[derive(Debug, Copy, Clone)] pub struct AnimationPerformanceWarning([u8; 0]); pub type CSSPseudoClassTypeBase = u8; #[repr(u8)] diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 07be5c8fce3..6d91e836199 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -45,6 +45,7 @@ use style::gecko_bindings::bindings::Gecko_AnimationAppendKeyframe; use style::gecko_bindings::bindings::RawGeckoComputedKeyframeValuesListBorrowedMut; use style::gecko_bindings::bindings::RawGeckoElementBorrowed; use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed; +use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowed; use style::gecko_bindings::bindings::RawServoAnimationValueStrong; use style::gecko_bindings::bindings::RawServoImportRuleBorrowed; use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull; @@ -247,6 +248,18 @@ pub extern "C" fn Servo_AnimationValues_Interpolate(from: RawServoAnimationValue } } +#[no_mangle] +pub extern "C" fn Servo_AnimationValueMap_Push(value_map: RawServoAnimationValueMapBorrowed, + property: nsCSSPropertyID, + value: RawServoAnimationValueBorrowed) +{ + use style::properties::animated_properties::AnimationValueMap; + + let value_map = RwLock::::as_arc(&value_map); + let value = AnimationValue::as_arc(&value).as_ref(); + value_map.write().insert(property.into(), value.clone()); +} + #[no_mangle] pub extern "C" fn Servo_AnimationValues_Uncompute(value: RawServoAnimationValueBorrowedListBorrowed) -> RawServoDeclarationBlockStrong