From 7e34909a67757e0e660fa3ab2f4d3897470f6b1d Mon Sep 17 00:00:00 2001 From: Steve Williams Date: Sat, 31 Jan 2026 15:10:49 +0400 Subject: [PATCH] color_representation: ensure encoding/range/drm formats compatibility --- types/wlr_color_representation_v1.c | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/types/wlr_color_representation_v1.c b/types/wlr_color_representation_v1.c index ff9b6e3b7..55ad98e6c 100644 --- a/types/wlr_color_representation_v1.c +++ b/types/wlr_color_representation_v1.c @@ -2,12 +2,14 @@ #include #include +#include #include #include #include #include #include "color-representation-v1-protocol.h" +#include "render/pixel_format.h" #include "util/mem.h" #define WP_COLOR_REPRESENTATION_VERSION 1 @@ -234,8 +236,35 @@ static void color_repr_manager_handle_destroy(struct wl_client *client, wl_resource_destroy(resource); } +static void surface_synced_commit(struct wlr_surface_synced *synced) { + struct wlr_color_representation_v1 *color_repr = wl_container_of(synced, color_repr, synced); + + struct wlr_dmabuf_attributes dmabuf; + + if (!color_repr->surface->buffer || + !wlr_buffer_get_dmabuf(&color_repr->surface->buffer->base, &dmabuf)) { + return; + } + + bool is_unset = color_repr->current.coefficients == 0 && color_repr->current.range == 0; + bool is_ycbcr = pixel_format_is_ycbcr(dmabuf.format); + if (is_ycbcr) { + if (is_unset) { + color_repr->current.coefficients = WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT601; + color_repr->current.range = WP_COLOR_REPRESENTATION_SURFACE_V1_RANGE_LIMITED; + } + } else /* rgb */ { + if (!is_unset) { + wl_resource_post_error(color_repr->resource, + WP_COLOR_REPRESENTATION_SURFACE_V1_ERROR_PIXEL_FORMAT, + "unexpected encoding/range for rgb"); + } + } +} + static const struct wlr_surface_synced_impl surface_synced_impl = { .state_size = sizeof(struct wlr_color_representation_v1_surface_state), + .commit = surface_synced_commit }; static struct wlr_color_representation_v1 *color_repr_from_surface( @@ -280,6 +309,7 @@ static void color_repr_manager_handle_get_surface(struct wl_client *client, } color_repr->manager = manager_from_resource(manager_resource); + color_repr->surface = surface; if (!wlr_surface_synced_init(&color_repr->synced, surface, &surface_synced_impl, &color_repr->pending, &color_repr->current)) {