From 4d14adaa2cefaf5bc33f50842a072758216a8ce3 Mon Sep 17 00:00:00 2001
From: Philipp Zabel
Date: Tue, 4 Jul 2023 16:44:11 +0200
Subject: [PATCH] backend-pipewire: make sure to finish frames with timestamps
in the past
Round up the ms delay to make sure that the finish_frame_timer always
expires after the next frame_time. That way, finish_frame_handler()
never passes a timestamp in the future to weston_output_finish_frame().
Setting frame_time into the future risks hitting an assert in
weston_output_finish_frame(), when it is called from start_repaint_loop
within the frame interval.
Use CLIP() to simplify limiting the ms delay to a reasonable range.
Signed-off-by: Philipp Zabel
---
libweston/backend-pipewire/pipewire.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/libweston/backend-pipewire/pipewire.c b/libweston/backend-pipewire/pipewire.c
index dc2fe10c7..01a9a1de7 100644
--- a/libweston/backend-pipewire/pipewire.c
+++ b/libweston/backend-pipewire/pipewire.c
@@ -746,19 +746,15 @@ pipewire_output_arm_timer(struct pipewire_output *output)
struct timespec now;
struct timespec target;
int refresh_nsec = millihz_to_nsec(output->base.current_mode->refresh);
- int refresh_msec = refresh_nsec / 1000000;
- int next_frame_delta;
+ int64_t delay_nsec;
weston_compositor_read_presentation_clock(ec, &now);
timespec_add_nsec(&target, &output->base.frame_time, refresh_nsec);
- next_frame_delta = (int)timespec_sub_to_msec(&target, &now);
- if (next_frame_delta < 1)
- next_frame_delta = 1;
- if (next_frame_delta > refresh_msec)
- next_frame_delta = refresh_msec;
+ delay_nsec = CLIP(timespec_sub_to_nsec(&target, &now), 1, refresh_nsec);
- wl_event_source_timer_update(output->finish_frame_timer, next_frame_delta);
+ wl_event_source_timer_update(output->finish_frame_timer,
+ DIV_ROUND_UP(delay_nsec, 1000000));
}
static int