From 45ae99aff79068d8b975b02c2426d78b19327cd4 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Tue, 5 Sep 2023 17:18:12 +0300 Subject: [PATCH] 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 --- libweston/backend-drm/drm.c | 8 +++++++ libweston/backend-drm/modes.c | 39 +++++++++++++++++++++++++++++++++++ libweston/color.c | 16 ++++++++++++++ libweston/color.h | 3 +++ 4 files changed, 66 insertions(+) diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index a5af37d9..f8be3734 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -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); diff --git a/libweston/backend-drm/modes.c b/libweston/backend-drm/modes.c index e77fbe6c..79513c8a 100644 --- a/libweston/backend-drm/modes.c +++ b/libweston/backend-drm/modes.c @@ -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); } diff --git a/libweston/color.c b/libweston/color.c index 9b9f60a3..4e33946d 100644 --- a/libweston/color.c +++ b/libweston/color.c @@ -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 diff --git a/libweston/color.h b/libweston/color.h index fff7bd32..8269b12d 100644 --- a/libweston/color.h +++ b/libweston/color.h @@ -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);