backend-drm: set connector property "Colorspace"

Based on what is configured in weston_output, check and set the
colorimetry mode into KMS connector property "Colorspace".

This changes how video sinks interpret the pixels, and should allow
driving e.g. WCG monitors in BT.2020 mode.

This does not alter the pixel values themselves. That is the color
manager responsibility, and ultimately the responsibility of the
frontend and the end user to match the monitor driving mode with the
output color profile they chose.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
Pekka Paalanen 2023-09-20 13:11:30 +03:00 committed by Pekka Paalanen
parent 45ae99aff7
commit 8556059785
4 changed files with 53 additions and 0 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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;
}

View File

@ -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) {