backend: add get_present_clock

This commit is contained in:
emersion 2018-10-01 22:44:33 +02:00
parent 9203bfdd4f
commit 54e1287f30
7 changed files with 33 additions and 6 deletions

View file

@ -64,6 +64,13 @@ struct wlr_session *wlr_backend_get_session(struct wlr_backend *backend) {
return NULL; 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) { static size_t parse_outputs_env(const char *name) {
const char *outputs_str = getenv(name); const char *outputs_str = getenv(name);
if (outputs_str == NULL) { if (outputs_str == NULL) {

View file

@ -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 = { static struct wlr_backend_impl backend_impl = {
.start = backend_start, .start = backend_start,
.destroy = backend_destroy, .destroy = backend_destroy,
.get_renderer = backend_get_renderer, .get_renderer = backend_get_renderer,
.get_present_clock = backend_get_present_clock,
}; };
bool wlr_backend_is_drm(struct wlr_backend *b) { bool wlr_backend_is_drm(struct wlr_backend *b) {

View file

@ -1,3 +1,4 @@
#define _POSIX_C_SOURCE 199309L
#include <assert.h> #include <assert.h>
#include <drm_mode.h> #include <drm_mode.h>
#include <EGL/egl.h> #include <EGL/egl.h>
@ -27,8 +28,8 @@
#include "util/signal.h" #include "util/signal.h"
bool check_drm_features(struct wlr_drm_backend *drm) { bool check_drm_features(struct wlr_drm_backend *drm) {
if (drm->parent) {
uint64_t cap; uint64_t cap;
if (drm->parent) {
if (drmGetCap(drm->fd, DRM_CAP_PRIME, &cap) || if (drmGetCap(drm->fd, DRM_CAP_PRIME, &cap) ||
!(cap & DRM_PRIME_CAP_IMPORT)) { !(cap & DRM_PRIME_CAP_IMPORT)) {
wlr_log(WLR_ERROR, 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"); const char *no_atomic = getenv("WLR_DRM_NO_ATOMIC");
if (no_atomic && strcmp(no_atomic, "1") == 0) { 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; drm->iface = &legacy_iface;
} else if (drmSetClientCap(drm->fd, DRM_CLIENT_CAP_ATOMIC, 1)) { } 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; drm->iface = &legacy_iface;
} else { } else {
wlr_log(WLR_DEBUG, "Using atomic DRM interface"); wlr_log(WLR_DEBUG, "Using atomic DRM interface");
drm->iface = &atomic_iface; 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; return true;
} }

View file

@ -6,6 +6,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <time.h>
#include <wayland-server.h> #include <wayland-server.h>
#include <wayland-util.h> #include <wayland-util.h>
#include <wlr/backend/drm.h> #include <wlr/backend/drm.h>
@ -67,6 +68,7 @@ struct wlr_drm_backend {
struct wlr_drm_backend *parent; struct wlr_drm_backend *parent;
const struct wlr_drm_interface *iface; const struct wlr_drm_interface *iface;
clockid_t clock;
int fd; int fd;

View file

@ -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. * Might return NULL for backends that don't use a session.
*/ */
struct wlr_session *wlr_backend_get_session(struct wlr_backend *backend); 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 #endif

View file

@ -10,6 +10,7 @@
#define WLR_BACKEND_INTERFACE_H #define WLR_BACKEND_INTERFACE_H
#include <stdbool.h> #include <stdbool.h>
#include <time.h>
#include <wlr/backend.h> #include <wlr/backend.h>
#include <wlr/render/egl.h> #include <wlr/render/egl.h>
@ -18,6 +19,7 @@ struct wlr_backend_impl {
void (*destroy)(struct wlr_backend *backend); void (*destroy)(struct wlr_backend *backend);
struct wlr_renderer *(*get_renderer)(struct wlr_backend *backend); struct wlr_renderer *(*get_renderer)(struct wlr_backend *backend);
struct wlr_session *(*get_session)(struct wlr_backend *backend); struct wlr_session *(*get_session)(struct wlr_backend *backend);
clockid_t (*get_present_clock)(struct wlr_backend *backend);
}; };
/** /**

View file

@ -18,8 +18,6 @@
#define OUTPUT_VERSION 3 #define OUTPUT_VERSION 3
#define DEFAULT_PRESENT_CLOCK CLOCK_MONOTONIC
static void output_send_to_resource(struct wl_resource *resource) { static void output_send_to_resource(struct wl_resource *resource) {
struct wlr_output *output = wlr_output_from_resource(resource); struct wlr_output *output = wlr_output_from_resource(resource);
const uint32_t version = wl_resource_get_version(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.frame);
wl_signal_init(&output->events.needs_swap); wl_signal_init(&output->events.needs_swap);
wl_signal_init(&output->events.swap_buffers); wl_signal_init(&output->events.swap_buffers);
wl_signal_init(&output->events.present);
wl_signal_init(&output->events.enable); wl_signal_init(&output->events.enable);
wl_signal_init(&output->events.mode); wl_signal_init(&output->events.mode);
wl_signal_init(&output->events.scale); 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) { unsigned seq, uint32_t flags) {
struct timespec now; struct timespec now;
if (when == NULL) { 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: " wlr_log_errno(WLR_ERROR, "failed to send output present event: "
"failed to read clock"); "failed to read clock");
return; return;