backend-drm: get KMS colorimetry modes

Based on KMS "Colorspace" connector property, populate the mask of
supported colorimetry modes on a head.

EDID should be checked too, but it is currently ignored.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
Pekka Paalanen 2023-09-05 17:18:12 +03:00 committed by Pekka Paalanen
parent 53493aaddc
commit 45ae99aff7
4 changed files with 66 additions and 0 deletions

View File

@ -2576,6 +2576,14 @@ drm_head_log_info(struct drm_head *head, const char *msg)
str);
}
free(str);
str = weston_colorimetry_mask_to_str(head->base.supported_colorimetry_mask);
if (str) {
weston_log_continue(STAMP_SPACE
"Supported colorimetry modes: %s\n",
str);
}
free(str);
} else {
weston_log("DRM: head '%s' %s, connector %d is disconnected.\n",
head->base.name, msg, head->connector.connector_id);

View File

@ -49,6 +49,11 @@ struct drm_head_info {
* enum weston_eotf_mode bits.
*/
uint32_t eotf_mask;
/* The monitor supported colorimetry modes, combination of
* enum weston_colorimetry_mode bits.
*/
uint32_t colorimetry_mask;
};
static void
@ -251,6 +256,7 @@ drm_head_info_from_edid(struct drm_head_info *dhi,
/* TODO: parse this from EDID */
dhi->eotf_mask = WESTON_EOTF_MODE_ALL_MASK;
dhi->colorimetry_mask = WESTON_COLORIMETRY_MODE_ALL_MASK;
}
#else /* HAVE_LIBDISPLAY_INFO */
@ -380,6 +386,7 @@ drm_head_info_from_edid(struct drm_head_info *dhi,
/* This ad hoc code will never parse HDR data. */
dhi->eotf_mask = WESTON_EOTF_MODE_SDR;
dhi->colorimetry_mask = WESTON_COLORIMETRY_MODE_DEFAULT;
}
#endif /* HAVE_LIBDISPLAY_INFO else */
@ -447,6 +454,35 @@ prune_eotf_modes_by_kms_support(struct drm_head *head, uint32_t *eotf_mask)
*eotf_mask = WESTON_EOTF_MODE_SDR;
}
static uint32_t
drm_head_get_kms_colorimetry_modes(const struct drm_head *head)
{
const struct drm_property_info *info;
/* Cannot bother implementing without atomic */
if (!head->connector.device->atomic_modeset)
return WESTON_COLORIMETRY_MODE_DEFAULT;
info = &head->connector.props[WDRM_CONNECTOR_COLORSPACE];
if (info->prop_id == 0)
return WESTON_COLORIMETRY_MODE_DEFAULT;
uint32_t colorimetry_modes = WESTON_COLORIMETRY_MODE_NONE;
unsigned i; /* actually enum wdrm_colorspace */
for (i = 0; i < WDRM_COLORSPACE__COUNT; i++) {
if (info->enum_values[i].valid) {
const struct weston_colorimetry_mode_info *cm;
cm = weston_colorimetry_mode_info_get_by_wdrm(i);
if (cm)
colorimetry_modes |= cm->mode;
}
}
return colorimetry_modes;
}
static uint32_t
drm_refresh_rate_mHz(const drmModeModeInfo *info)
{
@ -643,6 +679,9 @@ update_head_from_connector(struct drm_head *head)
prune_eotf_modes_by_kms_support(head, &dhi.eotf_mask);
weston_head_set_supported_eotf_mask(&head->base, dhi.eotf_mask);
dhi.colorimetry_mask &= drm_head_get_kms_colorimetry_modes(head);
weston_head_set_supported_colorimetry_mask(&head->base, dhi.colorimetry_mask);
drm_head_info_fini(&dhi);
}

View File

@ -477,6 +477,22 @@ weston_colorimetry_mode_info_get(enum weston_colorimetry_mode c)
return NULL;
}
/** Get information structure of colorimetry mode from KMS "Colorspace" enum
*
* \internal
*/
WL_EXPORT const struct weston_colorimetry_mode_info *
weston_colorimetry_mode_info_get_by_wdrm(enum wdrm_colorspace cs)
{
unsigned i;
for (i = 0; i < ARRAY_LENGTH(colorimetry_mode_info_map); i++)
if (colorimetry_mode_info_map[i].wdrm == cs)
return &colorimetry_mode_info_map[i];
return NULL;
}
/** Get a string naming the colorimetry mode
*
* \internal

View File

@ -564,6 +564,9 @@ struct weston_colorimetry_mode_info {
const struct weston_colorimetry_mode_info *
weston_colorimetry_mode_info_get(enum weston_colorimetry_mode c);
const struct weston_colorimetry_mode_info *
weston_colorimetry_mode_info_get_by_wdrm(enum wdrm_colorspace cs);
const char *
weston_colorimetry_mode_to_str(enum weston_colorimetry_mode c);