From 2fbc0b5ac1d9877d024541eb4779a77e1f9102b1 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 28 Oct 2025 20:45:41 +0100 Subject: [PATCH] scene: add support for color encoding and range --- include/wlr/types/wlr_scene.h | 8 ++++++++ types/scene/wlr_scene.c | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h index 9658a02b4..83e5ad34a 100644 --- a/include/wlr/types/wlr_scene.h +++ b/include/wlr/types/wlr_scene.h @@ -197,6 +197,8 @@ struct wlr_scene_buffer { pixman_region32_t opaque_region; enum wlr_color_transfer_function transfer_function; enum wlr_color_named_primaries primaries; + enum wlr_color_encoding color_encoding; + enum wlr_color_range color_range; struct { uint64_t active_outputs; @@ -564,6 +566,12 @@ void wlr_scene_buffer_set_transfer_function(struct wlr_scene_buffer *scene_buffe void wlr_scene_buffer_set_primaries(struct wlr_scene_buffer *scene_buffer, enum wlr_color_named_primaries primaries); +void wlr_scene_buffer_set_color_encoding(struct wlr_scene_buffer *scene_buffer, + enum wlr_color_encoding encoding); + +void wlr_scene_buffer_set_color_range(struct wlr_scene_buffer *scene_buffer, + enum wlr_color_range range); + /** * Calls the buffer's frame_done signal. */ diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index c5cbcd29f..0c854c5b7 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -1121,6 +1121,26 @@ void wlr_scene_buffer_set_primaries(struct wlr_scene_buffer *scene_buffer, scene_node_update(&scene_buffer->node, NULL); } +void wlr_scene_buffer_set_color_encoding(struct wlr_scene_buffer *scene_buffer, + enum wlr_color_encoding color_encoding) { + if (scene_buffer->color_encoding == color_encoding) { + return; + } + + scene_buffer->color_encoding = color_encoding; + scene_node_update(&scene_buffer->node, NULL); +} + +void wlr_scene_buffer_set_color_range(struct wlr_scene_buffer *scene_buffer, + enum wlr_color_range color_range) { + if (scene_buffer->color_range == color_range) { + return; + } + + scene_buffer->color_range = color_range; + scene_node_update(&scene_buffer->node, NULL); +} + static struct wlr_texture *scene_buffer_get_texture( struct wlr_scene_buffer *scene_buffer, struct wlr_renderer *renderer) { if (scene_buffer->buffer == NULL || scene_buffer->texture != NULL) { @@ -1475,6 +1495,8 @@ static void scene_entry_render(struct render_list_entry *entry, const struct ren WLR_RENDER_BLEND_MODE_PREMULTIPLIED : WLR_RENDER_BLEND_MODE_NONE, .transfer_function = scene_buffer->transfer_function, .primaries = scene_buffer->primaries != 0 ? &primaries : NULL, + .color_encoding = scene_buffer->color_encoding, + .color_range = scene_buffer->color_range, .wait_timeline = scene_buffer->wait_timeline, .wait_point = scene_buffer->wait_point, }); @@ -2015,6 +2037,11 @@ static enum scene_direct_scanout_result scene_entry_try_direct_scanout( return SCANOUT_INELIGIBLE; } + if (buffer->color_encoding != WLR_COLOR_ENCODING_NONE || + buffer->color_range != WLR_COLOR_RANGE_NONE) { + return SCANOUT_INELIGIBLE; + } + // We want to ensure optimal buffer selection, but as direct-scanout can be enabled and disabled // on a frame-by-frame basis, we wait for a few frames to send the new format recommendations. // Maybe we should only send feedback in this case if tests fail.