output: add pre-blending color transform

This commit is contained in:
Simon Ser 2026-06-04 16:00:12 +02:00
parent 03712270ef
commit 97b945beee
3 changed files with 42 additions and 0 deletions

View file

@ -78,6 +78,7 @@ enum wlr_output_state_field {
WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM = 1 << 12, WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM = 1 << 12,
WLR_OUTPUT_STATE_IMAGE_DESCRIPTION = 1 << 13, WLR_OUTPUT_STATE_IMAGE_DESCRIPTION = 1 << 13,
WLR_OUTPUT_STATE_COLOR_REPRESENTATION = 1 << 14, WLR_OUTPUT_STATE_COLOR_REPRESENTATION = 1 << 14,
WLR_OUTPUT_STATE_PRE_COLOR_TRANSFORM = 1 << 15,
}; };
enum wlr_output_state_mode_type { enum wlr_output_state_mode_type {
@ -162,6 +163,8 @@ struct wlr_output_state {
struct wlr_drm_syncobj_timeline *signal_timeline; struct wlr_drm_syncobj_timeline *signal_timeline;
uint64_t signal_point; uint64_t signal_point;
// Pre-blending color transform
struct wlr_color_transform *pre_color_transform;
// Post-blending color transform // Post-blending color transform
struct wlr_color_transform *post_color_transform; struct wlr_color_transform *post_color_transform;
@ -277,6 +280,7 @@ struct wlr_output {
struct { struct {
struct wl_listener display_destroy; struct wl_listener display_destroy;
struct wlr_output_image_description image_description_value; struct wlr_output_image_description image_description_value;
struct wlr_color_transform *pre_color_transform;
struct wlr_color_transform *post_color_transform; struct wlr_color_transform *post_color_transform;
struct wlr_color_primaries default_primaries_value; struct wlr_color_primaries default_primaries_value;
} WLR_PRIVATE; } WLR_PRIVATE;
@ -619,6 +623,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, void wlr_output_state_set_signal_timeline(struct wlr_output_state *state,
struct wlr_drm_syncobj_timeline *timeline, uint64_t dst_point); struct wlr_drm_syncobj_timeline *timeline, uint64_t dst_point);
/**
* Set the pre-blending color transform for an output.
*
* The color transform is applied before blending output layers.
*/
void wlr_output_state_set_pre_color_transform(struct wlr_output_state *state,
struct wlr_color_transform *tr);
/** /**
* Set the post-blending color transform for an output. * Set the post-blending color transform for an output.
* *

View file

@ -252,6 +252,15 @@ static void output_apply_state(struct wlr_output *output,
} }
} }
if (state->committed & WLR_OUTPUT_STATE_PRE_COLOR_TRANSFORM) {
wlr_color_transform_unref(output->pre_color_transform);
if (state->pre_color_transform != NULL) {
output->pre_color_transform = wlr_color_transform_ref(state->pre_color_transform);
} else {
output->pre_color_transform = NULL;
}
}
if (state->committed & WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM) { if (state->committed & WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM) {
wlr_color_transform_unref(output->post_color_transform); wlr_color_transform_unref(output->post_color_transform);
if (state->post_color_transform != NULL) { if (state->post_color_transform != NULL) {
@ -426,6 +435,7 @@ void wlr_output_finish(struct wlr_output *output) {
wlr_swapchain_destroy(output->cursor_swapchain); wlr_swapchain_destroy(output->cursor_swapchain);
wlr_buffer_unlock(output->cursor_front_buffer); wlr_buffer_unlock(output->cursor_front_buffer);
wlr_color_transform_unref(output->pre_color_transform);
wlr_color_transform_unref(output->post_color_transform); wlr_color_transform_unref(output->post_color_transform);
wlr_swapchain_destroy(output->swapchain); wlr_swapchain_destroy(output->swapchain);
@ -581,6 +591,10 @@ static uint32_t output_compare_state(struct wlr_output *output,
output->subpixel == state->subpixel) { output->subpixel == state->subpixel) {
fields |= WLR_OUTPUT_STATE_SUBPIXEL; fields |= WLR_OUTPUT_STATE_SUBPIXEL;
} }
if ((state->committed & WLR_OUTPUT_STATE_PRE_COLOR_TRANSFORM) &&
output->pre_color_transform == state->pre_color_transform) {
fields |= WLR_OUTPUT_STATE_PRE_COLOR_TRANSFORM;
}
if ((state->committed & WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM) && if ((state->committed & WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM) &&
output->post_color_transform == state->post_color_transform) { output->post_color_transform == state->post_color_transform) {
fields |= WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM; fields |= WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM;
@ -685,6 +699,7 @@ static bool output_basic_test(struct wlr_output *output,
{ WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED, "adaptive sync" }, { WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED, "adaptive sync" },
{ WLR_OUTPUT_STATE_RENDER_FORMAT, "render format" }, { WLR_OUTPUT_STATE_RENDER_FORMAT, "render format" },
{ WLR_OUTPUT_STATE_SUBPIXEL, "subpixel" }, { WLR_OUTPUT_STATE_SUBPIXEL, "subpixel" },
{ WLR_OUTPUT_STATE_PRE_COLOR_TRANSFORM, "pre color transform" },
{ WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM, "post color transform" }, { WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM, "post color transform" },
{ WLR_OUTPUT_STATE_IMAGE_DESCRIPTION, "image description" }, { WLR_OUTPUT_STATE_IMAGE_DESCRIPTION, "image description" },
}; };

View file

@ -19,6 +19,7 @@ void wlr_output_state_finish(struct wlr_output_state *state) {
pixman_region32_fini(&state->damage); pixman_region32_fini(&state->damage);
wlr_drm_syncobj_timeline_unref(state->wait_timeline); wlr_drm_syncobj_timeline_unref(state->wait_timeline);
wlr_drm_syncobj_timeline_unref(state->signal_timeline); wlr_drm_syncobj_timeline_unref(state->signal_timeline);
wlr_color_transform_unref(state->pre_color_transform);
wlr_color_transform_unref(state->post_color_transform); wlr_color_transform_unref(state->post_color_transform);
free(state->image_description); free(state->image_description);
} }
@ -113,6 +114,17 @@ void wlr_output_state_set_signal_timeline(struct wlr_output_state *state,
state->signal_point = dst_point; state->signal_point = dst_point;
} }
void wlr_output_state_set_pre_color_transform(struct wlr_output_state *state,
struct wlr_color_transform *tr) {
state->committed |= WLR_OUTPUT_STATE_PRE_COLOR_TRANSFORM;
wlr_color_transform_unref(state->pre_color_transform);
if (tr) {
state->pre_color_transform = wlr_color_transform_ref(tr);
} else {
state->pre_color_transform = NULL;
}
}
void wlr_output_state_set_post_color_transform(struct wlr_output_state *state, void wlr_output_state_set_post_color_transform(struct wlr_output_state *state,
struct wlr_color_transform *tr) { struct wlr_color_transform *tr) {
state->committed |= WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM; state->committed |= WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM;
@ -164,6 +176,7 @@ bool wlr_output_state_copy(struct wlr_output_state *dst,
pixman_region32_init(&copy.damage); pixman_region32_init(&copy.damage);
copy.wait_timeline = NULL; copy.wait_timeline = NULL;
copy.signal_timeline = NULL; copy.signal_timeline = NULL;
copy.pre_color_transform = NULL;
copy.post_color_transform = NULL; copy.post_color_transform = NULL;
copy.image_description = NULL; copy.image_description = NULL;
@ -186,6 +199,9 @@ bool wlr_output_state_copy(struct wlr_output_state *dst,
src->signal_point); src->signal_point);
} }
if (src->committed & WLR_OUTPUT_STATE_PRE_COLOR_TRANSFORM) {
wlr_output_state_set_pre_color_transform(&copy, src->pre_color_transform);
}
if (src->committed & WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM) { if (src->committed & WLR_OUTPUT_STATE_POST_COLOR_TRANSFORM) {
wlr_output_state_set_post_color_transform(&copy, src->post_color_transform); wlr_output_state_set_post_color_transform(&copy, src->post_color_transform);
} }