summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Plourde <frederic.plourde@collabora.co.uk>2014-11-04 06:30:11 -0500
committerFrederic Plourde <frederic.plourde@collabora.co.uk>2014-11-04 10:56:05 -0500
commit507cfb65fba6ed2f4e0b3973f6335ba98aa97894 (patch)
tree999530c63a2f1e5ca6bd71fb31efe4d3fe2f2fd7
parent280e7dd918f1717c7d677676384a9cd991097741 (diff)
compositor: Abort on bad frame timestampbad_timestamp_abort
Many features, like animations, hardly depend on page flip timestamps to work properly, but some DRM drivers do not correctly support page flip timestamps (or not at all) and in that case, things start to go wrong. This patch adds sanity check to weston_output_finish_frame to ensure that received timestamps are free from those pathologies: 1) Timestamps exactly equal 0 2) Timestamps do not advance from one frame to the next If a pathological case is detected, we gracefully exit Weston with an appropriate exit code to help developers debug their drivers. This fixes: https://bugs.freedesktop.org/show_bug.cgi?id=79502 Note: This patch depends on "compositor: Return a user-defined exit code"
-rw-r--r--src/compositor.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/compositor.c b/src/compositor.c
index ac5bda27..f2541161 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2052,6 +2052,33 @@ weston_compositor_read_input(int fd, uint32_t mask, void *data)
return 1;
}
+static void
+weston_output_check_timestamp(struct weston_output *output,
+ const struct timespec *stamp)
+{
+ int bad_timestamp = 0;
+ uint32_t cur_frame_time = stamp->tv_sec * 1000 +
+ stamp->tv_nsec / 1000000;
+
+ /* Getting zeroed-out timestamps is very unlikely and probably
+ * indicates that DRM driver does not support it.
+ */
+ if (stamp->tv_sec == 0 && stamp->tv_nsec == 0)
+ bad_timestamp = 1;
+
+ /* Also, let's make sure that current stamp has advanced
+ * at least a little since last time.
+ */
+ if (cur_frame_time <= output->frame_time)
+ bad_timestamp = 1;
+
+ if (bad_timestamp) {
+ weston_log("Bad timestamp! Abort Weston! %m\n");
+ weston_compositor_exit_with_code(output->compositor,
+ EXIT_FAILURE);
+ }
+}
+
WL_EXPORT void
weston_output_finish_frame(struct weston_output *output,
const struct timespec *stamp)
@@ -2062,6 +2089,8 @@ weston_output_finish_frame(struct weston_output *output,
int fd, r;
uint32_t refresh_nsec;
+ weston_output_check_timestamp(output, stamp);
+
refresh_nsec = 1000000000000UL / output->current_mode->refresh;
weston_presentation_feedback_present_list(&output->feedback_list,
output, refresh_nsec, stamp,