diff --git a/libweston/backend-drm/drm-internal.h b/libweston/backend-drm/drm-internal.h index 706dfcab001906a31864770248726861172bd992..c6938d922a5565e18f3a8a320698e2b32c768eeb 100644 --- a/libweston/backend-drm/drm-internal.h +++ b/libweston/backend-drm/drm-internal.h @@ -187,6 +187,7 @@ enum wdrm_connector_property { WDRM_CONNECTOR_HDCP_CONTENT_TYPE, WDRM_CONNECTOR_PANEL_ORIENTATION, WDRM_CONNECTOR_HDR_OUTPUT_METADATA, + WDRM_CONNECTOR_MAX_BPC, WDRM_CONNECTOR__COUNT }; diff --git a/libweston/backend-drm/kms.c b/libweston/backend-drm/kms.c index 6e2d29b27b6de77657a904a4160ef438fb0323c7..cd4049a82fcf113940f05d332b1677a5248a219f 100644 --- a/libweston/backend-drm/kms.c +++ b/libweston/backend-drm/kms.c @@ -146,6 +146,7 @@ const struct drm_property_info connector_props[] = { [WDRM_CONNECTOR_HDR_OUTPUT_METADATA] = { .name = "HDR_OUTPUT_METADATA", }, + [WDRM_CONNECTOR_MAX_BPC] = { .name = "max bpc", }, }; const struct drm_property_info crtc_props[] = { @@ -924,6 +925,35 @@ drm_connector_set_hdcp_property(struct drm_connector *connector, assert(ret == 0); } +static int +drm_connector_set_max_bpc(struct drm_connector *connector, + struct drm_output *output, + drmModeAtomicReq *req) +{ + const struct drm_property_info *info; + uint64_t max_bpc; + uint64_t a, b; + + if (!drm_connector_has_prop(connector, WDRM_CONNECTOR_MAX_BPC)) + return 0; + + info = &connector->props[WDRM_CONNECTOR_MAX_BPC]; + assert(info->flags & DRM_MODE_PROP_RANGE); + assert(info->num_range_values == 2); + a = info->range_values[0]; + b = info->range_values[1]; + assert(a <= b); + + /* HDR modes need more bits, SDR mode is happy with 8 bits */ + if (output->base.eotf_mode == WESTON_EOTF_MODE_SDR) + max_bpc = MIN(MAX(8, a), b); + else + max_bpc = MIN(MAX(16, a), b); + + return connector_add_prop(req, connector, + WDRM_CONNECTOR_MAX_BPC, max_bpc); +} + static int drm_output_apply_state_atomic(struct drm_output_state *state, drmModeAtomicReq *req, @@ -983,6 +1013,8 @@ drm_output_apply_state_atomic(struct drm_output_state *state, WDRM_CONNECTOR_HDR_OUTPUT_METADATA, output->hdr_output_metadata_blob_id); } + + ret |= drm_connector_set_max_bpc(&head->connector, output, req); } if (ret != 0) {