From eca5cca56125052003861529eb2c181b420845aa Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 28 Feb 2017 21:53:51 +0000 Subject: [PATCH] Account for very large repaint window misses At the bottom of weston_output_finish_frame(), code exists to account for flips which have missed the repaint window, by shifting them to lock on to the next repaint window rather than repainting immediately. This code only accounted for flips which missed their target by one repaint window. If they miss by multiples of the repaint window, adjust them until the next repaint timestamp is in the future. This will only happen in fairly extreme situations, such as Weston being scheduled out for a punitively long period of time. Nevertheless, try to help recovery by still aiming for more predictable timings. Signed-off-by: Daniel Stone Reviewed-by: Pekka Paalanen --- libweston/compositor.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libweston/compositor.c b/libweston/compositor.c index 2bca19cd..2a3074db 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -2510,9 +2510,14 @@ weston_output_finish_frame(struct weston_output *output, * the deadline given by repaint_msec? In that case we delay until * the deadline of the next frame, to give clients a more predictable * timing of the repaint cycle to lock on. */ - if (presented_flags == WP_PRESENTATION_FEEDBACK_INVALID && msec_rel < 0) - timespec_add_nsec(&output->next_repaint, &output->next_repaint, - refresh_nsec); + if (presented_flags == WP_PRESENTATION_FEEDBACK_INVALID && + msec_rel < 0) { + while (timespec_sub_to_nsec(&output->next_repaint, &now) < 0) { + timespec_add_nsec(&output->next_repaint, + &output->next_repaint, + refresh_nsec); + } + } out: output->repaint_status = REPAINT_SCHEDULED;