mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-06-13 14:32:57 -04:00
Merge branch 'output_color_format' into 'master'
Draft: output: add color_format state field See merge request wlroots/wlroots!5364
This commit is contained in:
commit
66df6f3a4d
11 changed files with 135 additions and 7 deletions
|
|
@ -401,6 +401,7 @@ bool drm_atomic_connector_prepare(struct wlr_drm_connector_state *state, bool mo
|
|||
state->vrr_enabled = vrr_enabled;
|
||||
state->colorspace = colorspace;
|
||||
state->hdr_output_metadata = hdr_output_metadata;
|
||||
state->color_format = state->base->color_format;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -567,6 +568,10 @@ static void atomic_connector_add(struct atomic *atom,
|
|||
if (modeset && active && conn->props.max_bpc != 0 && conn->max_bpc_bounds[1] != 0) {
|
||||
atomic_add(atom, conn->id, conn->props.max_bpc, pick_max_bpc(conn, state->primary_fb));
|
||||
}
|
||||
if (modeset && conn->props.color_format != 0 &&
|
||||
state->base->committed & WLR_OUTPUT_STATE_COLOR_FORMAT) {
|
||||
atomic_add(atom, conn->id, conn->props.color_format, state->color_format);
|
||||
}
|
||||
if (conn->props.colorspace != 0) {
|
||||
atomic_add(atom, conn->id, conn->props.colorspace, state->colorspace);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ static const uint32_t COMMIT_OUTPUT_STATE =
|
|||
WLR_OUTPUT_STATE_SIGNAL_TIMELINE |
|
||||
WLR_OUTPUT_STATE_COLOR_TRANSFORM |
|
||||
WLR_OUTPUT_STATE_IMAGE_DESCRIPTION |
|
||||
WLR_OUTPUT_STATE_COLOR_REPRESENTATION;
|
||||
WLR_OUTPUT_STATE_COLOR_REPRESENTATION |
|
||||
WLR_OUTPUT_STATE_COLOR_FORMAT;
|
||||
|
||||
static const uint32_t SUPPORTED_OUTPUT_STATE =
|
||||
WLR_OUTPUT_STATE_BACKEND_OPTIONAL | COMMIT_OUTPUT_STATE;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ static const struct prop_info connector_info[] = {
|
|||
{ "EDID", INDEX(edid) },
|
||||
{ "HDR_OUTPUT_METADATA", INDEX(hdr_output_metadata) },
|
||||
{ "PATH", INDEX(path) },
|
||||
{ "color format", INDEX(color_format) },
|
||||
{ "content type", INDEX(content_type) },
|
||||
{ "link-status", INDEX(link_status) },
|
||||
{ "max bpc", INDEX(max_bpc) },
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ struct wlr_drm_connector_state {
|
|||
uint32_t fb_damage_clips;
|
||||
int primary_in_fence_fd;
|
||||
bool vrr_enabled;
|
||||
uint32_t color_format;
|
||||
uint32_t colorspace;
|
||||
uint32_t hdr_output_metadata;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ struct wlr_drm_connector_props {
|
|||
uint32_t panel_orientation; // not guaranteed to exist
|
||||
uint32_t content_type; // not guaranteed to exist
|
||||
uint32_t max_bpc; // not guaranteed to exist
|
||||
uint32_t color_format; // not guaranteed to exist
|
||||
|
||||
// atomic-modesetting only
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,21 @@ enum wlr_output_state_field {
|
|||
WLR_OUTPUT_STATE_COLOR_TRANSFORM = 1 << 12,
|
||||
WLR_OUTPUT_STATE_IMAGE_DESCRIPTION = 1 << 13,
|
||||
WLR_OUTPUT_STATE_COLOR_REPRESENTATION = 1 << 14,
|
||||
WLR_OUTPUT_STATE_COLOR_FORMAT = 1 << 15,
|
||||
};
|
||||
|
||||
/**
|
||||
* DRM color format for output connectors.
|
||||
*
|
||||
* These values match enum drm_connector_color_format in the kernel.
|
||||
* AUTO (0) is the default and lets the driver pick.
|
||||
*/
|
||||
enum wlr_output_color_format {
|
||||
WLR_OUTPUT_COLOR_FORMAT_AUTO = 0,
|
||||
WLR_OUTPUT_COLOR_FORMAT_RGB444,
|
||||
WLR_OUTPUT_COLOR_FORMAT_YCBCR444,
|
||||
WLR_OUTPUT_COLOR_FORMAT_YCBCR422,
|
||||
WLR_OUTPUT_COLOR_FORMAT_YCBCR420,
|
||||
};
|
||||
|
||||
enum wlr_output_state_mode_type {
|
||||
|
|
@ -165,6 +180,8 @@ struct wlr_output_state {
|
|||
struct wlr_color_transform *color_transform;
|
||||
|
||||
struct wlr_output_image_description *image_description;
|
||||
|
||||
uint32_t color_format; // enum wlr_output_color_format
|
||||
};
|
||||
|
||||
struct wlr_output_impl;
|
||||
|
|
@ -210,6 +227,7 @@ struct wlr_output {
|
|||
enum wl_output_transform transform;
|
||||
enum wlr_output_adaptive_sync_status adaptive_sync_status;
|
||||
uint32_t render_format;
|
||||
enum wlr_output_color_format color_format;
|
||||
enum wlr_color_encoding color_encoding;
|
||||
enum wlr_color_range color_range;
|
||||
const struct wlr_output_image_description *image_description;
|
||||
|
|
@ -641,6 +659,20 @@ void wlr_output_state_set_color_encoding_and_range(
|
|||
struct wlr_output_state *state,
|
||||
enum wlr_color_encoding encoding, enum wlr_color_range range);
|
||||
|
||||
/**
|
||||
* Sets the color format for an output. The color format determines the color
|
||||
* encoding sent to the display (RGB, YCbCr 4:4:4, YCbCr 4:2:2, YCbCr 4:2:0).
|
||||
*
|
||||
* The default value is WLR_OUTPUT_COLOR_FORMAT_AUTO.
|
||||
*
|
||||
* Not all connectors support all color formats. If the connector doesn't
|
||||
* support the "color format" DRM property, this setting is ignored.
|
||||
*
|
||||
* This state will be applied once wlr_output_commit_state() is called.
|
||||
*/
|
||||
void wlr_output_state_set_color_format(struct wlr_output_state *state,
|
||||
enum wlr_output_color_format color_format);
|
||||
|
||||
/**
|
||||
* Copies the output state from src to dst. It is safe to then
|
||||
* wlr_output_state_finish() src and have dst still be valid.
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ struct wlr_output_head_v1_state {
|
|||
enum wl_output_transform transform;
|
||||
float scale;
|
||||
bool adaptive_sync_enabled;
|
||||
enum wlr_output_color_format color_format;
|
||||
};
|
||||
|
||||
struct wlr_output_head_v1 {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
interface version number is reset.
|
||||
</description>
|
||||
|
||||
<interface name="zwlr_output_manager_v1" version="4">
|
||||
<interface name="zwlr_output_manager_v1" version="5">
|
||||
<description summary="output device configuration manager">
|
||||
This interface is a manager that allows reading and writing the current
|
||||
output device configuration.
|
||||
|
|
@ -125,7 +125,7 @@
|
|||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_output_head_v1" version="4">
|
||||
<interface name="zwlr_output_head_v1" version="5">
|
||||
<description summary="output device">
|
||||
A head is an output device. The difference between a wl_output object and
|
||||
a head is that heads are advertised even if they are turned off. A head
|
||||
|
|
@ -364,6 +364,28 @@
|
|||
</description>
|
||||
<arg name="state" type="uint" enum="adaptive_sync_state"/>
|
||||
</event>
|
||||
|
||||
<!-- Version 5 additions -->
|
||||
|
||||
<enum name="color_format" since="5">
|
||||
<description summary="color format for the output">
|
||||
These values correspond to the DRM connector color format property.
|
||||
The compositor may not support all formats on all connectors.
|
||||
</description>
|
||||
<entry name="auto" value="0" summary="compositor/driver picks"/>
|
||||
<entry name="rgb" value="1" summary="RGB output"/>
|
||||
<entry name="ycbcr444" value="2" summary="YCbCr 4:4:4"/>
|
||||
<entry name="ycbcr422" value="3" summary="YCbCr 4:2:2"/>
|
||||
<entry name="ycbcr420" value="4" summary="YCbCr 4:2:0"/>
|
||||
</enum>
|
||||
|
||||
<event name="color_format" since="5">
|
||||
<description summary="current color format">
|
||||
This event describes the color format currently used by the head.
|
||||
The color format determines the color encoding sent to the display.
|
||||
</description>
|
||||
<arg name="format" type="uint" enum="color_format"/>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_output_mode_v1" version="3">
|
||||
|
|
@ -421,7 +443,7 @@
|
|||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_output_configuration_v1" version="4">
|
||||
<interface name="zwlr_output_configuration_v1" version="5">
|
||||
<description summary="output configuration">
|
||||
This object is used by the client to describe a full output configuration.
|
||||
|
||||
|
|
@ -539,7 +561,7 @@
|
|||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_output_configuration_head_v1" version="4">
|
||||
<interface name="zwlr_output_configuration_head_v1" version="5">
|
||||
<description summary="head configuration">
|
||||
This object is used by the client to update a single head's configuration.
|
||||
|
||||
|
|
@ -554,6 +576,8 @@
|
|||
<entry name="invalid_scale" value="5" summary="scale negative or zero"/>
|
||||
<entry name="invalid_adaptive_sync_state" value="6" since="4"
|
||||
summary="invalid enum value used in the set_adaptive_sync request"/>
|
||||
<entry name="invalid_color_format" value="7" since="5"
|
||||
summary="invalid enum value used in the set_color_format request"/>
|
||||
</enum>
|
||||
|
||||
<request name="set_mode">
|
||||
|
|
@ -607,5 +631,19 @@
|
|||
</description>
|
||||
<arg name="state" type="uint" enum="zwlr_output_head_v1.adaptive_sync_state"/>
|
||||
</request>
|
||||
|
||||
<!-- Version 5 additions -->
|
||||
|
||||
<request name="set_color_format" since="5">
|
||||
<description summary="set the color format">
|
||||
This request sets the color format for the output. The color format
|
||||
determines the color encoding sent to the display (RGB, YCbCr 4:4:4,
|
||||
YCbCr 4:2:2, YCbCr 4:2:0).
|
||||
|
||||
If the connector does not support the color format property, the
|
||||
compositor should ignore this request.
|
||||
</description>
|
||||
<arg name="format" type="uint" enum="zwlr_output_head_v1.color_format"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
||||
|
|
|
|||
|
|
@ -216,6 +216,10 @@ static void output_apply_state(struct wlr_output *output,
|
|||
output->render_format = state->render_format;
|
||||
}
|
||||
|
||||
if (state->committed & WLR_OUTPUT_STATE_COLOR_FORMAT) {
|
||||
output->color_format = state->color_format;
|
||||
}
|
||||
|
||||
if (state->committed & WLR_OUTPUT_STATE_SUBPIXEL) {
|
||||
output->subpixel = state->subpixel;
|
||||
}
|
||||
|
|
@ -357,6 +361,7 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
|
|||
.impl = impl,
|
||||
.event_loop = event_loop,
|
||||
.render_format = DRM_FORMAT_XRGB8888,
|
||||
.color_format = WLR_OUTPUT_COLOR_FORMAT_AUTO,
|
||||
.transform = WL_OUTPUT_TRANSFORM_NORMAL,
|
||||
.scale = 1,
|
||||
.commit_seq = 0,
|
||||
|
|
@ -590,6 +595,10 @@ static uint32_t output_compare_state(struct wlr_output *output,
|
|||
output->color_range == state->color_range) {
|
||||
fields |= WLR_OUTPUT_STATE_COLOR_REPRESENTATION;
|
||||
}
|
||||
if ((state->committed & WLR_OUTPUT_STATE_COLOR_FORMAT) &&
|
||||
output->color_format == state->color_format) {
|
||||
fields |= WLR_OUTPUT_STATE_COLOR_FORMAT;
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,12 @@ void wlr_output_state_set_layers(struct wlr_output_state *state,
|
|||
state->layers_len = layers_len;
|
||||
}
|
||||
|
||||
void wlr_output_state_set_color_format(struct wlr_output_state *state,
|
||||
enum wlr_output_color_format color_format) {
|
||||
state->committed |= WLR_OUTPUT_STATE_COLOR_FORMAT;
|
||||
state->color_format = color_format;
|
||||
}
|
||||
|
||||
void wlr_output_state_set_wait_timeline(struct wlr_output_state *state,
|
||||
struct wlr_drm_syncobj_timeline *timeline, uint64_t src_point) {
|
||||
state->committed |= WLR_OUTPUT_STATE_WAIT_TIMELINE;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include <wlr/util/log.h>
|
||||
#include "wlr-output-management-unstable-v1-protocol.h"
|
||||
|
||||
#define OUTPUT_MANAGER_VERSION 4
|
||||
#define OUTPUT_MANAGER_VERSION 5
|
||||
|
||||
enum {
|
||||
HEAD_STATE_ENABLED = 1 << 0,
|
||||
|
|
@ -15,11 +15,12 @@ enum {
|
|||
HEAD_STATE_TRANSFORM = 1 << 3,
|
||||
HEAD_STATE_SCALE = 1 << 4,
|
||||
HEAD_STATE_ADAPTIVE_SYNC = 1 << 5,
|
||||
HEAD_STATE_COLOR_FORMAT = 1 << 6,
|
||||
};
|
||||
|
||||
static const uint32_t HEAD_STATE_ALL = HEAD_STATE_ENABLED | HEAD_STATE_MODE |
|
||||
HEAD_STATE_POSITION | HEAD_STATE_TRANSFORM | HEAD_STATE_SCALE |
|
||||
HEAD_STATE_ADAPTIVE_SYNC;
|
||||
HEAD_STATE_ADAPTIVE_SYNC | HEAD_STATE_COLOR_FORMAT;
|
||||
|
||||
static const struct zwlr_output_head_v1_interface head_impl;
|
||||
|
||||
|
|
@ -162,6 +163,7 @@ struct wlr_output_configuration_head_v1 *
|
|||
config_head->state.scale = output->scale;
|
||||
config_head->state.adaptive_sync_enabled =
|
||||
output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED;
|
||||
config_head->state.color_format = output->color_format;
|
||||
return config_head;
|
||||
}
|
||||
|
||||
|
|
@ -307,6 +309,24 @@ static void config_head_handle_set_adaptive_sync(struct wl_client *client,
|
|||
}
|
||||
}
|
||||
|
||||
static void config_head_handle_set_color_format(struct wl_client *client,
|
||||
struct wl_resource *config_head_resource, uint32_t format) {
|
||||
struct wlr_output_configuration_head_v1 *config_head =
|
||||
config_head_from_resource(config_head_resource);
|
||||
if (config_head == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (format > ZWLR_OUTPUT_HEAD_V1_COLOR_FORMAT_YCBCR420) {
|
||||
wl_resource_post_error(config_head_resource,
|
||||
ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_COLOR_FORMAT,
|
||||
"client requested invalid color format %u", format);
|
||||
return;
|
||||
}
|
||||
|
||||
config_head->state.color_format = format;
|
||||
}
|
||||
|
||||
static const struct zwlr_output_configuration_head_v1_interface config_head_impl = {
|
||||
.set_mode = config_head_handle_set_mode,
|
||||
.set_custom_mode = config_head_handle_set_custom_mode,
|
||||
|
|
@ -314,6 +334,7 @@ static const struct zwlr_output_configuration_head_v1_interface config_head_impl
|
|||
.set_transform = config_head_handle_set_transform,
|
||||
.set_scale = config_head_handle_set_scale,
|
||||
.set_adaptive_sync = config_head_handle_set_adaptive_sync,
|
||||
.set_color_format = config_head_handle_set_color_format,
|
||||
};
|
||||
|
||||
static void config_head_handle_resource_destroy(struct wl_resource *resource) {
|
||||
|
|
@ -815,6 +836,13 @@ static void head_send_state(struct wlr_output_head_v1 *head,
|
|||
ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
if ((state & HEAD_STATE_COLOR_FORMAT) &&
|
||||
wl_resource_get_version(head_resource) >=
|
||||
ZWLR_OUTPUT_HEAD_V1_COLOR_FORMAT_SINCE_VERSION) {
|
||||
zwlr_output_head_v1_send_color_format(head_resource,
|
||||
head->state.color_format);
|
||||
}
|
||||
}
|
||||
|
||||
static void head_handle_resource_destroy(struct wl_resource *resource) {
|
||||
|
|
@ -911,6 +939,9 @@ static bool manager_update_head(struct wlr_output_manager_v1 *manager,
|
|||
if (current->adaptive_sync_enabled != next->adaptive_sync_enabled) {
|
||||
state |= HEAD_STATE_ADAPTIVE_SYNC;
|
||||
}
|
||||
if (current->color_format != next->color_format) {
|
||||
state |= HEAD_STATE_COLOR_FORMAT;
|
||||
}
|
||||
|
||||
// If a mode was added to wlr_output.modes we need to add the new mode
|
||||
// to the wlr_output_head
|
||||
|
|
@ -1032,6 +1063,8 @@ void wlr_output_head_v1_state_apply(
|
|||
wlr_output_state_set_transform(output_state, head_state->transform);
|
||||
wlr_output_state_set_adaptive_sync_enabled(output_state,
|
||||
head_state->adaptive_sync_enabled);
|
||||
wlr_output_state_set_color_format(output_state,
|
||||
head_state->color_format);
|
||||
}
|
||||
|
||||
struct wlr_backend_output_state *wlr_output_configuration_v1_build_state(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue