diff options
Diffstat (limited to 'components/script/animations.rs')
-rw-r--r-- | components/script/animations.rs | 67 |
1 files changed, 41 insertions, 26 deletions
diff --git a/components/script/animations.rs b/components/script/animations.rs index d0bfcef6f79..0b35ba4ae1d 100644 --- a/components/script/animations.rs +++ b/components/script/animations.rs @@ -19,15 +19,14 @@ use crate::dom::event::Event; use crate::dom::node::{from_untrusted_node_address, window_from_node, Node, NodeDamage}; use crate::dom::transitionevent::TransitionEvent; use crate::dom::window::Window; -use fxhash::FxHashMap; +use fxhash::{FxHashMap, FxHashSet}; use libc::c_void; use msg::constellation_msg::PipelineId; -use parking_lot::RwLock; use script_traits::{AnimationState as AnimationsPresentState, ScriptMsg, UntrustedNodeAddress}; -use servo_arc::Arc; use std::cell::Cell; use style::animation::{ - Animation, AnimationState, ElementAnimationSet, KeyframesIterationState, Transition, + Animation, AnimationSetKey, AnimationState, DocumentAnimationSet, ElementAnimationSet, + KeyframesIterationState, Transition, }; use style::dom::OpaqueNode; @@ -36,8 +35,7 @@ use style::dom::OpaqueNode; #[unrooted_must_root_lint::must_root] pub(crate) struct Animations { /// The map of nodes to their animation states. - #[ignore_malloc_size_of = "Arc is hard"] - pub sets: Arc<RwLock<FxHashMap<OpaqueNode, ElementAnimationSet>>>, + pub sets: DocumentAnimationSet, /// Whether or not we have animations that are running. have_running_animations: Cell<bool>, @@ -60,30 +58,31 @@ impl Animations { } pub(crate) fn clear(&self) { - self.sets.write().clear(); + self.sets.sets.write().clear(); self.rooted_nodes.borrow_mut().clear(); self.pending_events.borrow_mut().clear(); } pub(crate) fn mark_animating_nodes_as_dirty(&self) { - let sets = self.sets.read(); + let sets = self.sets.sets.read(); let rooted_nodes = self.rooted_nodes.borrow(); - for node in sets.keys().filter_map(|node| rooted_nodes.get(&node)) { + for node in sets.keys().filter_map(|key| rooted_nodes.get(&key.0)) { node.dirty(NodeDamage::NodeStyleDamaged); } } pub(crate) fn update_for_new_timeline_value(&self, window: &Window, now: f64) { let pipeline_id = window.pipeline_id(); - let mut sets = self.sets.write(); + let mut sets = self.sets.sets.write(); - for set in sets.values_mut() { - self.start_pending_animations(set, now, pipeline_id); + for (key, set) in sets.iter_mut() { + self.start_pending_animations(key, set, now, pipeline_id); // When necessary, iterate our running animations to the next iteration. for animation in set.animations.iter_mut() { if animation.iterate_if_necessary(now) { self.add_animation_event( + key, animation, TransitionOrAnimationEventType::AnimationIteration, now, @@ -92,7 +91,7 @@ impl Animations { } } - self.finish_running_animations(set, now, pipeline_id); + self.finish_running_animations(key, set, now, pipeline_id); } self.unroot_unused_nodes(&sets); @@ -102,12 +101,12 @@ impl Animations { /// that trigger events for any animations that changed state. pub(crate) fn do_post_reflow_update(&self, window: &Window, now: f64) { let pipeline_id = window.pipeline_id(); - let mut sets = self.sets.write(); + let mut sets = self.sets.sets.write(); self.root_newly_animating_dom_nodes(&sets, window); - for set in sets.values_mut() { - self.handle_canceled_animations(set, now, pipeline_id); - self.handle_new_animations(set, now, pipeline_id); + for (key, set) in sets.iter_mut() { + self.handle_canceled_animations(key, set, now, pipeline_id); + self.handle_new_animations(key, set, now, pipeline_id); } // Remove empty states from our collection of states in order to free @@ -136,6 +135,7 @@ impl Animations { pub(crate) fn running_animation_count(&self) -> usize { self.sets + .sets .read() .values() .map(|state| state.running_animation_and_transition_count()) @@ -146,6 +146,7 @@ impl Animations { /// have left the delay phase. fn start_pending_animations( &self, + key: &AnimationSetKey, set: &mut ElementAnimationSet, now: f64, pipeline_id: PipelineId, @@ -154,6 +155,7 @@ impl Animations { if animation.state == AnimationState::Pending && animation.started_at <= now { animation.state = AnimationState::Running; self.add_animation_event( + key, animation, TransitionOrAnimationEventType::AnimationStart, now, @@ -166,6 +168,7 @@ impl Animations { if transition.state == AnimationState::Pending && transition.start_time <= now { transition.state = AnimationState::Running; self.add_transition_event( + key, transition, TransitionOrAnimationEventType::TransitionStart, now, @@ -179,6 +182,7 @@ impl Animations { /// have ended. fn finish_running_animations( &self, + key: &AnimationSetKey, set: &mut ElementAnimationSet, now: f64, pipeline_id: PipelineId, @@ -187,6 +191,7 @@ impl Animations { if animation.state == AnimationState::Running && animation.has_ended(now) { animation.state = AnimationState::Finished; self.add_animation_event( + key, animation, TransitionOrAnimationEventType::AnimationEnd, now, @@ -199,6 +204,7 @@ impl Animations { if transition.state == AnimationState::Running && transition.has_ended(now) { transition.state = AnimationState::Finished; self.add_transition_event( + key, transition, TransitionOrAnimationEventType::TransitionEnd, now, @@ -213,6 +219,7 @@ impl Animations { /// well. fn handle_canceled_animations( &self, + key: &AnimationSetKey, set: &mut ElementAnimationSet, now: f64, pipeline_id: PipelineId, @@ -220,6 +227,7 @@ impl Animations { for transition in &set.transitions { if transition.state == AnimationState::Canceled { self.add_transition_event( + key, transition, TransitionOrAnimationEventType::TransitionCancel, now, @@ -231,6 +239,7 @@ impl Animations { for animation in &set.animations { if animation.state == AnimationState::Canceled { self.add_animation_event( + key, animation, TransitionOrAnimationEventType::AnimationCancel, now, @@ -244,6 +253,7 @@ impl Animations { fn handle_new_animations( &self, + key: &AnimationSetKey, set: &mut ElementAnimationSet, now: f64, pipeline_id: PipelineId, @@ -255,6 +265,7 @@ impl Animations { for transition in set.transitions.iter_mut() { if transition.is_new { self.add_transition_event( + key, transition, TransitionOrAnimationEventType::TransitionRun, now, @@ -270,13 +281,14 @@ impl Animations { #[allow(unsafe_code)] fn root_newly_animating_dom_nodes( &self, - sets: &FxHashMap<OpaqueNode, ElementAnimationSet>, + sets: &FxHashMap<AnimationSetKey, ElementAnimationSet>, window: &Window, ) { let js_runtime = window.get_js_runtime().as_ref().unwrap().rt(); let mut rooted_nodes = self.rooted_nodes.borrow_mut(); - for (opaque_node, set) in sets.iter() { - if rooted_nodes.contains_key(opaque_node) { + for (key, set) in sets.iter() { + let opaque_node = key.0; + if rooted_nodes.contains_key(&opaque_node) { continue; } @@ -286,7 +298,7 @@ impl Animations { let address = UntrustedNodeAddress(opaque_node.0 as *const c_void); unsafe { rooted_nodes.insert( - opaque_node.clone(), + opaque_node, Dom::from_ref(&*from_untrusted_node_address(js_runtime, address)), ) }; @@ -295,15 +307,17 @@ impl Animations { } // Unroot any nodes that we have rooted but are no longer tracking animations for. - fn unroot_unused_nodes(&self, sets: &FxHashMap<OpaqueNode, ElementAnimationSet>) { + fn unroot_unused_nodes(&self, sets: &FxHashMap<AnimationSetKey, ElementAnimationSet>) { let pending_events = self.pending_events.borrow(); - self.rooted_nodes.borrow_mut().retain(|key, _| { - sets.contains_key(key) || pending_events.iter().any(|event| event.node == *key) + let nodes: FxHashSet<OpaqueNode> = sets.keys().map(|key| key.0).collect(); + self.rooted_nodes.borrow_mut().retain(|node, _| { + nodes.contains(&node) || pending_events.iter().any(|event| event.node == *node) }); } fn add_transition_event( &self, + key: &AnimationSetKey, transition: &Transition, event_type: TransitionOrAnimationEventType, now: f64, @@ -330,7 +344,7 @@ impl Animations { .push(TransitionOrAnimationEvent { pipeline_id, event_type, - node: transition.node.clone(), + node: key.0, property_or_animation_name: transition .property_animation .property_id() @@ -342,6 +356,7 @@ impl Animations { fn add_animation_event( &self, + key: &AnimationSetKey, animation: &Animation, event_type: TransitionOrAnimationEventType, now: f64, @@ -377,7 +392,7 @@ impl Animations { .push(TransitionOrAnimationEvent { pipeline_id, event_type, - node: animation.node.clone(), + node: key.0, property_or_animation_name: animation.name.to_string(), elapsed_time, }); |