diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 2c5e5faa5b8..ba9a4fdd89e 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -6751,7 +6751,10 @@ pub(crate) struct ImageAnimationUpdateCallback { impl ImageAnimationUpdateCallback { pub(crate) fn invoke(self, can_gc: CanGc) { - with_script_thread(|script_thread| script_thread.update_the_rendering(true, can_gc)) + with_script_thread(|script_thread| { + script_thread.set_has_pending_animation_tick(); + script_thread.update_the_rendering(can_gc); + }) } } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 595747f2b5a..49b135c5eb9 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -342,10 +342,12 @@ pub struct ScriptThread { #[no_trace] scheduled_script_thread_animation_timer: RefCell>, - /// A flag that lets the [`ScriptThread`]'s main loop know that the - /// [`Self::scheduled_script_thread_animation_timer`] timer fired and it should - /// trigger an animation tick "update the rendering" call. - should_trigger_script_thread_animation_tick: Arc, + /// Whether an animation tick is pending. This might either be because the Servo renderer + /// is managing animations and the [`ScriptThread`] has received a + /// [`ScriptThreadMessage::TickAllAnimations`] message or because the [`ScriptThread`] + /// itself is managing animations the the timer fired triggering a [`ScriptThread`]-based + /// animation tick. + has_pending_animation_tick: Arc, } struct BHMExitSignal { @@ -594,6 +596,11 @@ impl ScriptThread { } } + pub(crate) fn set_has_pending_animation_tick(&self) { + self.has_pending_animation_tick + .store(true, Ordering::Relaxed); + } + /// Step 13 of pub(crate) fn navigate( pipeline_id: PipelineId, @@ -965,7 +972,7 @@ impl ScriptThread { layout_factory, relative_mouse_down_point: Cell::new(Point2D::zero()), scheduled_script_thread_animation_timer: Default::default(), - should_trigger_script_thread_animation_tick: Arc::new(AtomicBool::new(false)), + has_pending_animation_tick: Arc::new(AtomicBool::new(false)), } } @@ -1165,25 +1172,16 @@ impl ScriptThread { /// /// Attempt to update the rendering and then do a microtask checkpoint if rendering was actually /// updated. - pub(crate) fn update_the_rendering(&self, requested_by_renderer: bool, can_gc: CanGc) { + pub(crate) fn update_the_rendering(&self, can_gc: CanGc) { *self.last_render_opportunity_time.borrow_mut() = Some(Instant::now()); - // If the ScriptThread animation timer fired, this is an animation tick. - let mut is_animation_tick = requested_by_renderer; - if self - .should_trigger_script_thread_animation_tick - .load(Ordering::Relaxed) - { - self.should_trigger_script_thread_animation_tick + let is_animation_tick = self.has_pending_animation_tick.load(Ordering::Relaxed); + if is_animation_tick { + self.has_pending_animation_tick .store(false, Ordering::Relaxed); - *self.scheduled_script_thread_animation_timer.borrow_mut() = None; - is_animation_tick = true; - } - - // If this is an animation tick, cancel any upcoming ScriptThread-based animation timer. - // This tick serves the purpose and we to limit animation ticks if some are coming from - // the renderer. - if requested_by_renderer { + // If this is an animation tick, cancel any upcoming ScriptThread-based animation timer. + // This tick serves the purpose and we to limit animation ticks if some are coming from + // the renderer. if let Some(timer_id) = self .scheduled_script_thread_animation_timer .borrow_mut() @@ -1412,8 +1410,7 @@ impl ScriptThread { const SCRIPT_THREAD_ANIMATION_TICK_DELAY: u64 = 30; debug!("Scheduling ScriptThread animation frame."); - let trigger_script_thread_animation = - self.should_trigger_script_thread_animation_tick.clone(); + let trigger_script_thread_animation = self.has_pending_animation_tick.clone(); let timer_id = self.schedule_timer(TimerEventRequest { callback: Box::new(move || { trigger_script_thread_animation.store(true, Ordering::Relaxed); @@ -1444,7 +1441,6 @@ impl ScriptThread { .receivers .recv(&self.task_queue, &self.timer_scheduler.borrow()); - let mut compositor_requested_update_the_rendering = false; loop { debug!("Handling event: {event:?}"); @@ -1515,7 +1511,7 @@ impl ScriptThread { MixedMessage::FromConstellation(ScriptThreadMessage::TickAllAnimations( _webviews, )) => { - compositor_requested_update_the_rendering = true; + self.set_has_pending_animation_tick(); }, MixedMessage::FromConstellation(ScriptThreadMessage::SendInputEvent(id, event)) => { self.handle_input_event(id, event) @@ -1643,7 +1639,7 @@ impl ScriptThread { // Update the rendering whenever we receive an IPC message. This may not actually do anything if // we are running animations and the compositor hasn't requested a new frame yet via a TickAllAnimatons // message. - self.update_the_rendering(compositor_requested_update_the_rendering, can_gc); + self.update_the_rendering(can_gc); true }