diff options
author | Frederic Plourde <frederic.plourde@collabora.co.uk> | 2014-11-04 06:30:11 -0500 |
---|---|---|
committer | Frederic Plourde <frederic.plourde@collabora.co.uk> | 2014-11-04 10:56:05 -0500 |
commit | 507cfb65fba6ed2f4e0b3973f6335ba98aa97894 (patch) | |
tree | 999530c63a2f1e5ca6bd71fb31efe4d3fe2f2fd7 | |
parent | 280e7dd918f1717c7d677676384a9cd991097741 (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.c | 29 |
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, |