From 54e1287f307d13566deaf51683da373f3524d1d9 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 1 Oct 2018 22:44:33 +0200 Subject: [PATCH] backend: add get_present_clock --- backend/backend.c | 7 +++++++ backend/drm/backend.c | 6 ++++++ backend/drm/drm.c | 12 +++++++++--- include/backend/drm/drm.h | 2 ++ include/wlr/backend.h | 4 ++++ include/wlr/backend/interface.h | 2 ++ types/wlr_output.c | 6 +++--- 7 files changed, 33 insertions(+), 6 deletions(-) diff --git a/backend/backend.c b/backend/backend.c index 2d6464b7..b8cf8797 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -64,6 +64,13 @@ struct wlr_session *wlr_backend_get_session(struct wlr_backend *backend) { return NULL; } +clockid_t wlr_backend_get_present_clock(struct wlr_backend *backend) { + if (backend->impl->get_present_clock) { + return backend->impl->get_present_clock(backend); + } + return CLOCK_MONOTONIC; +} + static size_t parse_outputs_env(const char *name) { const char *outputs_str = getenv(name); if (outputs_str == NULL) { diff --git a/backend/drm/backend.c b/backend/drm/backend.c index b298365e..b230613d 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -65,10 +65,16 @@ static struct wlr_renderer *backend_get_renderer( } } +static clockid_t backend_get_present_clock(struct wlr_backend *backend) { + struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend); + return drm->clock; +} + static struct wlr_backend_impl backend_impl = { .start = backend_start, .destroy = backend_destroy, .get_renderer = backend_get_renderer, + .get_present_clock = backend_get_present_clock, }; bool wlr_backend_is_drm(struct wlr_backend *b) { diff --git a/backend/drm/drm.c b/backend/drm/drm.c index ace0835e..753b6ab8 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -1,3 +1,4 @@ +#define _POSIX_C_SOURCE 199309L #include #include #include @@ -27,8 +28,8 @@ #include "util/signal.h" bool check_drm_features(struct wlr_drm_backend *drm) { + uint64_t cap; if (drm->parent) { - uint64_t cap; if (drmGetCap(drm->fd, DRM_CAP_PRIME, &cap) || !(cap & DRM_PRIME_CAP_IMPORT)) { wlr_log(WLR_ERROR, @@ -51,16 +52,21 @@ bool check_drm_features(struct wlr_drm_backend *drm) { const char *no_atomic = getenv("WLR_DRM_NO_ATOMIC"); if (no_atomic && strcmp(no_atomic, "1") == 0) { - wlr_log(WLR_DEBUG, "WLR_DRM_NO_ATOMIC set, forcing legacy DRM interface"); + wlr_log(WLR_DEBUG, + "WLR_DRM_NO_ATOMIC set, forcing legacy DRM interface"); drm->iface = &legacy_iface; } else if (drmSetClientCap(drm->fd, DRM_CLIENT_CAP_ATOMIC, 1)) { - wlr_log(WLR_DEBUG, "Atomic modesetting unsupported, using legacy DRM interface"); + wlr_log(WLR_DEBUG, + "Atomic modesetting unsupported, using legacy DRM interface"); drm->iface = &legacy_iface; } else { wlr_log(WLR_DEBUG, "Using atomic DRM interface"); drm->iface = &atomic_iface; } + int ret = drmGetCap(drm->fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap); + drm->clock = (ret == 0 && cap == 1) ? CLOCK_MONOTONIC : CLOCK_REALTIME; + return true; } diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index 3c728808..de5212d3 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,7 @@ struct wlr_drm_backend { struct wlr_drm_backend *parent; const struct wlr_drm_interface *iface; + clockid_t clock; int fd; diff --git a/include/wlr/backend.h b/include/wlr/backend.h index dfb8d2a8..aee45b73 100644 --- a/include/wlr/backend.h +++ b/include/wlr/backend.h @@ -62,5 +62,9 @@ struct wlr_renderer *wlr_backend_get_renderer(struct wlr_backend *backend); * Might return NULL for backends that don't use a session. */ struct wlr_session *wlr_backend_get_session(struct wlr_backend *backend); +/** + * Returns the clock used by the backend for presentation feedback. + */ +clockid_t wlr_backend_get_present_clock(struct wlr_backend *backend); #endif diff --git a/include/wlr/backend/interface.h b/include/wlr/backend/interface.h index 2c300709..a930c241 100644 --- a/include/wlr/backend/interface.h +++ b/include/wlr/backend/interface.h @@ -10,6 +10,7 @@ #define WLR_BACKEND_INTERFACE_H #include +#include #include #include @@ -18,6 +19,7 @@ struct wlr_backend_impl { void (*destroy)(struct wlr_backend *backend); struct wlr_renderer *(*get_renderer)(struct wlr_backend *backend); struct wlr_session *(*get_session)(struct wlr_backend *backend); + clockid_t (*get_present_clock)(struct wlr_backend *backend); }; /** diff --git a/types/wlr_output.c b/types/wlr_output.c index 4ffe561a..1baa5027 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -18,8 +18,6 @@ #define OUTPUT_VERSION 3 -#define DEFAULT_PRESENT_CLOCK CLOCK_MONOTONIC - static void output_send_to_resource(struct wl_resource *resource) { struct wlr_output *output = wlr_output_from_resource(resource); const uint32_t version = wl_resource_get_version(resource); @@ -268,6 +266,7 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, wl_signal_init(&output->events.frame); wl_signal_init(&output->events.needs_swap); wl_signal_init(&output->events.swap_buffers); + wl_signal_init(&output->events.present); wl_signal_init(&output->events.enable); wl_signal_init(&output->events.mode); wl_signal_init(&output->events.scale); @@ -566,7 +565,8 @@ void wlr_output_send_present(struct wlr_output *output, struct timespec *when, unsigned seq, uint32_t flags) { struct timespec now; if (when == NULL) { - if (!clock_gettime(DEFAULT_PRESENT_CLOCK, &now)) { + clockid_t clock = wlr_backend_get_present_clock(output->backend); + if (!clock_gettime(clock, &now)) { wlr_log_errno(WLR_ERROR, "failed to send output present event: " "failed to read clock"); return;