From 97f6946c8d1603dc6faa8689bd7e63aa2cea4a36 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sat, 24 Aug 2024 11:14:54 +0200 Subject: [PATCH] output: add color transform to state Color transforms are better suited than raw gamma tables, because: - They don't need to get copied around: they are ref'counted. - They can represent more color operations (will be useful for the upcoming KMS color pipeline API, and for the Wayland color management protocol). --- include/wlr/types/wlr_output.h | 10 ++++++++++ types/output/output.c | 4 ++++ types/output/state.c | 20 +++++++++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 31b757062..6473ece4f 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -74,6 +74,7 @@ enum wlr_output_state_field { WLR_OUTPUT_STATE_LAYERS = 1 << 10, WLR_OUTPUT_STATE_WAIT_TIMELINE = 1 << 11, WLR_OUTPUT_STATE_SIGNAL_TIMELINE = 1 << 12, + WLR_OUTPUT_STATE_COLOR_TRANSFORM = 1 << 13, }; enum wlr_output_state_mode_type { @@ -132,6 +133,8 @@ struct wlr_output_state { uint64_t wait_point; struct wlr_drm_syncobj_timeline *signal_timeline; uint64_t signal_point; + + struct wlr_color_transform *color_transform; }; struct wlr_output_impl; @@ -586,6 +589,13 @@ void wlr_output_state_set_wait_timeline(struct wlr_output_state *state, */ void wlr_output_state_set_signal_timeline(struct wlr_output_state *state, struct wlr_drm_syncobj_timeline *timeline, uint64_t dst_point); +/** + * Set the color transform for an output. + * + * The color transform is applied after blending output layers. + */ +void wlr_output_state_set_color_transform(struct wlr_output_state *state, + struct wlr_color_transform *tr); /** * Copies the output state from src to dst. It is safe to then diff --git a/types/output/output.c b/types/output/output.c index 55f8a7645..9e63ec76e 100644 --- a/types/output/output.c +++ b/types/output/output.c @@ -651,6 +651,10 @@ static bool output_basic_test(struct wlr_output *output, wlr_log(WLR_DEBUG, "Tried to set the subpixel layout on a disabled output"); return false; } + if (!enabled && state->committed & WLR_OUTPUT_STATE_COLOR_TRANSFORM) { + wlr_log(WLR_DEBUG, "Tried to set a color transform on a disabled output"); + return false; + } if (state->committed & WLR_OUTPUT_STATE_LAYERS) { if (state->layers_len != (size_t)wl_list_length(&output->layers)) { diff --git a/types/output/state.c b/types/output/state.c index 72849c027..1a7b00508 100644 --- a/types/output/state.c +++ b/types/output/state.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "types/wlr_output.h" @@ -133,6 +134,17 @@ void wlr_output_state_set_signal_timeline(struct wlr_output_state *state, state->signal_point = dst_point; } +void wlr_output_state_set_color_transform(struct wlr_output_state *state, + struct wlr_color_transform *tr) { + state->committed |= WLR_OUTPUT_STATE_COLOR_TRANSFORM; + wlr_color_transform_unref(state->color_transform); + if (tr) { + state->color_transform = wlr_color_transform_ref(tr); + } else { + state->color_transform = NULL; + } +} + bool wlr_output_state_copy(struct wlr_output_state *dst, const struct wlr_output_state *src) { struct wlr_output_state copy = *src; @@ -140,7 +152,8 @@ bool wlr_output_state_copy(struct wlr_output_state *dst, WLR_OUTPUT_STATE_DAMAGE | WLR_OUTPUT_STATE_GAMMA_LUT | WLR_OUTPUT_STATE_WAIT_TIMELINE | - WLR_OUTPUT_STATE_SIGNAL_TIMELINE); + WLR_OUTPUT_STATE_SIGNAL_TIMELINE | + WLR_OUTPUT_STATE_COLOR_TRANSFORM); copy.buffer = NULL; copy.buffer_src_box = (struct wlr_fbox){0}; copy.buffer_dst_box = (struct wlr_box){0}; @@ -149,6 +162,7 @@ bool wlr_output_state_copy(struct wlr_output_state *dst, copy.gamma_lut_size = 0; copy.wait_timeline = NULL; copy.signal_timeline = NULL; + copy.color_transform = NULL; if (src->committed & WLR_OUTPUT_STATE_BUFFER) { wlr_output_state_set_buffer(©, src->buffer); @@ -178,6 +192,10 @@ bool wlr_output_state_copy(struct wlr_output_state *dst, src->signal_point); } + if (src->committed & WLR_OUTPUT_STATE_COLOR_TRANSFORM) { + wlr_output_state_set_color_transform(©, src->color_transform); + } + wlr_output_state_finish(dst); *dst = copy; return true;