mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	backend: add get_present_clock
This commit is contained in:
		
							parent
							
								
									9203bfdd4f
								
							
						
					
					
						commit
						54e1287f30
					
				
					 7 changed files with 33 additions and 6 deletions
				
			
		| 
						 | 
					@ -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) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue