From 4f32a0b76f5a71bda761fb509c663a3ae9b8b90b Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 29 May 2026 16:56:16 +0200 Subject: [PATCH] backend/drm: add support for LUMINANCE KMS property References: https://lore.kernel.org/dri-devel/20260528054911.1513208-1-superm1@kernel.org/ --- backend/drm/atomic.c | 9 +++++++++ backend/drm/drm.c | 18 +++++++++++++++++- backend/drm/properties.c | 1 + include/backend/drm/drm.h | 2 ++ include/backend/drm/properties.h | 1 + 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index daa8ba9bf..7a2ff5e37 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -394,6 +394,11 @@ bool drm_atomic_connector_prepare(struct wlr_drm_connector_state *state, bool mo return false; } + double brightness = (state->base->committed & WLR_OUTPUT_STATE_BRIGHTNESS) ? + state->base->brightness : output->brightness; + uint64_t luminance = conn->luminance_bounds[0] + + round(brightness * (conn->luminance_bounds[1] - conn->luminance_bounds[0])); + state->mode_id = mode_id; state->gamma_lut = gamma_lut; state->fb_damage_clips = fb_damage_clips; @@ -401,6 +406,7 @@ bool drm_atomic_connector_prepare(struct wlr_drm_connector_state *state, bool mo state->vrr_enabled = vrr_enabled; state->colorspace = colorspace; state->hdr_output_metadata = hdr_output_metadata; + state->luminance = luminance; return true; } @@ -573,6 +579,9 @@ static void atomic_connector_add(struct atomic *atom, if (conn->props.hdr_output_metadata != 0) { atomic_add(atom, conn->id, conn->props.hdr_output_metadata, state->hdr_output_metadata); } + if (conn->props.luminance != 0) { + atomic_add(atom, conn->id, conn->props.luminance, state->luminance); + } atomic_add(atom, crtc->id, crtc->props.mode_id, state->mode_id); atomic_add(atom, crtc->id, crtc->props.active, active); if (active) { diff --git a/backend/drm/drm.c b/backend/drm/drm.c index d2f75f71f..6f66d23e8 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -44,7 +44,8 @@ static const uint32_t COMMIT_OUTPUT_STATE = WLR_OUTPUT_STATE_SIGNAL_TIMELINE | WLR_OUTPUT_STATE_COLOR_TRANSFORM | WLR_OUTPUT_STATE_IMAGE_DESCRIPTION | - WLR_OUTPUT_STATE_COLOR_REPRESENTATION; + WLR_OUTPUT_STATE_COLOR_REPRESENTATION | + WLR_OUTPUT_STATE_BRIGHTNESS; static const uint32_t SUPPORTED_OUTPUT_STATE = WLR_OUTPUT_STATE_BACKEND_OPTIONAL | COMMIT_OUTPUT_STATE; @@ -118,6 +119,12 @@ bool check_drm_features(struct wlr_drm_backend *drm) { wlr_log(WLR_INFO, "DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT supported"); } #endif +#define DRM_CLIENT_CAP_LUMINANCE 8 +#ifdef DRM_CLIENT_CAP_LUMINANCE + if (drm->iface == &atomic_iface && drmSetClientCap(drm->fd, DRM_CLIENT_CAP_LUMINANCE, 1) == 0) { + wlr_log(WLR_INFO, "DRM_CLIENT_CAP_LUMINANCE supported"); + } +#endif if (drm->iface == &legacy_iface) { drm->supports_tearing_page_flips = drmGetCap(drm->fd, DRM_CAP_ASYNC_PAGE_FLIP, &cap) == 0 && cap == 1; @@ -1736,6 +1743,15 @@ static bool connect_drm_connector(struct wlr_drm_connector *wlr_conn, } output->adaptive_sync_supported = vrr_capable; + if (wlr_conn->props.luminance != 0) { + if (introspect_drm_prop_range(drm->fd, wlr_conn->props.luminance, + &wlr_conn->luminance_bounds[0], &wlr_conn->luminance_bounds[1])) { + output->brightness_supported = true; + } else { + wlr_log(WLR_ERROR, "Failed to introspect 'LUMINANCE' property"); + } + } + size_t edid_len = 0; uint8_t *edid = get_drm_prop_blob(drm->fd, wlr_conn->id, wlr_conn->props.edid, &edid_len); diff --git a/backend/drm/properties.c b/backend/drm/properties.c index 4c6bdcb36..9336209d4 100644 --- a/backend/drm/properties.c +++ b/backend/drm/properties.c @@ -26,6 +26,7 @@ static const struct prop_info connector_info[] = { { "DPMS", INDEX(dpms) }, { "EDID", INDEX(edid) }, { "HDR_OUTPUT_METADATA", INDEX(hdr_output_metadata) }, + { "LUMINANCE", INDEX(luminance) }, { "PATH", INDEX(path) }, { "content type", INDEX(content_type) }, { "link-status", INDEX(link_status) }, diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index a8c5e077a..ef294e1c5 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -164,6 +164,7 @@ struct wlr_drm_connector_state { bool vrr_enabled; uint32_t colorspace; uint32_t hdr_output_metadata; + uint64_t luminance; }; /** @@ -199,6 +200,7 @@ struct wlr_drm_connector { drmModeConnection status; uint32_t id; uint64_t max_bpc_bounds[2]; + uint64_t luminance_bounds[2]; struct wlr_drm_lease *lease; struct wlr_drm_crtc *crtc; diff --git a/include/backend/drm/properties.h b/include/backend/drm/properties.h index 20e0a5bff..bd6bed641 100644 --- a/include/backend/drm/properties.h +++ b/include/backend/drm/properties.h @@ -28,6 +28,7 @@ struct wlr_drm_connector_props { uint32_t crtc_id; uint32_t colorspace; uint32_t hdr_output_metadata; + uint32_t luminance; }; struct wlr_drm_crtc_props {