script: join compositor_requested_update_the_rendering into should_trigger_script_thread_animation_tick (#37889)

This will help us make "update the rendering" a proper task.

Testing: Existing WPT tests.

try run: https://github.com/sagudev/servo/actions/runs/16085256131

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
sagudev 2025-07-08 17:26:32 +02:00 committed by GitHub
parent 51367c22a6
commit e64bc6d282
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 26 additions and 27 deletions

View file

@ -6751,7 +6751,10 @@ pub(crate) struct ImageAnimationUpdateCallback {
impl ImageAnimationUpdateCallback { impl ImageAnimationUpdateCallback {
pub(crate) fn invoke(self, can_gc: CanGc) { 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);
})
} }
} }

View file

@ -342,10 +342,12 @@ pub struct ScriptThread {
#[no_trace] #[no_trace]
scheduled_script_thread_animation_timer: RefCell<Option<TimerId>>, scheduled_script_thread_animation_timer: RefCell<Option<TimerId>>,
/// A flag that lets the [`ScriptThread`]'s main loop know that the /// Whether an animation tick is pending. This might either be because the Servo renderer
/// [`Self::scheduled_script_thread_animation_timer`] timer fired and it should /// is managing animations and the [`ScriptThread`] has received a
/// trigger an animation tick "update the rendering" call. /// [`ScriptThreadMessage::TickAllAnimations`] message or because the [`ScriptThread`]
should_trigger_script_thread_animation_tick: Arc<AtomicBool>, /// itself is managing animations the the timer fired triggering a [`ScriptThread`]-based
/// animation tick.
has_pending_animation_tick: Arc<AtomicBool>,
} }
struct BHMExitSignal { 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 <https://html.spec.whatwg.org/multipage/#navigate> /// Step 13 of <https://html.spec.whatwg.org/multipage/#navigate>
pub(crate) fn navigate( pub(crate) fn navigate(
pipeline_id: PipelineId, pipeline_id: PipelineId,
@ -965,7 +972,7 @@ impl ScriptThread {
layout_factory, layout_factory,
relative_mouse_down_point: Cell::new(Point2D::zero()), relative_mouse_down_point: Cell::new(Point2D::zero()),
scheduled_script_thread_animation_timer: Default::default(), 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 /// Attempt to update the rendering and then do a microtask checkpoint if rendering was actually
/// updated. /// 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()); *self.last_render_opportunity_time.borrow_mut() = Some(Instant::now());
// If the ScriptThread animation timer fired, this is an animation tick. let is_animation_tick = self.has_pending_animation_tick.load(Ordering::Relaxed);
let mut is_animation_tick = requested_by_renderer; if is_animation_tick {
if self self.has_pending_animation_tick
.should_trigger_script_thread_animation_tick
.load(Ordering::Relaxed)
{
self.should_trigger_script_thread_animation_tick
.store(false, Ordering::Relaxed); .store(false, Ordering::Relaxed);
*self.scheduled_script_thread_animation_timer.borrow_mut() = None; // If this is an animation tick, cancel any upcoming ScriptThread-based animation timer.
is_animation_tick = true; // This tick serves the purpose and we to limit animation ticks if some are coming from
} // the 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 requested_by_renderer {
if let Some(timer_id) = self if let Some(timer_id) = self
.scheduled_script_thread_animation_timer .scheduled_script_thread_animation_timer
.borrow_mut() .borrow_mut()
@ -1412,8 +1410,7 @@ impl ScriptThread {
const SCRIPT_THREAD_ANIMATION_TICK_DELAY: u64 = 30; const SCRIPT_THREAD_ANIMATION_TICK_DELAY: u64 = 30;
debug!("Scheduling ScriptThread animation frame."); debug!("Scheduling ScriptThread animation frame.");
let trigger_script_thread_animation = let trigger_script_thread_animation = self.has_pending_animation_tick.clone();
self.should_trigger_script_thread_animation_tick.clone();
let timer_id = self.schedule_timer(TimerEventRequest { let timer_id = self.schedule_timer(TimerEventRequest {
callback: Box::new(move || { callback: Box::new(move || {
trigger_script_thread_animation.store(true, Ordering::Relaxed); trigger_script_thread_animation.store(true, Ordering::Relaxed);
@ -1444,7 +1441,6 @@ impl ScriptThread {
.receivers .receivers
.recv(&self.task_queue, &self.timer_scheduler.borrow()); .recv(&self.task_queue, &self.timer_scheduler.borrow());
let mut compositor_requested_update_the_rendering = false;
loop { loop {
debug!("Handling event: {event:?}"); debug!("Handling event: {event:?}");
@ -1515,7 +1511,7 @@ impl ScriptThread {
MixedMessage::FromConstellation(ScriptThreadMessage::TickAllAnimations( MixedMessage::FromConstellation(ScriptThreadMessage::TickAllAnimations(
_webviews, _webviews,
)) => { )) => {
compositor_requested_update_the_rendering = true; self.set_has_pending_animation_tick();
}, },
MixedMessage::FromConstellation(ScriptThreadMessage::SendInputEvent(id, event)) => { MixedMessage::FromConstellation(ScriptThreadMessage::SendInputEvent(id, event)) => {
self.handle_input_event(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 // 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 // we are running animations and the compositor hasn't requested a new frame yet via a TickAllAnimatons
// message. // message.
self.update_the_rendering(compositor_requested_update_the_rendering, can_gc); self.update_the_rendering(can_gc);
true true
} }