diff options
Diffstat (limited to 'components/layout_2020/animation.rs')
-rw-r--r-- | components/layout_2020/animation.rs | 211 |
1 files changed, 0 insertions, 211 deletions
diff --git a/components/layout_2020/animation.rs b/components/layout_2020/animation.rs deleted file mode 100644 index 96e4801fa4e..00000000000 --- a/components/layout_2020/animation.rs +++ /dev/null @@ -1,211 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -//! CSS transitions and animations. - -use crate::context::LayoutContext; -use crate::display_list::items::OpaqueNode; -use crate::flow::{Flow, GetBaseFlow}; -use crate::opaque_node::OpaqueNodeMethods; -use crossbeam_channel::Receiver; -use fxhash::{FxHashMap, FxHashSet}; -use ipc_channel::ipc::IpcSender; -use msg::constellation_msg::PipelineId; -use script_traits::UntrustedNodeAddress; -use script_traits::{AnimationState, ConstellationControlMsg, LayoutMsg as ConstellationMsg}; -use style::animation::{update_style_for_animation, Animation}; -use style::dom::TElement; -use style::font_metrics::ServoMetricsProvider; -use style::selector_parser::RestyleDamage; -use style::timer::Timer; - -/// Processes any new animations that were discovered after style recalculation. -/// Also expire any old animations that have completed, inserting them into -/// `expired_animations`. -pub fn update_animation_state<E>( - constellation_chan: &IpcSender<ConstellationMsg>, - script_chan: &IpcSender<ConstellationControlMsg>, - running_animations: &mut FxHashMap<OpaqueNode, Vec<Animation>>, - expired_animations: &mut FxHashMap<OpaqueNode, Vec<Animation>>, - mut keys_to_remove: FxHashSet<OpaqueNode>, - mut newly_transitioning_nodes: Option<&mut Vec<UntrustedNodeAddress>>, - new_animations_receiver: &Receiver<Animation>, - pipeline_id: PipelineId, - timer: &Timer, -) where - E: TElement, -{ - let mut new_running_animations = vec![]; - while let Ok(animation) = new_animations_receiver.try_recv() { - let mut should_push = true; - if let Animation::Keyframes(ref node, _, ref name, ref state) = animation { - // If the animation was already present in the list for the - // node, just update its state, else push the new animation to - // run. - if let Some(ref mut animations) = running_animations.get_mut(node) { - // TODO: This being linear is probably not optimal. - for anim in animations.iter_mut() { - if let Animation::Keyframes(_, _, ref anim_name, ref mut anim_state) = *anim { - if *name == *anim_name { - debug!("update_animation_state: Found other animation {}", name); - anim_state.update_from_other(&state, timer); - should_push = false; - break; - } - } - } - } - } - - if should_push { - new_running_animations.push(animation); - } - } - - if running_animations.is_empty() && new_running_animations.is_empty() { - // Nothing to do. Return early so we don't flood the compositor with - // `ChangeRunningAnimationsState` messages. - return; - } - - let now = timer.seconds(); - // Expire old running animations. - // - // TODO: Do not expunge Keyframes animations, since we need that state if - // the animation gets re-triggered. Probably worth splitting in two - // different maps, or at least using a linked list? - for (key, running_animations) in running_animations.iter_mut() { - let mut animations_still_running = vec![]; - for mut running_animation in running_animations.drain(..) { - let still_running = !running_animation.is_expired() && - match running_animation { - Animation::Transition(_, started_at, ref frame) => { - now < started_at + frame.duration - }, - Animation::Keyframes(_, _, _, ref mut state) => { - // This animation is still running, or we need to keep - // iterating. - now < state.started_at + state.duration || state.tick() - }, - }; - - debug!( - "update_animation_state({:?}): {:?}", - still_running, running_animation - ); - - if still_running { - animations_still_running.push(running_animation); - continue; - } - - if let Animation::Transition(node, _, ref frame) = running_animation { - script_chan - .send(ConstellationControlMsg::TransitionEnd( - node.to_untrusted_node_address(), - frame.property_animation.property_name().into(), - frame.duration, - )) - .unwrap(); - } - - expired_animations - .entry(*key) - .or_insert_with(Vec::new) - .push(running_animation); - } - - if animations_still_running.is_empty() { - keys_to_remove.insert(*key); - } else { - *running_animations = animations_still_running - } - } - - for key in keys_to_remove { - running_animations.remove(&key).unwrap(); - } - - // Add new running animations. - for new_running_animation in new_running_animations { - if new_running_animation.is_transition() { - match newly_transitioning_nodes { - Some(ref mut nodes) => { - nodes.push(new_running_animation.node().to_untrusted_node_address()); - }, - None => { - warn!("New transition encountered from compositor-initiated layout."); - }, - } - } - - running_animations - .entry(*new_running_animation.node()) - .or_insert_with(Vec::new) - .push(new_running_animation) - } - - let animation_state = if running_animations.is_empty() { - AnimationState::NoAnimationsPresent - } else { - AnimationState::AnimationsPresent - }; - - constellation_chan - .send(ConstellationMsg::ChangeRunningAnimationsState( - pipeline_id, - animation_state, - )) - .unwrap(); -} - -/// Recalculates style for a set of animations. This does *not* run with the DOM -/// lock held. Returns a set of nodes associated with animations that are no longer -/// valid. -pub fn recalc_style_for_animations<E>( - context: &LayoutContext, - flow: &mut dyn Flow, - animations: &FxHashMap<OpaqueNode, Vec<Animation>>, -) -> FxHashSet<OpaqueNode> -where - E: TElement, -{ - let mut invalid_nodes = animations.keys().cloned().collect(); - do_recalc_style_for_animations::<E>(context, flow, animations, &mut invalid_nodes); - invalid_nodes -} - -fn do_recalc_style_for_animations<E>( - context: &LayoutContext, - flow: &mut dyn Flow, - animations: &FxHashMap<OpaqueNode, Vec<Animation>>, - invalid_nodes: &mut FxHashSet<OpaqueNode>, -) where - E: TElement, -{ - let mut damage = RestyleDamage::empty(); - flow.mutate_fragments(&mut |fragment| { - if let Some(ref animations) = animations.get(&fragment.node) { - invalid_nodes.remove(&fragment.node); - for animation in animations.iter() { - let old_style = fragment.style.clone(); - update_style_for_animation::<E>( - &context.style_context, - animation, - &mut fragment.style, - &ServoMetricsProvider, - ); - let difference = - RestyleDamage::compute_style_difference(&old_style, &fragment.style); - damage |= difference.damage; - } - } - }); - - let base = flow.mut_base(); - base.restyle_damage.insert(damage); - for kid in base.children.iter_mut() { - do_recalc_style_for_animations::<E>(context, kid, animations, invalid_nodes) - } -} |