aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-05-23 10:50:37 -0700
committerbors-servo <lbergstrom+bors@mozilla.com>2016-05-23 10:50:37 -0700
commit7d02c2055d5c5c7a5a6b1fff34bbef75e1da7cf6 (patch)
tree0b7f005ac4432a7159527b94a5586eda02547d77
parent208337976d0b913e00fe9c090c6868027092a0a1 (diff)
parent1e9be028cf6f5f347dcf2d6f66caa850ec3ee6e4 (diff)
downloadservo-7d02c2055d5c5c7a5a6b1fff34bbef75e1da7cf6.tar.gz
servo-7d02c2055d5c5c7a5a6b1fff34bbef75e1da7cf6.zip
Auto merge of #11341 - nox:raf, r=pcwalton
Use a simple Vec for the animation frame list Adding an animation frame list is now just pushing a new pair onto the vector, while canceling one is setting its callback to None. This means we can't send NoAnimationCallbacksPresent anymore to the constellation when all entries were cancelled, but I'm not sure that's very important anyway. The good downside of this change is that when running the callbacks, if no new one was queued during their execution, we can just swap back the original Vec into the Document in run_the_animation_frame_callbacks, thus reusing the original allocation. <!-- 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/11341) <!-- Reviewable:end -->
-rw-r--r--components/script/dom/document.rs28
1 files changed, 15 insertions, 13 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 10645b761d7..2aebe049d21 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -112,8 +112,8 @@ use std::ascii::AsciiExt;
use std::borrow::ToOwned;
use std::boxed::FnBox;
use std::cell::{Cell, Ref, RefMut};
+use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
-use std::collections::{BTreeMap, HashMap};
use std::default::Default;
use std::mem;
use std::ptr;
@@ -200,7 +200,7 @@ pub struct Document {
/// https://html.spec.whatwg.org/multipage/#list-of-animation-frame-callbacks
/// List of animation frame callbacks
#[ignore_heap_size_of = "closures are hard"]
- animation_frame_list: DOMRefCell<BTreeMap<u32, Box<FnBox(f64)>>>,
+ animation_frame_list: DOMRefCell<Vec<(u32, Option<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
@@ -1282,7 +1282,7 @@ impl Document {
let ident = self.animation_frame_ident.get() + 1;
self.animation_frame_ident.set(ident);
- self.animation_frame_list.borrow_mut().insert(ident, callback);
+ 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.
@@ -1303,25 +1303,25 @@ impl Document {
/// https://html.spec.whatwg.org/multipage/#dom-window-cancelanimationframe
pub fn cancel_animation_frame(&self, ident: u32) {
- self.animation_frame_list.borrow_mut().remove(&ident);
- if self.animation_frame_list.borrow().is_empty() {
- let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
- AnimationState::NoAnimationCallbacksPresent);
- self.window.constellation_chan().send(event).unwrap();
+ let mut list = self.animation_frame_list.borrow_mut();
+ if let Some(mut pair) = list.iter_mut().find(|pair| pair.0 == ident) {
+ pair.1 = None;
}
}
/// https://html.spec.whatwg.org/multipage/#run-the-animation-frame-callbacks
pub fn run_the_animation_frame_callbacks(&self) {
- let animation_frame_list =
- mem::replace(&mut *self.animation_frame_list.borrow_mut(), BTreeMap::new());
+ let mut animation_frame_list =
+ mem::replace(&mut *self.animation_frame_list.borrow_mut(), vec![]);
self.running_animation_callbacks.set(true);
let performance = self.window.Performance();
let performance = performance.r();
let timing = performance.Now();
- for (_, callback) in animation_frame_list {
- callback(*timing);
+ for (_, callback) in animation_frame_list.drain(..) {
+ if let Some(callback) = callback {
+ callback(*timing);
+ }
}
// Only send the animation change state message after running any callbacks.
@@ -1329,6 +1329,8 @@ impl Document {
// the next frame (which is the common case), we won't send a NoAnimationCallbacksPresent
// message quickly followed by an AnimationCallbacksPresent message.
if self.animation_frame_list.borrow().is_empty() {
+ mem::swap(&mut *self.animation_frame_list.borrow_mut(),
+ &mut animation_frame_list);
let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
AnimationState::NoAnimationCallbacksPresent);
self.window.constellation_chan().send(event).unwrap();
@@ -1686,7 +1688,7 @@ impl Document {
asap_scripts_set: DOMRefCell::new(vec![]),
scripting_enabled: Cell::new(browsing_context.is_some()),
animation_frame_ident: Cell::new(0),
- animation_frame_list: DOMRefCell::new(BTreeMap::new()),
+ animation_frame_list: DOMRefCell::new(vec![]),
running_animation_callbacks: Cell::new(false),
loader: DOMRefCell::new(doc_loader),
current_parser: Default::default(),