From e3bd318547aeca306371ab78b1b01e3b06c6ba86 Mon Sep 17 00:00:00 2001 From: Ian Forbes Date: Tue, 19 Mar 2024 16:20:32 -0500 Subject: [PATCH] drm/backend: add support for cursor hotspots Enables DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT and sets the cursor hotspots on the cursor plane so virtualized drivers can accelerate mouse movement. Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3776 --- backend/drm/atomic.c | 10 ++++++++++ backend/drm/drm.c | 5 +++++ backend/drm/properties.c | 2 ++ include/backend/drm/properties.h | 4 +++- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index be215dab..9defa7c6 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -353,6 +353,10 @@ static void set_plane_props(struct atomic *atom, struct wlr_drm_backend *drm, atomic_add(atom, id, props->crtc_y, (uint64_t)y); } +static bool supports_cursor_hotspots(const struct wlr_drm_plane* plane) { + return plane->props.hotspot_x && plane->props.hotspot_y; +} + static void atomic_connector_add(struct atomic *atom, const struct wlr_drm_connector_state *state, bool modeset) { struct wlr_drm_connector *conn = state->connector; @@ -391,6 +395,12 @@ static void atomic_connector_add(struct atomic *atom, if (drm_connector_is_cursor_visible(conn)) { set_plane_props(atom, drm, crtc->cursor, state->cursor_fb, crtc->id, conn->cursor_x, conn->cursor_y); + if (supports_cursor_hotspots(crtc->cursor)) { + atomic_add(atom, crtc->cursor->id, + crtc->cursor->props.hotspot_x, conn->cursor_hotspot_x); + atomic_add(atom, crtc->cursor->id, + crtc->cursor->props.hotspot_y, conn->cursor_hotspot_y); + } } else { plane_disable(atom, crtc->cursor); } diff --git a/backend/drm/drm.c b/backend/drm/drm.c index fcdd060e..da194445 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -111,6 +111,11 @@ bool check_drm_features(struct wlr_drm_backend *drm) { wlr_log(WLR_DEBUG, "Using atomic DRM interface"); drm->iface = &atomic_iface; } +#ifdef DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT + if (drm->iface == &atomic_iface && drmSetClientCap(drm->fd, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT, 1) == 0) { + wlr_log(WLR_INFO, "DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT supported"); + } +#endif if (drm->iface == &legacy_iface) { drm->supports_tearing_page_flips = drmGetCap(drm->fd, DRM_CAP_ASYNC_PAGE_FLIP, &cap) == 0 && cap == 1; diff --git a/backend/drm/properties.c b/backend/drm/properties.c index ecd0d910..2058e37c 100644 --- a/backend/drm/properties.c +++ b/backend/drm/properties.c @@ -53,6 +53,8 @@ static const struct prop_info plane_info[] = { { "CRTC_Y", INDEX(crtc_y) }, { "FB_DAMAGE_CLIPS", INDEX(fb_damage_clips) }, { "FB_ID", INDEX(fb_id) }, + { "HOTSPOT_X", INDEX(hotspot_x) }, + { "HOTSPOT_Y", INDEX(hotspot_y) }, { "IN_FORMATS", INDEX(in_formats) }, { "SRC_H", INDEX(src_h) }, { "SRC_W", INDEX(src_w) }, diff --git a/include/backend/drm/properties.h b/include/backend/drm/properties.h index 4ce95767..c924c29b 100644 --- a/include/backend/drm/properties.h +++ b/include/backend/drm/properties.h @@ -65,8 +65,10 @@ union wlr_drm_plane_props { uint32_t fb_id; uint32_t crtc_id; uint32_t fb_damage_clips; + uint32_t hotspot_x; + uint32_t hotspot_y; }; - uint32_t props[14]; + uint32_t props[16]; }; bool get_drm_connector_props(int fd, uint32_t id,