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