diff options
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/document.rs | 59 | ||||
-rw-r--r-- | components/script/dom/element.rs | 2 |
2 files changed, 39 insertions, 22 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index da3b5db052c..d603d898f5c 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1538,28 +1538,29 @@ impl Document { self.animation_frame_ident.set(ident); self.animation_frame_list.borrow_mut().push((ident, Some(callback))); - // No need to send a `ChangeRunningAnimationsState` if we're running animation callbacks: - // we're guaranteed to already be in the "animation callbacks present" state. - // - // This reduces CPU usage by avoiding needless thread wakeups in the common case of - // repeated rAF. - // // TODO: Should tick animation only when document is visible - if !self.running_animation_callbacks.get() { - if !self.is_faking_animation_frames() { - let global_scope = self.window.upcast::<GlobalScope>(); - let event = ConstellationMsg::ChangeRunningAnimationsState( - global_scope.pipeline_id(), - AnimationState::AnimationCallbacksPresent); - global_scope.constellation_chan().send(event).unwrap(); - } else { - let callback = FakeRequestAnimationFrameCallback { - document: Trusted::new(self), - }; - self.global() - .schedule_callback(OneshotTimerCallback::FakeRequestAnimationFrame(callback), - MsDuration::new(FAKE_REQUEST_ANIMATION_FRAME_DELAY)); - } + + // If we are running 'fake' animation frames, we unconditionally + // set up a one-shot timer for script to execute the rAF callbacks. + if self.is_faking_animation_frames() { + let callback = FakeRequestAnimationFrameCallback { + document: Trusted::new(self), + }; + self.global() + .schedule_callback(OneshotTimerCallback::FakeRequestAnimationFrame(callback), + MsDuration::new(FAKE_REQUEST_ANIMATION_FRAME_DELAY)); + } else if !self.running_animation_callbacks.get() { + // No need to send a `ChangeRunningAnimationsState` if we're running animation callbacks: + // we're guaranteed to already be in the "animation callbacks present" state. + // + // This reduces CPU usage by avoiding needless thread wakeups in the common case of + // repeated rAF. + + let global_scope = self.window.upcast::<GlobalScope>(); + let event = ConstellationMsg::ChangeRunningAnimationsState( + global_scope.pipeline_id(), + AnimationState::AnimationCallbacksPresent); + global_scope.constellation_chan().send(event).unwrap(); } ident @@ -1596,6 +1597,22 @@ impl Document { ReflowQueryType::NoQuery, ReflowReason::RequestAnimationFrame); + if spurious && !was_faking_animation_frames { + // If the rAF callbacks did not mutate the DOM, then the + // reflow call above means that layout will not be invoked, + // and therefore no new frame will be sent to the compositor. + // If this happens, the compositor will not tick the animation + // and the next rAF will never be called! When this happens + // for several frames, then the spurious rAF detection below + // will kick in and use a timer to tick the callbacks. However, + // for the interim frames where we are deciding whether this rAF + // is considered spurious, we need to ensure that the layout + // and compositor *do* tick the animation. + self.window.force_reflow(ReflowGoal::ForDisplay, + ReflowQueryType::NoQuery, + ReflowReason::RequestAnimationFrame); + } + // Only send the animation change state message after running any callbacks. // This means that if the animation callback adds a new callback for // the next frame (which is the common case), we won't send a NoAnimationCallbacksPresent diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index f279c2c279b..a431d0c9dbb 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -89,6 +89,7 @@ use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivit use selectors::matching::{ElementSelectorFlags, LocalMatchingContext, MatchingContext, MatchingMode}; use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS}; use selectors::matching::{RelevantLinkStatus, matches_selector_list}; +use selectors::sink::Push; use servo_atoms::Atom; use std::ascii::AsciiExt; use std::borrow::Cow; @@ -109,7 +110,6 @@ use style::rule_tree::CascadeLevel; use style::selector_parser::{NonTSPseudoClass, PseudoElement, RestyleDamage, SelectorImpl, SelectorParser}; use style::selector_parser::extended_filtering; use style::shared_lock::{SharedRwLock, Locked}; -use style::sink::Push; use style::stylearc::Arc; use style::thread_state; use style::values::{CSSFloat, Either}; |