diff --git a/components/layout/animation.rs b/components/layout/animation.rs index dcb860308ef..863b1eb325a 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -49,32 +49,41 @@ pub fn start_transitions_if_applicable(new_animations_sender: &Sender } /// Processes any new animations that were discovered after style recalculation. -pub fn process_new_animations(rw_data: &mut LayoutTaskData, pipeline_id: PipelineId) { +/// Also expire any old animations that have completed. +pub fn update_animation_state(rw_data: &mut LayoutTaskData, pipeline_id: PipelineId) { let mut new_running_animations = Vec::new(); while let Ok(animation) = rw_data.new_animations_receiver.try_recv() { new_running_animations.push(animation) } - if !new_running_animations.is_empty() { - let mut running_animations = (*rw_data.running_animations).clone(); - // Expire old running animations. - let now = clock_ticks::precise_time_s(); - for (_, running_animations) in &mut running_animations { - running_animations.retain(|running_animation| now < running_animation.end_time); + let mut running_animations_hash = (*rw_data.running_animations).clone(); + + // Expire old running animations. + let now = clock_ticks::precise_time_s(); + let mut keys_to_remove = Vec::new(); + for (key, running_animations) in &mut running_animations_hash { + running_animations.retain(|running_animation| { + now < running_animation.end_time + }); + if running_animations.len() == 0 { + keys_to_remove.push(*key); } - - // Add new running animations. - for new_running_animation in new_running_animations { - match running_animations.entry(OpaqueNode(new_running_animation.node)) { - Entry::Vacant(entry) => { - entry.insert(vec![new_running_animation]); - } - Entry::Occupied(mut entry) => entry.get_mut().push(new_running_animation), - } - } - - rw_data.running_animations = Arc::new(running_animations); } + for key in keys_to_remove { + running_animations_hash.remove(&key).unwrap(); + } + + // Add new running animations. + for new_running_animation in new_running_animations { + match running_animations_hash.entry(OpaqueNode(new_running_animation.node)) { + Entry::Vacant(entry) => { + entry.insert(vec![new_running_animation]); + } + Entry::Occupied(mut entry) => entry.get_mut().push(new_running_animation), + } + } + + rw_data.running_animations = Arc::new(running_animations_hash); let animation_state; if rw_data.running_animations.is_empty() { diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 17bd99b0749..28eacfd1763 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -1183,9 +1183,6 @@ impl LayoutTask { // Retrieve the (possibly rebuilt) root flow. rw_data.root_flow = self.try_get_layout_root((*node).clone()); - - // Kick off animations if any were triggered. - animation::process_new_animations(&mut *rw_data, self.id); } // Send new canvas renderers to the paint task @@ -1327,6 +1324,9 @@ impl LayoutTask { rw_data: &mut LayoutTaskData, layout_context: &mut SharedLayoutContext) { if let Some(mut root_flow) = rw_data.layout_root() { + // Kick off animations if any were triggered, expire completed ones. + animation::update_animation_state(&mut *rw_data, self.id); + profile(time::ProfilerCategory::LayoutRestyleDamagePropagation, self.profiler_metadata(), self.time_profiler_chan.clone(), diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs index c43a5566a1c..ab244707c28 100644 --- a/components/msg/constellation_msg.rs +++ b/components/msg/constellation_msg.rs @@ -275,7 +275,7 @@ pub enum Msg { NodeStatus(Option), } -#[derive(Clone, Eq, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Eq, PartialEq, Deserialize, Serialize, Debug)] pub enum AnimationState { AnimationsPresent, AnimationCallbacksPresent,