mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2025-12-20 12:50:11 +01:00
DRM: Add support for HDMI content type
Some monitors expose a selector for the kind of content that will get displayed, allowing them to optimise their settings for this particular content type. I got access to such a monitor, sadly even setting it to game mode didn’t lower its atrocious latency, but drm_info[1] reports it to be set correctly so hopefully it’ll work better with other monitors. [1] https://github.com/ascent12/drm_info Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
This commit is contained in:
parent
2e39630214
commit
1c5ce4c2cc
6 changed files with 100 additions and 0 deletions
|
|
@ -2024,6 +2024,7 @@ drm_backend_output_configure(struct weston_output *output,
|
|||
char *s;
|
||||
char *modeline = NULL;
|
||||
char *gbm_format = NULL;
|
||||
char *content_type = NULL;
|
||||
char *seat = NULL;
|
||||
|
||||
api = weston_drm_output_get_api(output->compositor);
|
||||
|
|
@ -2080,6 +2081,12 @@ drm_backend_output_configure(struct weston_output *output,
|
|||
api->set_gbm_format(output, gbm_format);
|
||||
free(gbm_format);
|
||||
|
||||
weston_config_section_get_string(section,
|
||||
"content-type", &content_type, NULL);
|
||||
if (api->set_content_type(output, content_type) < 0)
|
||||
return -1;
|
||||
free(content_type);
|
||||
|
||||
weston_config_section_get_string(section, "seat", &seat, "");
|
||||
|
||||
api->set_seat(output, seat);
|
||||
|
|
|
|||
|
|
@ -93,6 +93,17 @@ struct weston_drm_output_api {
|
|||
* This can be set only while the output is disabled.
|
||||
*/
|
||||
void (*set_max_bpc)(struct weston_output *output, unsigned max_bpc);
|
||||
|
||||
/** The content type primarily used on the output. Valid values are:
|
||||
* - NULL or "no data" - No information is provided about the usage of the
|
||||
* output
|
||||
* - "graphics"
|
||||
* - "photo"
|
||||
* - "cinema"
|
||||
* - "game"
|
||||
*/
|
||||
int (*set_content_type)(struct weston_output *output,
|
||||
const char *content_type);
|
||||
};
|
||||
|
||||
static inline const struct weston_drm_output_api *
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ enum wdrm_connector_property {
|
|||
WDRM_CONNECTOR_PANEL_ORIENTATION,
|
||||
WDRM_CONNECTOR_HDR_OUTPUT_METADATA,
|
||||
WDRM_CONNECTOR_MAX_BPC,
|
||||
WDRM_CONNECTOR_CONTENT_TYPE,
|
||||
WDRM_CONNECTOR__COUNT
|
||||
};
|
||||
|
||||
|
|
@ -220,6 +221,15 @@ enum wdrm_panel_orientation {
|
|||
WDRM_PANEL_ORIENTATION__COUNT
|
||||
};
|
||||
|
||||
enum wdrm_content_type {
|
||||
WDRM_CONTENT_TYPE_NO_DATA = 0,
|
||||
WDRM_CONTENT_TYPE_GRAPHICS,
|
||||
WDRM_CONTENT_TYPE_PHOTO,
|
||||
WDRM_CONTENT_TYPE_CINEMA,
|
||||
WDRM_CONTENT_TYPE_GAME,
|
||||
WDRM_CONTENT_TYPE__COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
* List of properties attached to DRM CRTCs
|
||||
*/
|
||||
|
|
@ -587,6 +597,8 @@ struct drm_output {
|
|||
void (*virtual_destroy)(struct weston_output *base);
|
||||
|
||||
submit_frame_cb virtual_submit_frame;
|
||||
|
||||
enum wdrm_content_type content_type;
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1425,6 +1425,38 @@ drm_output_set_max_bpc(struct weston_output *base, unsigned max_bpc)
|
|||
output->max_bpc = max_bpc;
|
||||
}
|
||||
|
||||
static const struct { const char *name; uint32_t token; } content_types[] = {
|
||||
{ "no data", WDRM_CONTENT_TYPE_NO_DATA },
|
||||
{ "graphics", WDRM_CONTENT_TYPE_GRAPHICS },
|
||||
{ "photo", WDRM_CONTENT_TYPE_PHOTO },
|
||||
{ "cinema", WDRM_CONTENT_TYPE_CINEMA },
|
||||
{ "game", WDRM_CONTENT_TYPE_GAME },
|
||||
};
|
||||
|
||||
static int
|
||||
drm_output_set_content_type(struct weston_output *base,
|
||||
const char *content_type)
|
||||
{
|
||||
unsigned int i;
|
||||
struct drm_output *output = to_drm_output(base);
|
||||
|
||||
if (content_type == NULL) {
|
||||
output->content_type = WDRM_CONTENT_TYPE_NO_DATA;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(content_types); i++)
|
||||
if (strcmp(content_types[i].name, content_type) == 0) {
|
||||
output->content_type = content_types[i].token;
|
||||
return 0;
|
||||
}
|
||||
|
||||
weston_log("Error: unknown content-type for output %s: \"%s\"\n",
|
||||
base->name, content_type);
|
||||
output->content_type = WDRM_CONTENT_TYPE_NO_DATA;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
drm_output_init_gamma_size(struct drm_output *output)
|
||||
{
|
||||
|
|
@ -3084,6 +3116,7 @@ static const struct weston_drm_output_api api = {
|
|||
drm_output_set_gbm_format,
|
||||
drm_output_set_seat,
|
||||
drm_output_set_max_bpc,
|
||||
drm_output_set_content_type,
|
||||
};
|
||||
|
||||
static struct drm_backend *
|
||||
|
|
|
|||
|
|
@ -119,6 +119,14 @@ struct drm_property_enum_info panel_orientation_enums[] = {
|
|||
[WDRM_PANEL_ORIENTATION_RIGHT_SIDE_UP] = { .name = "Right Side Up", },
|
||||
};
|
||||
|
||||
struct drm_property_enum_info content_type_enums[] = {
|
||||
[WDRM_CONTENT_TYPE_NO_DATA] = { .name = "No Data", },
|
||||
[WDRM_CONTENT_TYPE_GRAPHICS] = { .name = "Graphics", },
|
||||
[WDRM_CONTENT_TYPE_PHOTO] = { .name = "Photo", },
|
||||
[WDRM_CONTENT_TYPE_CINEMA] = { .name = "Cinema", },
|
||||
[WDRM_CONTENT_TYPE_GAME] = { .name = "Game", },
|
||||
};
|
||||
|
||||
const struct drm_property_info connector_props[] = {
|
||||
[WDRM_CONNECTOR_EDID] = { .name = "EDID" },
|
||||
[WDRM_CONNECTOR_DPMS] = {
|
||||
|
|
@ -147,6 +155,11 @@ const struct drm_property_info connector_props[] = {
|
|||
.name = "HDR_OUTPUT_METADATA",
|
||||
},
|
||||
[WDRM_CONNECTOR_MAX_BPC] = { .name = "max bpc", },
|
||||
[WDRM_CONNECTOR_CONTENT_TYPE] = {
|
||||
.name = "content type",
|
||||
.enum_values = content_type_enums,
|
||||
.num_enum_values = WDRM_CONTENT_TYPE__COUNT,
|
||||
},
|
||||
};
|
||||
|
||||
const struct drm_property_info crtc_props[] = {
|
||||
|
|
@ -939,6 +952,24 @@ drm_connector_set_max_bpc(struct drm_connector *connector,
|
|||
WDRM_CONNECTOR_MAX_BPC, max_bpc);
|
||||
}
|
||||
|
||||
static int
|
||||
drm_connector_set_content_type(struct drm_connector *connector,
|
||||
enum wdrm_content_type content_type,
|
||||
drmModeAtomicReq *req)
|
||||
{
|
||||
struct drm_property_enum_info *enum_info;
|
||||
uint64_t prop_val;
|
||||
struct drm_property_info *props = connector->props;
|
||||
|
||||
if (!drm_connector_has_prop(connector, WDRM_CONNECTOR_CONTENT_TYPE))
|
||||
return 0;
|
||||
|
||||
enum_info = props[WDRM_CONNECTOR_CONTENT_TYPE].enum_values;
|
||||
prop_val = enum_info[content_type].value;
|
||||
return connector_add_prop(req, connector,
|
||||
WDRM_CONNECTOR_CONTENT_TYPE, prop_val);
|
||||
}
|
||||
|
||||
static int
|
||||
drm_output_apply_state_atomic(struct drm_output_state *state,
|
||||
drmModeAtomicReq *req,
|
||||
|
|
@ -992,6 +1023,8 @@ drm_output_apply_state_atomic(struct drm_output_state *state,
|
|||
wl_list_for_each(head, &output->base.head_list, base.output_link) {
|
||||
drm_connector_set_hdcp_property(&head->connector,
|
||||
state->protection, req);
|
||||
ret |= drm_connector_set_content_type(&head->connector,
|
||||
output->content_type, req);
|
||||
|
||||
if (drm_connector_has_prop(&head->connector,
|
||||
WDRM_CONNECTOR_HDR_OUTPUT_METADATA)) {
|
||||
|
|
|
|||
|
|
@ -543,6 +543,10 @@ content-protection can actually be realized, only if the hardware
|
|||
(source and sink) support HDCP, and the backend has the implementation
|
||||
of content-protection protocol. Currently, HDCP is supported by drm-backend.
|
||||
.TP 7
|
||||
.BI "content-type=" content_type
|
||||
The type of the content being primarily displayed to this output. Can be "no
|
||||
data" (default), "graphics", "photo", "cinema" or "game".
|
||||
.TP 7
|
||||
.BI "app-ids=" app-id[,app_id]*
|
||||
A comma separated list of the IDs of applications to place on this output.
|
||||
These IDs should match the application IDs as set with the xdg_shell.set_app_id
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue