diff options
-rw-r--r-- | components/style/animation.rs | 4 | ||||
-rw-r--r-- | components/style/matching.rs | 19 |
2 files changed, 18 insertions, 5 deletions
diff --git a/components/style/animation.rs b/components/style/animation.rs index eb9dc9fd32d..87184928eb8 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -83,6 +83,7 @@ impl<Impl: SelectorImplExt> KeyframesAnimationState<Impl> { /// Returns true if the animation should keep running. pub fn tick(&mut self) -> bool { debug!("KeyframesAnimationState::tick"); + debug_assert!(!self.expired); self.started_at += self.duration + self.delay; match self.running_state { @@ -495,9 +496,9 @@ pub fn update_style_for_animation<Damage, Impl>(context: &SharedStyleContext<Imp where Impl: SelectorImplExt, Damage: TRestyleDamage<ConcreteComputedValues = Impl::ComputedValues> { debug!("update_style_for_animation: entering"); + debug_assert!(!animation.is_expired()); match *animation { Animation::Transition(_, start_time, ref frame, expired) => { - debug_assert!(!expired); debug!("update_style_for_animation: transition found"); let now = time::precise_time_s(); let mut new_style = (*style).clone(); @@ -513,7 +514,6 @@ where Impl: SelectorImplExt, } } Animation::Keyframes(_, ref name, ref state) => { - debug_assert!(!state.expired); debug!("update_style_for_animation: animation found: \"{}\", {:?}", name, state); let duration = state.duration; let started_at = state.started_at; diff --git a/components/style/matching.rs b/components/style/matching.rs index 5e0009c379b..7f865cf9a72 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -498,9 +498,22 @@ trait PrivateMatchMethods: TNode if had_running_animations { let mut all_running_animations = context.running_animations.write().unwrap(); for mut running_animation in all_running_animations.get_mut(&this_opaque).unwrap() { - animation::update_style_for_animation::<Self::ConcreteRestyleDamage, - <Self::ConcreteElement as Element>::Impl>(context, running_animation, style, None); - running_animation.mark_as_expired(); + // This shouldn't happen frequently, but under some + // circumstances mainly huge load or debug builds, the + // constellation might be delayed in sending the + // `TickAllAnimations` message to layout. + // + // Thus, we can't assume all the animations have been already + // updated by layout, because other restyle due to script might + // be triggered by layout before the animation tick. + // + // See #12171 and the associated PR for an example where this + // happened while debugging other release panic. + if !running_animation.is_expired() { + animation::update_style_for_animation::<Self::ConcreteRestyleDamage, + <Self::ConcreteElement as Element>::Impl>(context, running_animation, style, None); + running_animation.mark_as_expired(); + } } } |