backend-rdp: 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.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
Philipp Zabel 2023-07-04 16:50:08 +02:00 committed by Marius Vlad
parent 5a95339d7a
commit e541aea2d7
1 changed files with 4 additions and 7 deletions

View File

@ -280,8 +280,7 @@ rdp_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
struct rdp_peers_item *peer; struct rdp_peers_item *peer;
struct timespec now, target; struct timespec now, target;
int refresh_nsec = millihz_to_nsec(output_base->current_mode->refresh); int refresh_nsec = millihz_to_nsec(output_base->current_mode->refresh);
int refresh_msec = refresh_nsec / 1000000; int64_t delay_nsec;
int next_frame_delta;
/* Calculate the time we should complete this frame such that frames /* Calculate the time we should complete this frame such that frames
are spaced out by the specified monitor refresh. Note that our timer are spaced out by the specified monitor refresh. Note that our timer
@ -292,10 +291,7 @@ rdp_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
timespec_add_nsec(&target, &output_base->frame_time, refresh_nsec); timespec_add_nsec(&target, &output_base->frame_time, refresh_nsec);
next_frame_delta = (int)timespec_sub_to_msec(&target, &now); delay_nsec = CLIP(timespec_sub_to_nsec(&target, &now), 1, refresh_nsec);
if (next_frame_delta < 1 || next_frame_delta > refresh_msec) {
next_frame_delta = refresh_msec;
}
assert(output); assert(output);
@ -317,7 +313,8 @@ rdp_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
pixman_region32_fini(&transformed_damage); pixman_region32_fini(&transformed_damage);
} }
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));
return 0; return 0;
} }