diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 4485b3694..c8e44b0e6 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -77,6 +77,7 @@ enum wlr_output_state_field { WLR_OUTPUT_STATE_SIGNAL_TIMELINE = 1 << 11, WLR_OUTPUT_STATE_COLOR_TRANSFORM = 1 << 12, WLR_OUTPUT_STATE_IMAGE_DESCRIPTION = 1 << 13, + WLR_OUTPUT_STATE_COLOR_REPRESENTATION = 1 << 14, }; enum wlr_output_state_mode_type { @@ -142,6 +143,10 @@ struct wlr_output_state { * regular page-flip at the next wlr_output.frame event. */ bool tearing_page_flip; + // Set if (committed & WLR_OUTPUT_STATE_COLOR_REPRESENTATION) + enum wlr_color_encoding color_encoding; + enum wlr_color_range color_range; + enum wlr_output_state_mode_type mode_type; struct wlr_output_mode *mode; struct { @@ -205,6 +210,8 @@ struct wlr_output { enum wl_output_transform transform; enum wlr_output_adaptive_sync_status adaptive_sync_status; uint32_t render_format; + enum wlr_color_encoding color_encoding; + enum wlr_color_range color_range; const struct wlr_output_image_description *image_description; // Indicates whether making changes to adaptive sync status is supported. @@ -625,6 +632,15 @@ void wlr_output_state_set_color_transform(struct wlr_output_state *state, bool wlr_output_state_set_image_description(struct wlr_output_state *state, const struct wlr_output_image_description *image_desc); +/** + * Set the color encoding and range of the primary scanout buffer. + * + * Pass WLR_COLOR_ENCODING_NONE / WLR_COLOR_RANGE_NONE to reset to defaults. + */ +void wlr_output_state_set_color_encoding_and_range( + struct wlr_output_state *state, + enum wlr_color_encoding encoding, enum wlr_color_range range); + /** * Copies the output state from src to dst. It is safe to then * wlr_output_state_finish() src and have dst still be valid. diff --git a/types/output/output.c b/types/output/output.c index b1da61ed1..46da1f425 100644 --- a/types/output/output.c +++ b/types/output/output.c @@ -233,6 +233,11 @@ static void output_apply_state(struct wlr_output *output, output->transform = state->transform; } + if (state->committed & WLR_OUTPUT_STATE_COLOR_REPRESENTATION) { + output->color_encoding = state->color_encoding; + output->color_range = state->color_range; + } + if (state->committed & WLR_OUTPUT_STATE_IMAGE_DESCRIPTION) { if (state->image_description != NULL) { output->image_description_value = *state->image_description; @@ -580,6 +585,11 @@ static uint32_t output_compare_state(struct wlr_output *output, output->color_transform == state->color_transform) { fields |= WLR_OUTPUT_STATE_COLOR_TRANSFORM; } + if ((state->committed & WLR_OUTPUT_STATE_COLOR_REPRESENTATION) && + output->color_encoding == state->color_encoding && + output->color_range == state->color_range) { + fields |= WLR_OUTPUT_STATE_COLOR_REPRESENTATION; + } return fields; } @@ -632,6 +642,10 @@ static bool output_basic_test(struct wlr_output *output, wlr_log(WLR_DEBUG, "Tried to set signal timeline without a buffer"); return false; } + if (state->committed & WLR_OUTPUT_STATE_COLOR_REPRESENTATION) { + wlr_log(WLR_DEBUG, "Tried to set color representation without a buffer"); + return false; + } } if (state->committed & WLR_OUTPUT_STATE_RENDER_FORMAT) { diff --git a/types/output/state.c b/types/output/state.c index f2c655e21..5f44c18e8 100644 --- a/types/output/state.c +++ b/types/output/state.c @@ -141,6 +141,14 @@ bool wlr_output_state_set_image_description(struct wlr_output_state *state, return true; } +void wlr_output_state_set_color_encoding_and_range( + struct wlr_output_state *state, + enum wlr_color_encoding encoding, enum wlr_color_range range) { + state->committed |= WLR_OUTPUT_STATE_COLOR_REPRESENTATION; + state->color_encoding = encoding; + state->color_range = range; +} + bool wlr_output_state_copy(struct wlr_output_state *dst, const struct wlr_output_state *src) { struct wlr_output_state copy = *src;