mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #11205 - pcwalton:avoid-needless-animation-state-changes, r=jdm
script: Avoid needless `ChangeRunningAnimationsState` messages during typical `requestAnimationFrame()` animations. This skips useless message traffic when `requestAnimationFrame()` is called during an animation frame callback. It reduces CPU usage of the following snippet by 49%: <script> function foo() { requestAnimationFrame(foo); } </script> <button onclick="foo()">Start rAF</button> Partially addresses #9844. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11205) <!-- Reviewable:end -->
This commit is contained in:
commit
e5c3bb8977
1 changed files with 22 additions and 4 deletions
|
@ -201,6 +201,11 @@ pub struct Document {
|
|||
/// List of animation frame callbacks
|
||||
#[ignore_heap_size_of = "closures are hard"]
|
||||
animation_frame_list: DOMRefCell<BTreeMap<u32, Box<FnBox(f64)>>>,
|
||||
/// Whether we're in the process of running animation callbacks.
|
||||
///
|
||||
/// Tracking this is not necessary for correctness. Instead, it is an optimization to avoid
|
||||
/// sending needless `ChangeRunningAnimationsState` messages to the compositor.
|
||||
running_animation_callbacks: Cell<bool>,
|
||||
/// Tracks all outstanding loads related to this document.
|
||||
loader: DOMRefCell<DocumentLoader>,
|
||||
/// The current active HTML parser, to allow resuming after interruptions.
|
||||
|
@ -1281,11 +1286,20 @@ impl Document {
|
|||
self.animation_frame_ident.set(ident);
|
||||
self.animation_frame_list.borrow_mut().insert(ident, 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
|
||||
let ConstellationChan(ref chan) = *self.window.constellation_chan();
|
||||
let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
|
||||
AnimationState::AnimationCallbacksPresent);
|
||||
chan.send(event).unwrap();
|
||||
if !self.running_animation_callbacks.get() {
|
||||
let ConstellationChan(ref chan) = *self.window.constellation_chan();
|
||||
let event = ConstellationMsg::ChangeRunningAnimationsState(
|
||||
self.window.pipeline(),
|
||||
AnimationState::AnimationCallbacksPresent);
|
||||
chan.send(event).unwrap();
|
||||
}
|
||||
|
||||
ident
|
||||
}
|
||||
|
@ -1305,6 +1319,7 @@ impl Document {
|
|||
pub fn run_the_animation_frame_callbacks(&self) {
|
||||
let animation_frame_list =
|
||||
mem::replace(&mut *self.animation_frame_list.borrow_mut(), BTreeMap::new());
|
||||
self.running_animation_callbacks.set(true);
|
||||
let performance = self.window.Performance();
|
||||
let performance = performance.r();
|
||||
let timing = performance.Now();
|
||||
|
@ -1324,6 +1339,8 @@ impl Document {
|
|||
chan.send(event).unwrap();
|
||||
}
|
||||
|
||||
self.running_animation_callbacks.set(false);
|
||||
|
||||
self.window.reflow(ReflowGoal::ForDisplay,
|
||||
ReflowQueryType::NoQuery,
|
||||
ReflowReason::RequestAnimationFrame);
|
||||
|
@ -1676,6 +1693,7 @@ impl Document {
|
|||
scripting_enabled: Cell::new(browsing_context.is_some()),
|
||||
animation_frame_ident: Cell::new(0),
|
||||
animation_frame_list: DOMRefCell::new(BTreeMap::new()),
|
||||
running_animation_callbacks: Cell::new(false),
|
||||
loader: DOMRefCell::new(doc_loader),
|
||||
current_parser: Default::default(),
|
||||
reflow_timeout: Cell::new(None),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue