From 46c42e55c6e0b08d9e7db989d6a10f073525e999 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 21 Jul 2021 15:58:01 +0200 Subject: [PATCH] backend/drm: add support for FB_DAMAGE_CLIPS This allows the kernel to access our buffer damage. Some drivers can take advantage of this, e.g. for PSR2 panels (Panel Self Refresh) or for transfer over USB. Closes: https://github.com/swaywm/wlroots/issues/1267 --- backend/drm/atomic.c | 21 +++++++++++++++++++++ backend/drm/properties.c | 1 + include/backend/drm/properties.h | 3 ++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index 35dca7d4..a1774f9c 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -201,6 +201,18 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn, } } + uint32_t fb_damage_clips = 0; + if ((state->committed & WLR_OUTPUT_STATE_DAMAGE) && + crtc->primary->props.fb_damage_clips != 0) { + int rects_len; + const pixman_box32_t *rects = pixman_region32_rectangles( + (pixman_region32_t *)&state->damage, &rects_len); + if (drmModeCreatePropertyBlob(drm->fd, rects, + sizeof(*rects) * rects_len, &fb_damage_clips) != 0) { + wlr_log_errno(WLR_ERROR, "Failed to create FB_DAMAGE_CLIPS property blob"); + } + } + bool prev_vrr_enabled = output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED; bool vrr_enabled = prev_vrr_enabled; @@ -235,6 +247,10 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn, atomic_add(&atom, crtc->id, crtc->props.vrr_enabled, vrr_enabled); } set_plane_props(&atom, drm, crtc->primary, crtc->id, 0, 0); + if (crtc->primary->props.fb_damage_clips != 0) { + atomic_add(&atom, crtc->primary->id, + crtc->primary->props.fb_damage_clips, fb_damage_clips); + } if (crtc->cursor) { if (drm_connector_is_cursor_visible(conn)) { set_plane_props(&atom, drm, crtc->cursor, crtc->id, @@ -269,6 +285,11 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn, rollback_blob(drm, &crtc->gamma_lut, gamma_lut); } + if (fb_damage_clips != 0 && + drmModeDestroyPropertyBlob(drm->fd, fb_damage_clips) != 0) { + wlr_log_errno(WLR_ERROR, "Failed to destroy FB_DAMAGE_CLIPS property blob"); + } + return ok; } diff --git a/backend/drm/properties.c b/backend/drm/properties.c index 5581a130..637eb4bd 100644 --- a/backend/drm/properties.c +++ b/backend/drm/properties.c @@ -47,6 +47,7 @@ static const struct prop_info plane_info[] = { { "CRTC_W", INDEX(crtc_w) }, { "CRTC_X", INDEX(crtc_x) }, { "CRTC_Y", INDEX(crtc_y) }, + { "FB_DAMAGE_CLIPS", INDEX(fb_damage_clips) }, { "FB_ID", INDEX(fb_id) }, { "IN_FORMATS", INDEX(in_formats) }, { "SRC_H", INDEX(src_h) }, diff --git a/include/backend/drm/properties.h b/include/backend/drm/properties.h index 9e1fe0b6..bd90871d 100644 --- a/include/backend/drm/properties.h +++ b/include/backend/drm/properties.h @@ -59,8 +59,9 @@ union wlr_drm_plane_props { uint32_t crtc_h; uint32_t fb_id; uint32_t crtc_id; + uint32_t fb_damage_clips; }; - uint32_t props[13]; + uint32_t props[14]; }; bool get_drm_connector_props(int fd, uint32_t id,