mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-06-14 13:38:21 +02:00
backend-drm: Add support for the DRM connector property 'color format'
This is the last part to support the 'color format' DRM connector. Signed-off-by: Derek Foreman <derek.foreman@collabora.com> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com> Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
This commit is contained in:
parent
67f8d9d6a6
commit
4615d2a779
8 changed files with 173 additions and 0 deletions
|
|
@ -705,6 +705,8 @@ struct drm_output {
|
|||
|
||||
bool reused_state;
|
||||
bool force_rebuild_state;
|
||||
|
||||
enum wdrm_color_format connector_color_format;
|
||||
};
|
||||
|
||||
void
|
||||
|
|
@ -938,6 +940,9 @@ drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output);
|
|||
enum wdrm_colorspace
|
||||
wdrm_colorspace_from_output(struct weston_output *output);
|
||||
|
||||
enum wdrm_color_format
|
||||
wdrm_color_format_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,
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ enum wdrm_connector_property {
|
|||
WDRM_CONNECTOR_RIGHT_MARGIN,
|
||||
WDRM_CONNECTOR_TOP_MARGIN,
|
||||
WDRM_CONNECTOR_BOTTOM_MARGIN,
|
||||
WDRM_CONNECTOR_COLOR_FORMAT,
|
||||
WDRM_CONNECTOR__COUNT
|
||||
};
|
||||
|
||||
|
|
@ -273,6 +274,15 @@ enum wdrm_underscan {
|
|||
WDRM_UNDERSCAN__COUNT
|
||||
};
|
||||
|
||||
enum wdrm_color_format {
|
||||
WDRM_COLOR_FORMAT_RGB,
|
||||
WDRM_COLOR_FORMAT_YUV422,
|
||||
WDRM_COLOR_FORMAT_YUV444,
|
||||
WDRM_COLOR_FORMAT_YUV420,
|
||||
WDRM_COLOR_FORMAT_AUTO,
|
||||
WDRM_COLOR_FORMAT__COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
* List of properties attached to DRM CRTCs
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2863,6 +2863,10 @@ drm_output_enable(struct weston_output *base)
|
|||
if (output->connector_colorspace == WDRM_COLORSPACE__COUNT)
|
||||
return -1;
|
||||
|
||||
output->connector_color_format = wdrm_color_format_from_output(&output->base);
|
||||
if (output->connector_color_format == WDRM_COLOR_FORMAT__COUNT)
|
||||
return -1;
|
||||
|
||||
ret = drm_output_attach_crtc(output);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
|
@ -3245,6 +3249,13 @@ drm_head_log_info(struct drm_head *head, const char *msg)
|
|||
head->base.underscan_vborder_max);
|
||||
}
|
||||
|
||||
str = weston_color_format_mask_to_str(head->base.supported_color_format_mask);
|
||||
if (str) {
|
||||
weston_log_continue(STAMP_SPACE
|
||||
"Supported color formats: %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);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <shared/weston-assert.h>
|
||||
|
||||
#include "drm-internal.h"
|
||||
|
||||
|
|
@ -193,3 +194,30 @@ wdrm_colorspace_from_output(struct weston_output *output)
|
|||
|
||||
return cm->wdrm;
|
||||
}
|
||||
|
||||
enum wdrm_color_format
|
||||
wdrm_color_format_from_output(struct weston_output *output)
|
||||
{
|
||||
enum weston_color_format color_format = output->color_format;
|
||||
|
||||
if (!color_format)
|
||||
return WDRM_COLOR_FORMAT_AUTO;
|
||||
|
||||
weston_assert_true(output->compositor,
|
||||
weston_output_get_supported_color_formats(output) & color_format);
|
||||
|
||||
switch (color_format) {
|
||||
case WESTON_COLOR_FORMAT_AUTO:
|
||||
return WDRM_COLOR_FORMAT_AUTO;
|
||||
case WESTON_COLOR_FORMAT_RGB:
|
||||
return WDRM_COLOR_FORMAT_RGB;
|
||||
case WESTON_COLOR_FORMAT_YUV444:
|
||||
return WDRM_COLOR_FORMAT_YUV444;
|
||||
case WESTON_COLOR_FORMAT_YUV422:
|
||||
return WDRM_COLOR_FORMAT_YUV422;
|
||||
case WESTON_COLOR_FORMAT_YUV420:
|
||||
return WDRM_COLOR_FORMAT_YUV420;
|
||||
default:
|
||||
return WDRM_COLOR_FORMAT__COUNT;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,6 +283,14 @@ struct drm_property_enum_info underscan_enums[] = {
|
|||
[WDRM_UNDERSCAN_AUTO] = { .name = "auto", },
|
||||
};
|
||||
|
||||
struct drm_property_enum_info color_format_enums[] = {
|
||||
[WDRM_COLOR_FORMAT_AUTO] = { .name = "AUTO", },
|
||||
[WDRM_COLOR_FORMAT_RGB] = { .name = "RGB", },
|
||||
[WDRM_COLOR_FORMAT_YUV422] = { .name = "YUV 4:2:2", },
|
||||
[WDRM_COLOR_FORMAT_YUV444] = { .name = "YUV 4:4:4", },
|
||||
[WDRM_COLOR_FORMAT_YUV420] = { .name = "YUV 4:2:0", },
|
||||
};
|
||||
|
||||
const struct drm_property_info connector_props[] = {
|
||||
[WDRM_CONNECTOR_EDID] = { .name = "EDID" },
|
||||
[WDRM_CONNECTOR_DPMS] = {
|
||||
|
|
@ -350,6 +358,11 @@ const struct drm_property_info connector_props[] = {
|
|||
[WDRM_CONNECTOR_BOTTOM_MARGIN] = {
|
||||
.name = "bottom margin",
|
||||
},
|
||||
[WDRM_CONNECTOR_COLOR_FORMAT] = {
|
||||
.name = "color format",
|
||||
.enum_values = color_format_enums,
|
||||
.num_enum_values = WDRM_COLOR_FORMAT__COUNT,
|
||||
},
|
||||
};
|
||||
|
||||
const struct drm_property_info crtc_props[] = {
|
||||
|
|
@ -1479,6 +1492,32 @@ drm_plane_set_color_encoding(struct drm_plane *plane,
|
|||
color_encoding);
|
||||
}
|
||||
|
||||
static int
|
||||
drm_connector_set_color_format(struct drm_connector *connector,
|
||||
enum wdrm_color_format color_format,
|
||||
drmModeAtomicReq *req)
|
||||
{
|
||||
const struct drm_property_info *info;
|
||||
const struct drm_property_enum_info *enum_info;
|
||||
|
||||
assert(color_format >= 0);
|
||||
assert(color_format < WDRM_COLOR_FORMAT__COUNT);
|
||||
|
||||
if (!drm_connector_has_prop(connector, WDRM_CONNECTOR_COLOR_FORMAT)) {
|
||||
if (color_format == WDRM_COLOR_FORMAT_AUTO)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
info = &connector->props[WDRM_CONNECTOR_COLOR_FORMAT];
|
||||
enum_info = &info->enum_values[color_format];
|
||||
assert(enum_info->valid);
|
||||
|
||||
return connector_add_prop(req, connector, WDRM_CONNECTOR_COLOR_FORMAT,
|
||||
enum_info->value);
|
||||
}
|
||||
|
||||
static int
|
||||
drm_plane_set_color_range(struct drm_plane *plane,
|
||||
enum wdrm_plane_color_range color_range,
|
||||
|
|
@ -1789,6 +1828,8 @@ drm_output_apply_state_atomic(struct drm_output_state *state,
|
|||
ret |= drm_connector_set_colorspace(&head->connector,
|
||||
output->connector_colorspace, req);
|
||||
ret |= drm_connector_set_underscan(&head->connector, output, req);
|
||||
ret |= drm_connector_set_color_format(&head->connector,
|
||||
output->connector_color_format, req);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
|
|
@ -2005,6 +2046,11 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
|
|||
wl_list_for_each(output_state, &pending_state->output_list, link) {
|
||||
if (output_state->output->is_virtual)
|
||||
continue;
|
||||
|
||||
if (output_state->output->connector_color_format !=
|
||||
wdrm_color_format_from_output(&output_state->output->base))
|
||||
weston_assert_true(b->compositor, output_state->output->base.enabled);
|
||||
|
||||
if (mode == DRM_STATE_APPLY_SYNC)
|
||||
assert(output_state->dpms == WESTON_DPMS_OFF);
|
||||
may_tear &= output_state->tear;
|
||||
|
|
|
|||
|
|
@ -553,6 +553,47 @@ drm_head_get_underscan_caps(const struct drm_head *head,
|
|||
*hborder_max_out = hborder_max;
|
||||
}
|
||||
|
||||
static enum weston_color_format
|
||||
color_format_from_wdrm_color_format(enum wdrm_color_format format)
|
||||
{
|
||||
switch (format) {
|
||||
case WDRM_COLOR_FORMAT_AUTO:
|
||||
return WESTON_COLOR_FORMAT_AUTO;
|
||||
case WDRM_COLOR_FORMAT_RGB:
|
||||
return WESTON_COLOR_FORMAT_RGB;
|
||||
case WDRM_COLOR_FORMAT_YUV444:
|
||||
return WESTON_COLOR_FORMAT_YUV444;
|
||||
case WDRM_COLOR_FORMAT_YUV422:
|
||||
return WESTON_COLOR_FORMAT_YUV422;
|
||||
case WDRM_COLOR_FORMAT_YUV420:
|
||||
return WESTON_COLOR_FORMAT_YUV420;
|
||||
default:
|
||||
return WESTON_COLOR_FORMAT_AUTO;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
drm_head_get_kms_color_formats(const struct drm_head *head)
|
||||
{
|
||||
const struct drm_property_info *info;
|
||||
uint32_t color_formats = WESTON_COLOR_FORMAT_AUTO;
|
||||
unsigned i;
|
||||
|
||||
/* Cannot bother implementing without atomic */
|
||||
if (!head->connector.device->atomic_modeset)
|
||||
return color_formats;
|
||||
|
||||
info = &head->connector.props[WDRM_CONNECTOR_COLOR_FORMAT];
|
||||
if (info->prop_id == 0)
|
||||
return color_formats;
|
||||
|
||||
for (i = 0; i < WDRM_COLOR_FORMAT__COUNT; i++)
|
||||
if (info->enum_values[i].valid)
|
||||
color_formats |= color_format_from_wdrm_color_format(i);
|
||||
|
||||
return color_formats;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
drm_refresh_rate_mHz(const drmModeModeInfo *info)
|
||||
{
|
||||
|
|
@ -789,6 +830,9 @@ update_head_from_connector(struct drm_head *head)
|
|||
drm_head_get_underscan_caps(head, &hborder_max, &vborder_max);
|
||||
weston_head_set_supported_underscan(&head->base, hborder_max, vborder_max);
|
||||
|
||||
dhi.color_format_mask &= drm_head_get_kms_color_formats(head);
|
||||
weston_head_set_supported_color_format_mask(&head->base, dhi.color_format_mask);
|
||||
|
||||
drm_head_info_fini(&dhi);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -190,6 +190,9 @@ weston_head_set_supported_vrr_modes_mask(struct weston_head *head,
|
|||
void
|
||||
weston_head_set_supported_underscan(struct weston_head *head,
|
||||
uint32_t hborder, uint32_t vborder);
|
||||
void
|
||||
weston_head_set_supported_color_format_mask(struct weston_head *head,
|
||||
uint32_t color_format_mask);
|
||||
/* weston_output */
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -7223,6 +7223,32 @@ weston_head_set_supported_colorimetry_mask(struct weston_head *head,
|
|||
weston_head_set_device_changed(head);
|
||||
}
|
||||
|
||||
/** Store the set of supported color formats
|
||||
*
|
||||
* \param head The head to modify.
|
||||
* \param color_format_mask A bit mask with the possible bits or'ed together
|
||||
* from enum weston_color_format.
|
||||
*
|
||||
* This may set the device_changed flag.
|
||||
*
|
||||
* \ingroup head
|
||||
* \internal
|
||||
*/
|
||||
WL_EXPORT void
|
||||
weston_head_set_supported_color_format_mask(struct weston_head *head,
|
||||
uint32_t color_format_mask)
|
||||
{
|
||||
weston_assert_legal_bits(head->compositor, color_format_mask,
|
||||
WESTON_COLOR_FORMAT_ALL_MASK);
|
||||
|
||||
if (head->supported_color_format_mask == color_format_mask)
|
||||
return;
|
||||
|
||||
head->supported_color_format_mask = color_format_mask;
|
||||
|
||||
weston_head_set_device_changed(head);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_head_set_supported_vrr_modes_mask(struct weston_head *head,
|
||||
uint32_t vrr_mode_mask)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue