summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Paalanen <pekka.paalanen@collabora.com>2023-09-05 17:18:12 +0300
committerPekka Paalanen <pq@iki.fi>2024-05-06 10:39:42 +0000
commit45ae99aff79068d8b975b02c2426d78b19327cd4 (patch)
treea7369125822997939faa074f597cd23ba2e59d65
parent53493aaddcad885cb35529555151ed2caeea76d5 (diff)
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>
-rw-r--r--libweston/backend-drm/drm.c8
-rw-r--r--libweston/backend-drm/modes.c39
-rw-r--r--libweston/color.c16
-rw-r--r--libweston/color.h3
4 files changed, 66 insertions, 0 deletions
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 */
@@ -448,6 +455,35 @@ prune_eotf_modes_by_kms_support(struct drm_head *head, uint32_t *eotf_mask)
}
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)
{
uint64_t refresh;
@@ -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);