diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h index 114d5c0f3..9f27b4373 100644 --- a/include/wlr/types/wlr_scene.h +++ b/include/wlr/types/wlr_scene.h @@ -192,6 +192,7 @@ struct wlr_scene_buffer { int dst_width, dst_height; enum wl_output_transform transform; pixman_region32_t opaque_region; + enum wlr_color_transfer_function transfer_function; struct { uint64_t active_outputs; @@ -541,6 +542,9 @@ void wlr_scene_buffer_set_opacity(struct wlr_scene_buffer *scene_buffer, void wlr_scene_buffer_set_filter_mode(struct wlr_scene_buffer *scene_buffer, enum wlr_scale_filter_mode filter_mode); +void wlr_scene_buffer_set_transfer_function(struct wlr_scene_buffer *scene_buffer, + enum wlr_color_transfer_function transfer_function); + /** * Calls the buffer's frame_done signal. */ diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index 1acbb5650..baa36bf3a 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -1099,6 +1099,16 @@ void wlr_scene_buffer_set_filter_mode(struct wlr_scene_buffer *scene_buffer, scene_node_update(&scene_buffer->node, NULL); } +void wlr_scene_buffer_set_transfer_function(struct wlr_scene_buffer *scene_buffer, + enum wlr_color_transfer_function transfer_function) { + if (scene_buffer->transfer_function == transfer_function) { + return; + } + + scene_buffer->transfer_function = transfer_function; + 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) { @@ -1446,6 +1456,7 @@ static void scene_entry_render(struct render_list_entry *entry, const struct ren .blend_mode = !data->output->scene->calculate_visibility || !pixman_region32_empty(&opaque) ? WLR_RENDER_BLEND_MODE_PREMULTIPLIED : WLR_RENDER_BLEND_MODE_NONE, + .transfer_function = scene_buffer->transfer_function, .wait_timeline = scene_buffer->wait_timeline, .wait_point = scene_buffer->wait_point, }); @@ -1936,6 +1947,9 @@ static enum scene_direct_scanout_result scene_entry_try_direct_scanout( if (buffer->transform != data->transform) { return SCANOUT_INELIGIBLE; } + if (buffer->transfer_function != 0 && buffer->transfer_function != WLR_COLOR_TRANSFER_FUNCTION_SRGB) { + return false; + } // 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.