mirror of
https://github.com/servo/servo.git
synced 2025-06-11 10:00:18 +00:00
Fix animation frame callback cancellation (#35849)
Signed-off-by: Xiaocheng Hu <xiaochengh.work@gmail.com>
This commit is contained in:
parent
7fc5dc5c69
commit
b1e1e01ee9
2 changed files with 8 additions and 23 deletions
|
@ -345,7 +345,7 @@ pub(crate) struct Document {
|
||||||
animation_frame_ident: Cell<u32>,
|
animation_frame_ident: Cell<u32>,
|
||||||
/// <https://html.spec.whatwg.org/multipage/#list-of-animation-frame-callbacks>
|
/// <https://html.spec.whatwg.org/multipage/#list-of-animation-frame-callbacks>
|
||||||
/// List of animation frame callbacks
|
/// List of animation frame callbacks
|
||||||
animation_frame_list: DomRefCell<Vec<(u32, Option<AnimationFrameCallback>)>>,
|
animation_frame_list: DomRefCell<VecDeque<(u32, Option<AnimationFrameCallback>)>>,
|
||||||
/// Whether we're in the process of running animation callbacks.
|
/// Whether we're in the process of running animation callbacks.
|
||||||
///
|
///
|
||||||
/// Tracking this is not necessary for correctness. Instead, it is an optimization to avoid
|
/// Tracking this is not necessary for correctness. Instead, it is an optimization to avoid
|
||||||
|
@ -2337,7 +2337,7 @@ impl Document {
|
||||||
self.animation_frame_ident.set(ident);
|
self.animation_frame_ident.set(ident);
|
||||||
self.animation_frame_list
|
self.animation_frame_list
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.push((ident, Some(callback)));
|
.push_back((ident, Some(callback)));
|
||||||
|
|
||||||
// If we are running 'fake' animation frames, we unconditionally
|
// If we are running 'fake' animation frames, we unconditionally
|
||||||
// set up a one-shot timer for script to execute the rAF callbacks.
|
// set up a one-shot timer for script to execute the rAF callbacks.
|
||||||
|
@ -2380,11 +2380,6 @@ impl Document {
|
||||||
/// <https://html.spec.whatwg.org/multipage/#run-the-animation-frame-callbacks>
|
/// <https://html.spec.whatwg.org/multipage/#run-the-animation-frame-callbacks>
|
||||||
pub(crate) fn run_the_animation_frame_callbacks(&self, can_gc: CanGc) {
|
pub(crate) fn run_the_animation_frame_callbacks(&self, can_gc: CanGc) {
|
||||||
let _realm = enter_realm(self);
|
let _realm = enter_realm(self);
|
||||||
rooted_vec!(let mut animation_frame_list);
|
|
||||||
mem::swap(
|
|
||||||
&mut *animation_frame_list,
|
|
||||||
&mut *self.animation_frame_list.borrow_mut(),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.pending_animation_ticks
|
self.pending_animation_ticks
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -2394,8 +2389,10 @@ impl Document {
|
||||||
let was_faking_animation_frames = self.is_faking_animation_frames();
|
let was_faking_animation_frames = self.is_faking_animation_frames();
|
||||||
let timing = self.global().performance().Now();
|
let timing = self.global().performance().Now();
|
||||||
|
|
||||||
for (_, callback) in animation_frame_list.drain(..) {
|
let num_callbacks = self.animation_frame_list.borrow().len();
|
||||||
if let Some(callback) = callback {
|
for _ in 0..num_callbacks {
|
||||||
|
let (_, maybe_callback) = self.animation_frame_list.borrow_mut().pop_front().unwrap();
|
||||||
|
if let Some(callback) = maybe_callback {
|
||||||
callback.call(self, *timing, can_gc);
|
callback.call(self, *timing, can_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2440,16 +2437,7 @@ impl Document {
|
||||||
let just_crossed_spurious_animation_threshold =
|
let just_crossed_spurious_animation_threshold =
|
||||||
!was_faking_animation_frames && self.is_faking_animation_frames();
|
!was_faking_animation_frames && self.is_faking_animation_frames();
|
||||||
if is_empty || just_crossed_spurious_animation_threshold {
|
if is_empty || just_crossed_spurious_animation_threshold {
|
||||||
if is_empty {
|
if !is_empty {
|
||||||
// If the current animation frame list in the DOM instance is empty,
|
|
||||||
// we can reuse the original `Vec<T>` that we put on the stack to
|
|
||||||
// avoid allocating a new one next time an animation callback
|
|
||||||
// is queued.
|
|
||||||
mem::swap(
|
|
||||||
&mut *self.animation_frame_list.borrow_mut(),
|
|
||||||
&mut *animation_frame_list,
|
|
||||||
);
|
|
||||||
} else if just_crossed_spurious_animation_threshold {
|
|
||||||
// We just realized that we need to stop requesting compositor's animation ticks
|
// We just realized that we need to stop requesting compositor's animation ticks
|
||||||
// due to spurious animation frames, but we still have rAF callbacks queued. Since
|
// due to spurious animation frames, but we still have rAF callbacks queued. Since
|
||||||
// `is_faking_animation_frames` would not have been true at the point where these
|
// `is_faking_animation_frames` would not have been true at the point where these
|
||||||
|
@ -3686,7 +3674,7 @@ impl Document {
|
||||||
asap_scripts_set: Default::default(),
|
asap_scripts_set: Default::default(),
|
||||||
scripting_enabled: has_browsing_context,
|
scripting_enabled: has_browsing_context,
|
||||||
animation_frame_ident: Cell::new(0),
|
animation_frame_ident: Cell::new(0),
|
||||||
animation_frame_list: DomRefCell::new(vec![]),
|
animation_frame_list: DomRefCell::new(VecDeque::new()),
|
||||||
running_animation_callbacks: Cell::new(false),
|
running_animation_callbacks: Cell::new(false),
|
||||||
loader: DomRefCell::new(doc_loader),
|
loader: DomRefCell::new(doc_loader),
|
||||||
current_parser: Default::default(),
|
current_parser: Default::default(),
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[cancel-pending.html]
|
|
||||||
[cancelAnimationFrame cancels a pending animation frame callback]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue