diff --git a/libweston/backend-drm/drm-internal.h b/libweston/backend-drm/drm-internal.h index 7cc554872..38e678db1 100644 --- a/libweston/backend-drm/drm-internal.h +++ b/libweston/backend-drm/drm-internal.h @@ -548,6 +548,7 @@ struct drm_output { uint64_t ackd_color_outcome_serial; unsigned max_bpc; + enum wdrm_colorspace connector_colorspace; bool deprecated_gamma_is_set; bool legacy_gamma_not_supported; @@ -767,6 +768,9 @@ drm_output_set_cursor_view(struct drm_output *output, struct weston_view *ev); int drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output); +enum wdrm_colorspace +wdrm_colorspace_from_output(struct weston_output *output); + #ifdef BUILD_DRM_GBM extern struct drm_fb * drm_fb_get_from_paint_node(struct drm_output_state *state, diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index f8be3734a..62f73d003 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -2259,6 +2259,10 @@ drm_output_enable(struct weston_output *base) output->format = b->format; } + output->connector_colorspace = wdrm_colorspace_from_output(&output->base); + if (output->connector_colorspace == WDRM_COLORSPACE__COUNT) + return -1; + ret = drm_output_attach_crtc(output); if (ret < 0) return -1; diff --git a/libweston/backend-drm/kms-color.c b/libweston/backend-drm/kms-color.c index 610b24426..fde6e3e9f 100644 --- a/libweston/backend-drm/kms-color.c +++ b/libweston/backend-drm/kms-color.c @@ -176,3 +176,20 @@ drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output) return 0; } + +enum wdrm_colorspace +wdrm_colorspace_from_output(struct weston_output *output) +{ + enum weston_colorimetry_mode cmode = output->colorimetry_mode; + const struct weston_colorimetry_mode_info *cm; + + cm = weston_colorimetry_mode_info_get(cmode); + if (!(weston_output_get_supported_colorimetry_modes(output) & cmode) || + !cm || cm->wdrm == WDRM_COLORSPACE__COUNT) { + weston_log("Error: DRM output '%s' does not support colorimetry mode %s.", + output->name, weston_colorimetry_mode_to_str(cmode)); + return WDRM_COLORSPACE__COUNT; + } + + return cm->wdrm; +} diff --git a/libweston/backend-drm/kms.c b/libweston/backend-drm/kms.c index 2a27cd6ce..ccbfd4d93 100644 --- a/libweston/backend-drm/kms.c +++ b/libweston/backend-drm/kms.c @@ -1167,6 +1167,32 @@ drm_connector_set_content_type(struct drm_connector *connector, WDRM_CONNECTOR_CONTENT_TYPE, prop_val); } +static int +drm_connector_set_colorspace(struct drm_connector *connector, + enum wdrm_colorspace colorspace, + drmModeAtomicReq *req) +{ + const struct drm_property_info *info; + const struct drm_property_enum_info *enum_info; + + assert(colorspace >= 0); + assert(colorspace < WDRM_COLORSPACE__COUNT); + + if (!drm_connector_has_prop(connector, WDRM_CONNECTOR_COLORSPACE)) { + if (colorspace == WDRM_COLORSPACE_DEFAULT) + return 0; + + return -1; + } + + info = &connector->props[WDRM_CONNECTOR_COLORSPACE]; + enum_info = &info->enum_values[colorspace]; + assert(enum_info->valid); + + return connector_add_prop(req, connector, + WDRM_CONNECTOR_COLORSPACE, enum_info->value); +} + static int drm_output_apply_state_atomic(struct drm_output_state *state, drmModeAtomicReq *req, @@ -1276,6 +1302,8 @@ drm_output_apply_state_atomic(struct drm_output_state *state, } ret |= drm_connector_set_max_bpc(&head->connector, output, req); + ret |= drm_connector_set_colorspace(&head->connector, + output->connector_colorspace, req); } if (ret != 0) {