mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-10-03 02:42:06 +00:00
backend-drm: set connector max bpc
"max bpc" property is meant for working around faulty sink hardware. Normally it should be set to the maximum possible value so that the kernel driver has full freedom to choose the link bpc without being artificially forced to lower color precision. The default value is 16 because that is a nice round number and more than any link technology I've heard is using today which would be 12. Also offer an API set the value, so that weston.ini could be used in the next patch for sink workaround purposes. Closes: https://gitlab.freedesktop.org/wayland/weston/-/issues/612 Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
parent
4d2ea5dd0b
commit
d24adbbe25
|
@ -78,6 +78,20 @@ struct weston_drm_output_api {
|
|||
*/
|
||||
void (*set_seat)(struct weston_output *output,
|
||||
const char *seat);
|
||||
|
||||
/** Set the "max bpc" KMS connector property
|
||||
*
|
||||
* The property is used for working around faulty sink hardware like
|
||||
* monitors or media converters that mishandle the kernel driver
|
||||
* chosen bits-per-channel on the physical link. When having trouble,
|
||||
* try a lower value like 8.
|
||||
*
|
||||
* The value actually used in KMS is silently clamped to the range the
|
||||
* KMS driver claims to support. The default value is 16.
|
||||
*
|
||||
* This can be set only while the output is disabled.
|
||||
*/
|
||||
void (*set_max_bpc)(struct weston_output *output, unsigned max_bpc);
|
||||
};
|
||||
|
||||
static inline const struct weston_drm_output_api *
|
||||
|
|
|
@ -187,6 +187,7 @@ enum wdrm_connector_property {
|
|||
WDRM_CONNECTOR_HDCP_CONTENT_TYPE,
|
||||
WDRM_CONNECTOR_PANEL_ORIENTATION,
|
||||
WDRM_CONNECTOR_HDR_OUTPUT_METADATA,
|
||||
WDRM_CONNECTOR_MAX_BPC,
|
||||
WDRM_CONNECTOR__COUNT
|
||||
};
|
||||
|
||||
|
@ -559,6 +560,8 @@ struct drm_output {
|
|||
uint32_t hdr_output_metadata_blob_id;
|
||||
uint64_t ackd_color_outcome_serial;
|
||||
|
||||
unsigned max_bpc;
|
||||
|
||||
/* Plane being displayed directly on the CRTC */
|
||||
struct drm_plane *scanout_plane;
|
||||
|
||||
|
|
|
@ -1389,6 +1389,17 @@ drm_output_set_seat(struct weston_output *base,
|
|||
seat ? seat : "");
|
||||
}
|
||||
|
||||
static void
|
||||
drm_output_set_max_bpc(struct weston_output *base, unsigned max_bpc)
|
||||
{
|
||||
struct drm_output *output = to_drm_output(base);
|
||||
|
||||
assert(output);
|
||||
assert(!output->base.enabled);
|
||||
|
||||
output->max_bpc = max_bpc;
|
||||
}
|
||||
|
||||
static int
|
||||
drm_output_init_gamma_size(struct drm_output *output)
|
||||
{
|
||||
|
@ -2278,6 +2289,7 @@ drm_output_create(struct weston_compositor *compositor, const char *name)
|
|||
output->device = device;
|
||||
output->crtc = NULL;
|
||||
|
||||
output->max_bpc = 16;
|
||||
output->gbm_format = DRM_FORMAT_INVALID;
|
||||
#ifdef BUILD_DRM_GBM
|
||||
output->gbm_bo_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
|
||||
|
@ -3055,6 +3067,7 @@ static const struct weston_drm_output_api api = {
|
|||
drm_output_set_mode,
|
||||
drm_output_set_gbm_format,
|
||||
drm_output_set_seat,
|
||||
drm_output_set_max_bpc,
|
||||
};
|
||||
|
||||
static struct drm_backend *
|
||||
|
|
|
@ -146,6 +146,7 @@ const struct drm_property_info connector_props[] = {
|
|||
[WDRM_CONNECTOR_HDR_OUTPUT_METADATA] = {
|
||||
.name = "HDR_OUTPUT_METADATA",
|
||||
},
|
||||
[WDRM_CONNECTOR_MAX_BPC] = { .name = "max bpc", },
|
||||
};
|
||||
|
||||
const struct drm_property_info crtc_props[] = {
|
||||
|
@ -905,6 +906,30 @@ drm_connector_set_hdcp_property(struct drm_connector *connector,
|
|||
assert(ret == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
drm_connector_set_max_bpc(struct drm_connector *connector,
|
||||
struct drm_output *output,
|
||||
drmModeAtomicReq *req)
|
||||
{
|
||||
const struct drm_property_info *info;
|
||||
uint64_t max_bpc;
|
||||
uint64_t a, b;
|
||||
|
||||
if (!drm_connector_has_prop(connector, WDRM_CONNECTOR_MAX_BPC))
|
||||
return 0;
|
||||
|
||||
info = &connector->props[WDRM_CONNECTOR_MAX_BPC];
|
||||
assert(info->flags & DRM_MODE_PROP_RANGE);
|
||||
assert(info->num_range_values == 2);
|
||||
a = info->range_values[0];
|
||||
b = info->range_values[1];
|
||||
assert(a <= b);
|
||||
|
||||
max_bpc = MAX(a, MIN(output->max_bpc, b));
|
||||
return connector_add_prop(req, connector,
|
||||
WDRM_CONNECTOR_MAX_BPC, max_bpc);
|
||||
}
|
||||
|
||||
static int
|
||||
drm_output_apply_state_atomic(struct drm_output_state *state,
|
||||
drmModeAtomicReq *req,
|
||||
|
@ -965,6 +990,8 @@ drm_output_apply_state_atomic(struct drm_output_state *state,
|
|||
WDRM_CONNECTOR_HDR_OUTPUT_METADATA,
|
||||
output->hdr_output_metadata_blob_id);
|
||||
}
|
||||
|
||||
ret |= drm_connector_set_max_bpc(&head->connector, output, req);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
|
|
Loading…
Reference in a new issue