summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel A. Vico <mvicomoya@nvidia.com>2016-03-01 22:19:14 +0100
committerMiguel A. Vico <mvicomoya@nvidia.com>2016-05-10 15:17:54 +0200
commit35f1ea4c4ac7c329cb38bafd181585c5fd23d569 (patch)
treed157405de26c66a10952ce10c478f9835d5ab4ae
parentb82703ea54720c74bf6ff38fcff344cfa5153f48 (diff)
compositor-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 <mvicomoya@nvidia.com> Reviewed-by: Andy Ritger <aritger@nvidia.com>
-rw-r--r--src/compositor-drm.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index a81d29f8..eb1a2dfd 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -1,6 +1,7 @@
/*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2011 Intel Corporation
+ * Copyright © 2016 NVIDIA Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -761,8 +762,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;
@@ -783,7 +792,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.
*/
fb_id = output->current->fb_id;
@@ -869,6 +878,17 @@ page_flip_handler(int fd, unsigned int frame,
else if (!output->vblank_pending) {
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