From 4b7c52657806df8e8b7fb556bf6489d7f5ace1e0 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Fri, 16 Jun 2023 10:15:51 -0400 Subject: [PATCH] output: Introduce wlr_output_state_copy() --- include/wlr/types/wlr_output.h | 14 ++++++++++++- types/output/state.c | 36 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 5ed29208..ad034982 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -690,12 +690,24 @@ void wlr_output_state_set_damage(struct wlr_output_state *state, * advantage of backend features that may reduce the amount of things that * need to be composited. * - * The array must be kept valid by the caller until wlr_output_state_finish(). + * The array must be kept valid by the caller until wlr_output_state_finish() + * and all copies of the state have been finished as well. * This state will be applied once wlr_output_commit_state() is called. */ void wlr_output_state_set_layers(struct wlr_output_state *state, struct wlr_output_layer_state *layers, size_t layers_len); +/** + * Copies the output state from src to dst. It is safe to then + * wlr_output_state_finish() src and have dst still be valid. + * + * Note: The lifetime of the output layers inside the state are not managed. It + * is the responsibility of the constructor of the output layers to make sure + * they remain valid for the output state and all copies made. + */ +bool wlr_output_state_copy(struct wlr_output_state *dst, + const struct wlr_output_state *src); + /** * Re-configure the swapchain as required for the output's primary buffer. diff --git a/types/output/state.c b/types/output/state.c index 4633966c..7775fbb7 100644 --- a/types/output/state.c +++ b/types/output/state.c @@ -129,3 +129,39 @@ void wlr_output_state_set_layers(struct wlr_output_state *state, state->layers = layers; state->layers_len = layers_len; } + +bool wlr_output_state_copy(struct wlr_output_state *dst, + const struct wlr_output_state *src) { + struct wlr_output_state copy = *src; + copy.committed &= ~(WLR_OUTPUT_STATE_BUFFER | + WLR_OUTPUT_STATE_DAMAGE | + WLR_OUTPUT_STATE_GAMMA_LUT); + + if (src->committed & WLR_OUTPUT_STATE_BUFFER) { + wlr_output_state_set_buffer(©, src->buffer); + } + + if (src->committed & WLR_OUTPUT_STATE_DAMAGE) { + wlr_output_state_set_damage(©, &src->damage); + } + + if (src->committed & WLR_OUTPUT_STATE_GAMMA_LUT) { + size_t gamma_buffer_size = 3 * src->gamma_lut_size * sizeof(uint16_t); + copy.gamma_lut = malloc(gamma_buffer_size); + if (!copy.gamma_lut) { + wlr_log_errno(WLR_ERROR, "Allocation failed"); + goto err; + } + + copy.committed |= WLR_OUTPUT_STATE_GAMMA_LUT; + memcpy(copy.gamma_lut, src->gamma_lut, gamma_buffer_size); + copy.gamma_lut_size = src->gamma_lut_size; + } + + wlr_output_state_finish(dst); + *dst = copy; + return true; +err: + wlr_output_state_finish(©); + return false; +}