Skip to content
Commits on Source (5)
......@@ -92,6 +92,7 @@ struct pixel_format_info;
struct weston_output_capture_info;
struct weston_output_color_outcome;
struct weston_tearing_control;
struct di_info;
enum weston_keyboard_modifier {
MODIFIER_CTRL = (1 << 0),
......@@ -505,6 +506,7 @@ struct weston_head {
bool non_desktop; /**< non-desktop display, e.g. HMD */
uint32_t supported_eotf_mask; /**< supported weston_eotf_mode bits */
uint32_t supported_colorimetry_mask; /**< supported weston_colorimetry_mode bits */
struct di_info *display_info; /**< libdisplay-info, from DRM */
/** Current content protection status */
enum weston_hdcp_protection current_protection;
......@@ -2626,6 +2628,9 @@ weston_head_get_output(struct weston_head *head);
uint32_t
weston_head_get_transform(struct weston_head *head);
const struct di_info *
weston_head_get_display_info(const struct weston_head *head);
void
weston_head_detach(struct weston_head *head);
......
......@@ -669,6 +669,9 @@ drm_crtc_find(struct drm_device *device, uint32_t crtc_id);
struct drm_head *
drm_head_find_by_connector(struct drm_backend *backend, struct drm_device *device, uint32_t connector_id);
void
drm_free_display_info(struct di_info **display_info);
uint64_t
drm_rotation_from_output_transform(struct drm_plane *plane,
enum wl_output_transform ot);
......
......@@ -2774,6 +2774,7 @@ drm_head_destroy(struct weston_head *base)
assert(head);
drm_free_display_info(&head->base.display_info);
weston_head_release(&head->base);
drm_connector_fini(&head->connector);
......
......@@ -12,6 +12,9 @@ dep_libdisplay_info = dependency(
required: true,
not_found_message: 'Required by DRM-backend.',
)
if dep_libdisplay_info.version().version_compare('>= 0.2.0')
config_h.set('HAVE_LIBDISPLAY_INFO_HIGH_LEVEL_COLORIMETRY', '1')
endif
lib_backlight = static_library(
'backlight',
......
/*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2011 Intel Corporation
* Copyright © 2017, 2018 Collabora, Ltd.
* Copyright © 2017, 2018, 2024 Collabora, Ltd.
* Copyright © 2017, 2018 General Electric Company
* Copyright (c) 2018 DisplayLink (UK) Ltd.
*
......@@ -227,7 +227,80 @@ parse_modeline(const char *s, drmModeModeInfo *mode)
return 0;
}
static void
#ifdef HAVE_LIBDISPLAY_INFO_HIGH_LEVEL_COLORIMETRY
static uint32_t
get_eotf_mask(const struct di_info *info)
{
const struct di_hdr_static_metadata *hdr_static;
uint32_t mask = 0;
hdr_static = di_info_get_hdr_static_metadata(info);
if (!hdr_static->type1)
return WESTON_EOTF_MODE_SDR;
if (hdr_static->traditional_sdr)
mask |= WESTON_EOTF_MODE_SDR;
if (hdr_static->traditional_hdr)
mask |= WESTON_EOTF_MODE_TRADITIONAL_HDR;
if (hdr_static->pq)
mask |= WESTON_EOTF_MODE_ST2084;
if (hdr_static->hlg)
mask |= WESTON_EOTF_MODE_HLG;
return mask;
}
static uint32_t
get_colorimetry_mask(const struct di_info *info)
{
const struct di_supported_signal_colorimetry *ssc;
uint32_t mask = WESTON_COLORIMETRY_MODE_DEFAULT;
ssc = di_info_get_supported_signal_colorimetry(info);
if (!ssc)
return mask;
if (ssc->bt2020_cycc)
mask |= WESTON_COLORIMETRY_MODE_BT2020_CYCC;
if (ssc->bt2020_rgb)
mask |= WESTON_COLORIMETRY_MODE_BT2020_RGB;
if (ssc->bt2020_ycc)
mask |= WESTON_COLORIMETRY_MODE_BT2020_YCC;
if (ssc->st2113_rgb) {
mask |= WESTON_COLORIMETRY_MODE_P3D65;
mask |= WESTON_COLORIMETRY_MODE_P3DCI;
}
if (ssc->ictcp)
mask |= WESTON_COLORIMETRY_MODE_ICTCP;
return mask;
}
#else /* HAVE_LIBDISPLAY_INFO_HIGH_LEVEL_COLORIMETRY */
static uint32_t
get_eotf_mask(const struct di_info *info)
{
return WESTON_EOTF_MODE_SDR;
}
static uint32_t
get_colorimetry_mask(const struct di_info *info)
{
return WESTON_COLORIMETRY_MODE_DEFAULT;
}
#endif /* HAVE_LIBDISPLAY_INFO_HIGH_LEVEL_COLORIMETRY */
static struct di_info *
drm_head_info_from_edid(struct drm_head_info *dhi,
const uint8_t *data,
size_t length)
......@@ -236,8 +309,12 @@ drm_head_info_from_edid(struct drm_head_info *dhi,
const char *msg;
di_ctx = di_info_parse_edid(data, length);
if (!di_ctx)
return;
if (!di_ctx) {
memset(dhi, 0, sizeof(*dhi));
dhi->eotf_mask = WESTON_EOTF_MODE_SDR;
dhi->colorimetry_mask = WESTON_COLORIMETRY_MODE_DEFAULT;
return NULL;
}
msg = di_info_get_failure_msg(di_ctx);
if (msg)
......@@ -246,12 +323,20 @@ drm_head_info_from_edid(struct drm_head_info *dhi,
dhi->make = di_info_get_make(di_ctx);
dhi->model = di_info_get_model(di_ctx);
dhi->serial_number = di_info_get_serial(di_ctx);
dhi->eotf_mask = get_eotf_mask(di_ctx);
dhi->colorimetry_mask = get_colorimetry_mask(di_ctx);
di_info_destroy(di_ctx);
return di_ctx;
}
void
drm_free_display_info(struct di_info **display_info)
{
if (!*display_info)
return;
/* TODO: parse this from EDID */
dhi->eotf_mask = WESTON_EOTF_MODE_ALL_MASK;
dhi->colorimetry_mask = WESTON_COLORIMETRY_MODE_ALL_MASK;
di_info_destroy(*display_info);
*display_info = NULL;
}
static void
......@@ -533,9 +618,12 @@ update_head_from_connector(struct drm_head *head)
if (!drm_head_maybe_update_display_data(head, props))
return;
struct drm_head_info dhi = { .eotf_mask = WESTON_EOTF_MODE_SDR };
struct drm_head_info dhi;
drm_head_info_from_edid(&dhi, head->display_data, head->display_data_len);
drm_free_display_info(&head->base.display_info);
head->base.display_info = drm_head_info_from_edid(&dhi, head->display_data,
head->display_data_len);
weston_head_set_device_changed(&head->base);
weston_head_set_monitor_strings(&head->base, dhi.make,
dhi.model,
......
......@@ -6715,6 +6715,8 @@ weston_head_release(struct weston_head *head)
free(head->name);
wl_list_remove(&head->compositor_link);
assert(head->display_info == NULL);
}
/** Propagate device information changes
......@@ -7142,6 +7144,24 @@ weston_head_get_transform(struct weston_head *head)
return head->transform;
}
/** Get display information (EDID, DisplayID)
*
* \param head The head to query.
* \return libdisplay-info structure, or NULL.
*
* Hardware heads (monitors, TVs, etc.) driven directly by this compositor may
* provide EDID or DisplayID information. If a backend has that information,
* it may expose it as a libdisplay-info structure. The caller needs to use
* libdisplay-info to extract information from the returned pointer.
*
* \ingroup head
*/
WL_EXPORT const struct di_info *
weston_head_get_display_info(const struct weston_head *head)
{
return head->display_info;
}
/** Add destroy callback for a head
*
* \param head The head to watch for.
......