From b897295ffd88f1046e7150a084d57c41ced4cb9e Mon Sep 17 00:00:00 2001 From: "Miguel A. Vico" Date: Tue, 1 Mar 2016 22:19:14 +0100 Subject: [PATCH 4/6] backend-drm: Gracefully handle vblank and flip invalid timestamps Instant query for vblank timestamp may always fail, resulting in never scheduling a full repaint in drm_output_start_repaint_loop(). Additionally, timestamp provided in page_flip_handler() may also be invalid. This change makes both drm_output_start_repaint_loop() and page_flip_handler() to schedule a full repaint in any of the situations above. Signed-off-by: Miguel A Vico Moya Reviewed-by: Andy Ritger --- libweston/backend-drm/drm.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index 2780f3bd..94a2bf2a 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -4,6 +4,7 @@ * Copyright © 2017, 2018 Collabora, Ltd. * Copyright © 2017, 2018 General Electric Company * Copyright (c) 2018 DisplayLink (UK) Ltd. + * Copyright © 2016-2019 NVIDIA Corporation * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -319,6 +320,19 @@ drm_output_update_complete(struct drm_output *output, uint32_t flags, ts.tv_sec = sec; ts.tv_nsec = usec * 1000; + + /* Zero timestamp means failure to get valid timestamp, so + * immediately finish frame + * + * FIXME: Driver should never return an invalid page flip + * timestamp */ + if (ts.tv_sec == 0 && ts.tv_nsec == 0) { + weston_compositor_read_presentation_clock( + output->base.compositor, + &ts); + flags = WP_PRESENTATION_FEEDBACK_INVALID; + } + weston_output_finish_frame(&output->base, &ts, flags); /* We can't call this from frame_notify, because the output's @@ -555,8 +569,16 @@ drm_output_start_repaint_loop(struct weston_output *output_base) vbl.request.type |= drm_waitvblank_pipe(output); ret = drmWaitVBlank(backend->drm.fd, &vbl); - /* Error ret or zero timestamp means failure to get valid timestamp */ - if ((ret == 0) && (vbl.reply.tval_sec > 0 || vbl.reply.tval_usec > 0)) { + if (ret) { + /* Immediate query failed. It may always fail so we'll never get + * a valid timestamp to update msc and call into finish frame. + * Hence, jump to finish frame here. + */ + goto finish_frame; + } + + /* Zero timestamp means failure to get valid timestamp */ + if (vbl.reply.tval_sec > 0 || vbl.reply.tval_usec > 0) { ts.tv_sec = vbl.reply.tval_sec; ts.tv_nsec = vbl.reply.tval_usec * 1000; @@ -577,7 +599,7 @@ drm_output_start_repaint_loop(struct weston_output *output_base) } } - /* Immediate query didn't provide valid timestamp. + /* Immediate query succeeded, but didn't provide valid timestamp. * Use pageflip fallback. */ -- 2.25.1