backend-vnc: 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 <p.zabel@pengutronix.de>
This commit is contained in:
Philipp Zabel 2023-07-04 14:44:03 +02:00 committed by Marius Vlad
parent 4d14adaa2c
commit 5a95339d7a
1 changed files with 3 additions and 8 deletions

View File

@ -953,8 +953,7 @@ vnc_output_repaint(struct weston_output *base, pixman_region32_t *damage)
struct vnc_backend *backend = output->backend;
struct timespec now, 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;
assert(output);
@ -976,14 +975,10 @@ vnc_output_repaint(struct weston_output *base, pixman_region32_t *damage)
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);
DIV_ROUND_UP(delay_nsec, 1000000));
return 0;
}