Bug 1459436: Fix servo build. r=emilio
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sat, 05 May 2018 17:19:06 +0200
changeset 473167 22420d6434d4ad2049edb8c2030add30d32a7f61
parent 473166 84ac9609a9bc1ebbcf30033a283ae0a2d97d763d
child 473168 6403b7b81a8cd6675327fabce4c35a995f52faa8
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1459436
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1459436: Fix servo build. r=emilio MozReview-Commit-ID: Ex5RKgPgd8x
servo/components/layout/animation.rs
servo/components/layout/generated_content.rs
servo/components/style/animation.rs
servo/components/style/matching.rs
servo/components/style/stylesheets/keyframes_rule.rs
--- a/servo/components/layout/animation.rs
+++ b/servo/components/layout/animation.rs
@@ -34,24 +34,24 @@ pub fn update_animation_state<E>(
     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 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 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;
                         }
                     }
                 }
@@ -78,17 +78,17 @@ where
     let mut keys_to_remove = vec![];
     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, _expired) => {
                     now < started_at + frame.duration
                 }
-                Animation::Keyframes(_, _, ref mut state) => {
+                Animation::Keyframes(_, _, _, ref mut state) => {
                     // This animation is still running, or we need to keep
                     // iterating.
                     now < state.started_at + state.duration || state.tick()
                 }
             };
 
             if still_running {
                 animations_still_running.push(running_animation);
--- a/servo/components/layout/generated_content.rs
+++ b/servo/components/layout/generated_content.rs
@@ -267,37 +267,37 @@ impl<'a, 'b> ResolveGeneratedContentFrag
         }
 
         // Truncate down counters.
         for (_, counter) in &mut self.traversal.counters {
             counter.truncate_to_level(self.level);
         }
         self.traversal.list_item.truncate_to_level(self.level);
 
-        for &(ref counter_name, value) in &*fragment.style().get_counters().counter_reset {
-            let counter_name = &*counter_name.0;
+        for pair in &*fragment.style().get_counters().counter_reset {
+            let counter_name = &*pair.name.0;
             if let Some(ref mut counter) = self.traversal.counters.get_mut(counter_name) {
-                 counter.reset(self.level, value);
+                 counter.reset(self.level, pair.value);
                  continue
             }
 
             let mut counter = Counter::new();
-            counter.reset(self.level, value);
+            counter.reset(self.level, pair.value);
             self.traversal.counters.insert(counter_name.to_owned(), counter);
         }
 
-        for &(ref counter_name, value) in &*fragment.style().get_counters().counter_increment {
-            let counter_name = &*counter_name.0;
+        for pair in &*fragment.style().get_counters().counter_increment {
+            let counter_name = &*pair.name.0;
             if let Some(ref mut counter) = self.traversal.counters.get_mut(counter_name) {
-                counter.increment(self.level, value);
+                counter.increment(self.level, pair.value);
                 continue
             }
 
             let mut counter = Counter::new();
-            counter.increment(self.level, value);
+            counter.increment(self.level, pair.value);
             self.traversal.counters.insert(counter_name.to_owned(), counter);
         }
 
         self.incremented = true
     }
 
     fn quote(&self, style: &ComputedValues, close: bool) -> String {
         let quotes = &style.get_list().quotes;
--- a/servo/components/style/animation.rs
+++ b/servo/components/style/animation.rs
@@ -12,17 +12,17 @@ use dom::{OpaqueNode, TElement};
 use font_metrics::FontMetricsProvider;
 use properties::{self, CascadeFlags, ComputedValues, LonghandId};
 use properties::animated_properties::{AnimatedProperty, TransitionProperty};
 use properties::longhands::animation_direction::computed_value::single_value::T as AnimationDirection;
 use properties::longhands::animation_play_state::computed_value::single_value::T as AnimationPlayState;
 use rule_tree::CascadeLevel;
 use servo_arc::Arc;
 use std::sync::mpsc::Sender;
-use stylesheets::keyframes_rule::{KeyframesStep, KeyframesStepValue};
+use stylesheets::keyframes_rule::{KeyframesAnimation, KeyframesStep, KeyframesStepValue};
 use timer::Timer;
 use values::computed::Time;
 use values::computed::transform::TimingFunction;
 use values::generics::box_::AnimationIterationCount;
 use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction};
 
 /// This structure represents a keyframes animation current iteration state.
 ///
@@ -189,54 +189,56 @@ pub enum Animation {
     /// A transition is just a single frame triggered at a time, with a reflow.
     ///
     /// the f64 field is the start time as returned by `time::precise_time_s()`.
     ///
     /// The `bool` field is werther this animation should no longer run.
     Transition(OpaqueNode, f64, AnimationFrame, bool),
     /// A keyframes animation is identified by a name, and can have a
     /// node-dependent state (i.e. iteration count, etc.).
-    Keyframes(OpaqueNode, Atom, KeyframesAnimationState),
+    ///
+    /// TODO(emilio): The animation object could be refcounted.
+    Keyframes(OpaqueNode, KeyframesAnimation, Atom, KeyframesAnimationState),
 }
 
 impl Animation {
     /// Mark this animation as expired.
     #[inline]
     pub fn mark_as_expired(&mut self) {
         debug_assert!(!self.is_expired());
         match *self {
             Animation::Transition(_, _, _, ref mut expired) => *expired = true,
-            Animation::Keyframes(_, _, ref mut state) => state.expired = true,
+            Animation::Keyframes(_, _, _, ref mut state) => state.expired = true,
         }
     }
 
     /// Whether this animation is expired.
     #[inline]
     pub fn is_expired(&self) -> bool {
         match *self {
             Animation::Transition(_, _, _, expired) => expired,
-            Animation::Keyframes(_, _, ref state) => state.expired,
+            Animation::Keyframes(_, _, _, ref state) => state.expired,
         }
     }
 
     /// The opaque node that owns the animation.
     #[inline]
     pub fn node(&self) -> &OpaqueNode {
         match *self {
             Animation::Transition(ref node, _, _, _) => node,
-            Animation::Keyframes(ref node, _, _) => node,
+            Animation::Keyframes(ref node, _, _, _) => node,
         }
     }
 
     /// Whether this animation is paused. A transition can never be paused.
     #[inline]
     pub fn is_paused(&self) -> bool {
         match *self {
             Animation::Transition(..) => false,
-            Animation::Keyframes(_, _, ref state) => state.is_paused(),
+            Animation::Keyframes(_, _, _, ref state) => state.is_paused(),
         }
     }
 
     /// Whether this animation is a transition.
     #[inline]
     pub fn is_transition(&self) -> bool {
         match *self {
             Animation::Transition(..) => true,
@@ -495,39 +497,43 @@ where
             );
             computed
         },
     }
 }
 
 /// Triggers animations for a given node looking at the animation property
 /// values.
-pub fn maybe_start_animations(
+pub fn maybe_start_animations<E>(
+    element: E,
     context: &SharedStyleContext,
     new_animations_sender: &Sender<Animation>,
     node: OpaqueNode,
     new_style: &Arc<ComputedValues>,
-) -> bool {
+) -> bool
+where
+    E: TElement,
+{
     let mut had_animations = false;
 
     let box_style = new_style.get_box();
     for (i, name) in box_style.animation_name_iter().enumerate() {
         let name = if let Some(atom) = name.as_atom() {
             atom
         } else {
             continue;
         };
 
         debug!("maybe_start_animations: name={}", name);
         let total_duration = box_style.animation_duration_mod(i).seconds();
         if total_duration == 0. {
             continue;
         }
 
-        if let Some(ref anim) = context.stylist.get_animation(name) {
+        if let Some(anim) = context.stylist.get_animation(name, element) {
             debug!("maybe_start_animations: animation {} found", name);
 
             // If this animation doesn't have any keyframe, we can just continue
             // without submitting it to the compositor, since both the first and
             // the second keyframes would be synthetised from the computed
             // values.
             if anim.steps.is_empty() {
                 continue;
@@ -556,16 +562,17 @@ pub fn maybe_start_animations(
             let running_state = match box_style.animation_play_state_mod(i) {
                 AnimationPlayState::Paused => KeyframesRunningState::Paused(0.),
                 AnimationPlayState::Running => KeyframesRunningState::Running,
             };
 
             new_animations_sender
                 .send(Animation::Keyframes(
                     node,
+                    anim.clone(),
                     name.clone(),
                     KeyframesAnimationState {
                         started_at: animation_start,
                         duration: duration as f64,
                         delay: delay as f64,
                         iteration_state: iteration_state,
                         running_state: running_state,
                         direction: animation_direction,
@@ -623,37 +630,29 @@ pub fn update_style_for_animation<E>(
             let now = context.timer.seconds();
             let mut new_style = (*style).clone();
             let updated_style =
                 update_style_for_animation_frame(&mut new_style, now, start_time, frame);
             if updated_style {
                 *style = new_style
             }
         },
-        Animation::Keyframes(_, ref name, ref state) => {
+        Animation::Keyframes(_, ref animation, ref name, ref state) => {
             debug!(
                 "update_style_for_animation: animation found: \"{}\", {:?}",
                 name, state
             );
             let duration = state.duration;
             let started_at = state.started_at;
 
             let now = match state.running_state {
                 KeyframesRunningState::Running => context.timer.seconds(),
                 KeyframesRunningState::Paused(progress) => started_at + duration * progress,
             };
 
-            let animation = match context.stylist.get_animation(name) {
-                None => {
-                    warn!("update_style_for_animation: Animation {:?} not found", name);
-                    return;
-                },
-                Some(animation) => animation,
-            };
-
             debug_assert!(!animation.steps.is_empty());
 
             let maybe_index = style
                 .get_box()
                 .animation_name_iter()
                 .position(|animation_name| Some(name) == animation_name.as_atom());
 
             let index = match maybe_index {
--- a/servo/components/style/matching.rs
+++ b/servo/components/style/matching.rs
@@ -420,16 +420,17 @@ trait PrivateMatchMethods: TElement {
                 &context.thread_local.font_metrics_provider,
             );
         }
 
         let new_animations_sender = &context.thread_local.new_animations_sender;
         let this_opaque = self.as_node().opaque();
         // Trigger any present animations if necessary.
         animation::maybe_start_animations(
+            *self,
             &shared_context,
             new_animations_sender,
             this_opaque,
             &new_values,
         );
 
         // Trigger transitions if necessary. This will reset `new_values` back
         // to its old value if it did trigger a transition.
--- a/servo/components/style/stylesheets/keyframes_rule.rs
+++ b/servo/components/style/stylesheets/keyframes_rule.rs
@@ -254,33 +254,33 @@ impl DeepCloneWithLock for Keyframe {
     }
 }
 
 /// A keyframes step value. This can be a synthetised keyframes animation, that
 /// is, one autogenerated from the current computed values, or a list of
 /// declarations to apply.
 ///
 /// TODO: Find a better name for this?
-#[derive(Debug, MallocSizeOf)]
+#[derive(Clone, Debug, MallocSizeOf)]
 pub enum KeyframesStepValue {
     /// A step formed by a declaration block specified by the CSS.
     Declarations {
         /// The declaration block per se.
         #[cfg_attr(feature = "gecko",
                    ignore_malloc_size_of = "XXX: Primary ref, measure if DMD says it's worthwhile")]
         #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")]
         block: Arc<Locked<PropertyDeclarationBlock>>,
     },
     /// A synthetic step computed from the current computed values at the time
     /// of the animation.
     ComputedValues,
 }
 
 /// A single step from a keyframe animation.
-#[derive(Debug, MallocSizeOf)]
+#[derive(Clone, Debug, MallocSizeOf)]
 pub struct KeyframesStep {
     /// The percentage of the animation duration when this step starts.
     pub start_percentage: KeyframePercentage,
     /// Declarations that will determine the final style during the step, or
     /// `ComputedValues` if this is an autogenerated step.
     pub value: KeyframesStepValue,
     /// Wether a animation-timing-function declaration exists in the list of
     /// declarations.
@@ -347,17 +347,17 @@ impl KeyframesStep {
         }
     }
 }
 
 /// This structure represents a list of animation steps computed from the list
 /// of keyframes, in order.
 ///
 /// It only takes into account animable properties.
-#[derive(Debug, MallocSizeOf)]
+#[derive(Clone, Debug, MallocSizeOf)]
 pub struct KeyframesAnimation {
     /// The difference steps of the animation.
     pub steps: Vec<KeyframesStep>,
     /// The properties that change in this animation.
     pub properties_changed: LonghandIdSet,
     /// Vendor prefix type the @keyframes has.
     pub vendor_prefix: Option<VendorPrefix>,
 }