mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 00:05:36 +00:00
Bug 1646811 - servo: Add DocumentAnimationSet and AnimationSetKey.
This will be used in order to hold animations for pseudo elements in the DocumentAnimationSet. Also no longer store the OpaqueNode in the animation and transition data structures. This is already part of the DocumentAnimationSet key. Depends on D80241 Differential Revision: https://phabricator.services.mozilla.com/D80242
This commit is contained in:
parent
1a949f1378
commit
d406afe4e6
@ -19,6 +19,7 @@ use crate::properties::{
|
||||
PropertyDeclarationId,
|
||||
};
|
||||
use crate::rule_tree::CascadeLevel;
|
||||
use crate::shared_lock::{Locked, SharedRwLock};
|
||||
use crate::style_resolver::StyleResolverForElement;
|
||||
use crate::stylesheets::keyframes_rule::{KeyframesAnimation, KeyframesStep, KeyframesStepValue};
|
||||
use crate::values::animated::{Animate, Procedure};
|
||||
@ -26,6 +27,8 @@ use crate::values::computed::{Time, TimingFunction};
|
||||
use crate::values::generics::box_::AnimationIterationCount;
|
||||
use crate::values::generics::easing::{StepPosition, TimingFunction as GenericTimingFunction};
|
||||
use crate::Atom;
|
||||
use fxhash::FxHashMap;
|
||||
use parking_lot::RwLock;
|
||||
use servo_arc::Arc;
|
||||
use std::fmt;
|
||||
|
||||
@ -393,9 +396,6 @@ impl ComputedKeyframe {
|
||||
/// A CSS Animation
|
||||
#[derive(Clone, MallocSizeOf)]
|
||||
pub struct Animation {
|
||||
/// The node associated with this animation.
|
||||
pub node: OpaqueNode,
|
||||
|
||||
/// The name of this animation as defined by the style.
|
||||
pub name: Atom,
|
||||
|
||||
@ -736,9 +736,6 @@ impl fmt::Debug for Animation {
|
||||
/// A CSS Transition
|
||||
#[derive(Clone, Debug, MallocSizeOf)]
|
||||
pub struct Transition {
|
||||
/// The node associated with this animation.
|
||||
pub node: OpaqueNode,
|
||||
|
||||
/// The start time of this transition, which is the current value of the animation
|
||||
/// timeline when this transition was created plus any animation delay.
|
||||
pub start_time: f64,
|
||||
@ -891,7 +888,7 @@ impl ElementAnimationSet {
|
||||
}
|
||||
|
||||
pub(crate) fn apply_active_animations(
|
||||
&mut self,
|
||||
&self,
|
||||
context: &SharedStyleContext,
|
||||
style: &mut Arc<ComputedValues>,
|
||||
) {
|
||||
@ -987,7 +984,6 @@ impl ElementAnimationSet {
|
||||
&mut self,
|
||||
might_need_transitions_update: bool,
|
||||
context: &SharedStyleContext,
|
||||
opaque_node: OpaqueNode,
|
||||
old_style: Option<&Arc<ComputedValues>>,
|
||||
after_change_style: &Arc<ComputedValues>,
|
||||
) {
|
||||
@ -1015,7 +1011,6 @@ impl ElementAnimationSet {
|
||||
|
||||
let transitioning_properties = start_transitions_if_applicable(
|
||||
context,
|
||||
opaque_node,
|
||||
&before_change_style,
|
||||
after_change_style,
|
||||
self,
|
||||
@ -1037,7 +1032,6 @@ impl ElementAnimationSet {
|
||||
fn start_transition_if_applicable(
|
||||
&mut self,
|
||||
context: &SharedStyleContext,
|
||||
opaque_node: OpaqueNode,
|
||||
longhand_id: LonghandId,
|
||||
index: usize,
|
||||
old_style: &ComputedValues,
|
||||
@ -1079,7 +1073,6 @@ impl ElementAnimationSet {
|
||||
// it if we are replacing a reversed transition.
|
||||
let reversing_adjusted_start_value = property_animation.from.clone();
|
||||
let mut new_transition = Transition {
|
||||
node: opaque_node,
|
||||
start_time: now + delay,
|
||||
delay,
|
||||
property_animation,
|
||||
@ -1143,11 +1136,78 @@ impl ElementAnimationSet {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
|
||||
/// A key that is used to identify nodes in the `DocumentAnimationSet`.
|
||||
pub struct AnimationSetKey(pub OpaqueNode);
|
||||
|
||||
#[derive(Clone, Debug, Default, MallocSizeOf)]
|
||||
/// A set of animations for a document.
|
||||
pub struct DocumentAnimationSet {
|
||||
/// The `ElementAnimationSet`s that this set contains.
|
||||
#[ignore_malloc_size_of = "Arc is hard"]
|
||||
pub sets: Arc<RwLock<FxHashMap<AnimationSetKey, ElementAnimationSet>>>,
|
||||
}
|
||||
|
||||
impl DocumentAnimationSet {
|
||||
/// Return whether or not the provided node has active CSS animations.
|
||||
pub fn has_active_animations(&self, key: &AnimationSetKey) -> bool {
|
||||
self.sets
|
||||
.read()
|
||||
.get(key)
|
||||
.map(|set| set.has_active_animation())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Return whether or not the provided node has active CSS transitions.
|
||||
pub fn has_active_transitions(&self, key: &AnimationSetKey) -> bool {
|
||||
self.sets
|
||||
.read()
|
||||
.get(key)
|
||||
.map(|set| set.has_active_transition())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Return a locked PropertyDeclarationBlock with animation values for the given
|
||||
/// key and time.
|
||||
pub fn get_animation_declarations(
|
||||
&self,
|
||||
key: &AnimationSetKey,
|
||||
time: f64,
|
||||
shared_lock: &SharedRwLock,
|
||||
) -> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||
self.sets
|
||||
.read()
|
||||
.get(key)
|
||||
.and_then(|set| set.get_value_map_for_active_animations(time))
|
||||
.map(|map| {
|
||||
let block = PropertyDeclarationBlock::from_animation_value_map(&map);
|
||||
Arc::new(shared_lock.wrap(block))
|
||||
})
|
||||
}
|
||||
|
||||
/// Return a locked PropertyDeclarationBlock with transition values for the given
|
||||
/// key and time.
|
||||
pub fn get_transition_declarations(
|
||||
&self,
|
||||
key: &AnimationSetKey,
|
||||
time: f64,
|
||||
shared_lock: &SharedRwLock,
|
||||
) -> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||
self.sets
|
||||
.read()
|
||||
.get(key)
|
||||
.and_then(|set| set.get_value_map_for_active_transitions(time))
|
||||
.map(|map| {
|
||||
let block = PropertyDeclarationBlock::from_animation_value_map(&map);
|
||||
Arc::new(shared_lock.wrap(block))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Kick off any new transitions for this node and return all of the properties that are
|
||||
/// transitioning. This is at the end of calculating style for a single node.
|
||||
pub fn start_transitions_if_applicable(
|
||||
context: &SharedStyleContext,
|
||||
opaque_node: OpaqueNode,
|
||||
old_style: &ComputedValues,
|
||||
new_style: &Arc<ComputedValues>,
|
||||
animation_state: &mut ElementAnimationSet,
|
||||
@ -1162,7 +1222,6 @@ pub fn start_transitions_if_applicable(
|
||||
properties_that_transition.insert(physical_property);
|
||||
animation_state.start_transition_if_applicable(
|
||||
context,
|
||||
opaque_node,
|
||||
physical_property,
|
||||
transition.index,
|
||||
old_style,
|
||||
@ -1245,7 +1304,6 @@ pub fn maybe_start_animations<E>(
|
||||
);
|
||||
|
||||
let new_animation = Animation {
|
||||
node: element.as_node().opaque(),
|
||||
name: name.clone(),
|
||||
properties_changed: keyframe_animation.properties_changed,
|
||||
computed_steps,
|
||||
|
@ -5,11 +5,9 @@
|
||||
//! The context within which style is calculated.
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
use crate::animation::ElementAnimationSet;
|
||||
use crate::animation::DocumentAnimationSet;
|
||||
use crate::bloom::StyleBloom;
|
||||
use crate::data::{EagerPseudoStyles, ElementData};
|
||||
#[cfg(feature = "servo")]
|
||||
use crate::dom::OpaqueNode;
|
||||
use crate::dom::{SendElement, TElement};
|
||||
use crate::font_metrics::FontMetricsProvider;
|
||||
#[cfg(feature = "gecko")]
|
||||
@ -31,10 +29,9 @@ use app_units::Au;
|
||||
use euclid::default::Size2D;
|
||||
use euclid::Scale;
|
||||
use fxhash::FxHashMap;
|
||||
#[cfg(feature = "servo")]
|
||||
use parking_lot::RwLock;
|
||||
use selectors::matching::ElementSelectorFlags;
|
||||
use selectors::NthIndexCache;
|
||||
#[cfg(feature = "gecko")]
|
||||
use servo_arc::Arc;
|
||||
#[cfg(feature = "servo")]
|
||||
use servo_atoms::Atom;
|
||||
@ -167,7 +164,7 @@ pub struct SharedStyleContext<'a> {
|
||||
|
||||
/// The state of all animations for our styled elements.
|
||||
#[cfg(feature = "servo")]
|
||||
pub animation_states: Arc<RwLock<FxHashMap<OpaqueNode, ElementAnimationSet>>>,
|
||||
pub animations: DocumentAnimationSet,
|
||||
|
||||
/// Paint worklets
|
||||
#[cfg(feature = "servo")]
|
||||
|
@ -527,7 +527,7 @@ trait PrivateMatchMethods: TElement {
|
||||
old_values: &mut Option<Arc<ComputedValues>>,
|
||||
new_values: &mut Arc<ComputedValues>,
|
||||
) -> bool {
|
||||
use crate::animation::AnimationState;
|
||||
use crate::animation::{AnimationSetKey, AnimationState};
|
||||
|
||||
// We need to call this before accessing the `ElementAnimationSet` from the
|
||||
// map because this call will do a RwLock::read().
|
||||
@ -544,12 +544,13 @@ trait PrivateMatchMethods: TElement {
|
||||
after_change_style = self.after_change_style(context, new_values);
|
||||
}
|
||||
|
||||
let this_opaque = self.as_node().opaque();
|
||||
let key = AnimationSetKey(self.as_node().opaque());
|
||||
let shared_context = context.shared;
|
||||
let mut animation_set = shared_context
|
||||
.animation_states
|
||||
.animations
|
||||
.sets
|
||||
.write()
|
||||
.remove(&this_opaque)
|
||||
.remove(&key)
|
||||
.unwrap_or_default();
|
||||
|
||||
// Starting animations is expensive, because we have to recalculate the style
|
||||
@ -574,7 +575,6 @@ trait PrivateMatchMethods: TElement {
|
||||
animation_set.update_transitions_for_new_style(
|
||||
might_need_transitions_update,
|
||||
&shared_context,
|
||||
this_opaque,
|
||||
old_values.as_ref(),
|
||||
after_change_style.as_ref().unwrap_or(new_values),
|
||||
);
|
||||
@ -593,9 +593,10 @@ trait PrivateMatchMethods: TElement {
|
||||
if !animation_set.is_empty() {
|
||||
animation_set.dirty = false;
|
||||
shared_context
|
||||
.animation_states
|
||||
.animations
|
||||
.sets
|
||||
.write()
|
||||
.insert(this_opaque, animation_set);
|
||||
.insert(key, animation_set);
|
||||
}
|
||||
|
||||
changed_animations
|
||||
|
Loading…
Reference in New Issue
Block a user