wayland: add support for wp-color-representation-v1

This is yet another color-related protocol for wayland. It's pretty
simple compared to the color-management protocol, and there's no real
reason to not advertise the color representation to compositors that
might find it useful.
This commit is contained in:
Dudemanguy
2025-06-27 23:38:48 +00:00
parent 18defc8530
commit ed8954e8cf
6 changed files with 131 additions and 4 deletions
+5 -1
View File
@@ -13,7 +13,7 @@ protocols = [[wl_protocol_dir, 'stable/presentation-time/presentation-time.xml']
wl_protocols_source = []
wl_protocols_headers = []
foreach v: ['1.32', '1.38', '1.39', '1.41']
foreach v: ['1.32', '1.38', '1.39', '1.41', '1.44']
features += {'wayland-protocols-' + v.replace('.', '-'):
wayland['deps'][2].version().version_compare('>=' + v)}
endforeach
@@ -36,6 +36,10 @@ if features['wayland-protocols-1-41']
protocols += [[wl_protocol_dir, 'staging/color-management/color-management-v1.xml']]
endif
if features['wayland-protocols-1-44']
protocols += [[wl_protocol_dir, 'staging/color-representation/color-representation-v1.xml']]
endif
foreach p: protocols
xml = join_paths(p)
wl_protocols_source += custom_target(xml.underscorify() + '_c',
+2
View File
@@ -67,6 +67,8 @@ static void wayland_egl_swap_buffers(struct ra_ctx *ctx)
struct priv *p = ctx->priv;
struct vo_wayland_state *wl = ctx->vo->wl;
vo_wayland_handle_color(wl);
eglSwapBuffers(p->egl_display, p->egl_surface);
if (wl->opts->wl_internal_vsync)
+1
View File
@@ -261,6 +261,7 @@ static bool draw_frame(struct vo *vo, struct vo_frame *frame)
}
}
if (src) {
vo_wayland_handle_color(wl);
struct mp_image dst = buf->mpi;
struct mp_rect src_rc;
struct mp_rect dst_rc;
+2
View File
@@ -38,6 +38,8 @@ static void wayland_vk_swap_buffers(struct ra_ctx *ctx)
struct vo_wayland_state *wl = ctx->vo->wl;
struct priv *p = ctx->priv;
vo_wayland_handle_color(wl);
if ((!p->use_fifo && wl->opts->wl_internal_vsync == 1) || wl->opts->wl_internal_vsync == 2)
vo_wayland_wait_frame(wl);
+114 -3
View File
@@ -61,6 +61,10 @@
#include "color-management-v1.h"
#endif
#if HAVE_WAYLAND_PROTOCOLS_1_44
#include "color-representation-v1.h"
#endif
#if WAYLAND_VERSION_MAJOR > 1 || WAYLAND_VERSION_MINOR >= 22
#define HAVE_WAYLAND_1_22
#endif
@@ -1711,6 +1715,63 @@ static const struct wp_color_management_surface_feedback_v1_listener surface_fee
};
#endif
#if HAVE_WAYLAND_PROTOCOLS_1_44
static void supported_alpha_mode(void *data, struct wp_color_representation_manager_v1 *color_representation_manager,
uint32_t alpha_mode)
{
struct vo_wayland_state *wl = data;
switch (alpha_mode) {
case WP_COLOR_REPRESENTATION_SURFACE_V1_ALPHA_MODE_PREMULTIPLIED_ELECTRICAL:
#if PL_API_VER >= 344
wl->alpha_map[PL_ALPHA_NONE] = alpha_mode;
#endif
break;
case WP_COLOR_REPRESENTATION_SURFACE_V1_ALPHA_MODE_STRAIGHT:
wl->alpha_map[PL_ALPHA_INDEPENDENT] = alpha_mode;
break;
}
}
static void supported_coefficients_and_ranges(void *data, struct wp_color_representation_manager_v1 *color_representation_manager,
uint32_t coefficients, uint32_t range)
{
struct vo_wayland_state *wl = data;
int offset = range == WP_COLOR_REPRESENTATION_SURFACE_V1_RANGE_FULL ? 0 : PL_COLOR_SYSTEM_COUNT;
switch (coefficients) {
case WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT709:
wl->coefficients_map[PL_COLOR_SYSTEM_BT_709] = WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT709;
wl->range_map[PL_COLOR_SYSTEM_BT_709 + offset] = range;
break;
case WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT601:
wl->coefficients_map[PL_COLOR_SYSTEM_BT_601] = WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT601;
wl->range_map[PL_COLOR_SYSTEM_BT_601 + offset] = range;
break;
case WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_SMPTE240:
wl->coefficients_map[PL_COLOR_SYSTEM_SMPTE_240M] = WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_SMPTE240;
wl->range_map[PL_COLOR_SYSTEM_SMPTE_240M + offset] = range;
break;
case WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT2020:
wl->coefficients_map[PL_COLOR_SYSTEM_BT_2020_NC] = WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT2020;
wl->range_map[PL_COLOR_SYSTEM_BT_2020_NC + offset] = range;
break;
case WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT2020_CL:
wl->coefficients_map[PL_COLOR_SYSTEM_BT_2020_C] = WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT2020_CL;
wl->range_map[PL_COLOR_SYSTEM_BT_2020_C + offset] = range;
break;
}
}
static void color_representation_done(void *data, struct wp_color_representation_manager_v1 *color_representation_manager)
{
}
static const struct wp_color_representation_manager_v1_listener color_representation_listener = {
supported_alpha_mode,
supported_coefficients_and_ranges,
color_representation_done,
};
#endif
static const char *zxdg_decoration_mode_to_str(const uint32_t mode)
{
switch (mode) {
@@ -2058,6 +2119,14 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
wl->shm = wl_registry_bind(reg, id, &wl_shm_interface, ver);
}
#if HAVE_WAYLAND_PROTOCOLS_1_44
if (!strcmp(interface, wp_color_representation_manager_v1_interface.name) && found++) {
ver = 1;
wl->color_representation_manager = wl_registry_bind(reg, id, &wp_color_representation_manager_v1_interface, ver);
wp_color_representation_manager_v1_add_listener(wl->color_representation_manager, &color_representation_listener, wl);
}
#endif
if (!strcmp(interface, wp_content_type_manager_v1_interface.name) && found++) {
ver = 1;
wl->content_type_manager = wl_registry_bind(reg, id, &wp_content_type_manager_v1_interface, ver);
@@ -2694,11 +2763,9 @@ static void seat_create_text_input(struct vo_wayland_seat *seat)
static void set_color_management(struct vo_wayland_state *wl)
{
#if HAVE_WAYLAND_PROTOCOLS_1_41
struct mp_image_params target_params = vo_get_target_params(wl->vo);
if (!wl->color_surface || pl_color_space_equal(&target_params.color, &wl->target_params.color))
if (!wl->color_surface)
return;
wl->target_params = target_params;
wp_color_management_surface_v1_unset_image_description(wl->color_surface);
struct pl_color_space color = wl->target_params.color;
@@ -2743,6 +2810,29 @@ static void set_color_management(struct vo_wayland_state *wl)
#endif
}
static void set_color_representation(struct vo_wayland_state *wl)
{
#if HAVE_WAYLAND_PROTOCOLS_1_44
if (wl->color_representation_surface)
wp_color_representation_surface_v1_destroy(wl->color_representation_surface);
wl->color_representation_surface =
wp_color_representation_manager_v1_get_surface(wl->color_representation_manager, wl->callback_surface);
struct pl_color_repr repr = wl->target_params.repr;
int alpha = wl->alpha_map[repr.alpha];
int coefficients = wl->coefficients_map[repr.sys];
int range = repr.levels == PL_COLOR_LEVELS_FULL ? wl->range_map[repr.sys] :
wl->range_map[repr.sys + PL_COLOR_SYSTEM_COUNT];
if (coefficients && range)
wp_color_representation_surface_v1_set_coefficients_and_range(wl->color_representation_surface, coefficients, range);
if (alpha)
wp_color_representation_surface_v1_set_alpha_mode(wl->color_representation_surface, alpha);
#endif
}
static void set_content_type(struct vo_wayland_state *wl)
{
if (!wl->content_type_manager)
@@ -3326,7 +3416,13 @@ void vo_wayland_handle_color(struct vo_wayland_state *wl)
{
if (!wl->vo->target_params)
return;
struct mp_image_params target_params = vo_get_target_params(wl->vo);
if (pl_color_space_equal(&target_params.color, &wl->target_params.color) &&
pl_color_repr_equal(&target_params.repr, &wl->target_params.repr))
return;
wl->target_params = target_params;
set_color_management(wl);
set_color_representation(wl);
}
@@ -3442,6 +3538,13 @@ bool vo_wayland_init(struct vo *vo)
}
#endif
#if HAVE_WAYLAND_PROTOCOLS_1_44
if (!wl->color_representation_manager) {
MP_VERBOSE(wl, "Compositor doesn't support the %s protocol!\n",
wp_color_representation_surface_v1_interface.name);
}
#endif
if (wl->content_type_manager) {
wl->content_type = wp_content_type_manager_v1_get_surface_content_type(wl->content_type_manager, wl->surface);
} else {
@@ -3664,6 +3767,14 @@ void vo_wayland_uninit(struct vo *vo)
wp_color_management_surface_feedback_v1_destroy(wl->color_surface_feedback);
#endif
#if HAVE_WAYLAND_PROTOCOLS_1_44
if (wl->color_representation_manager)
wp_color_representation_manager_v1_destroy(wl->color_representation_manager);
if (wl->color_representation_surface)
wp_color_representation_surface_v1_destroy(wl->color_representation_surface);
#endif
if (wl->content_type)
wp_content_type_v1_destroy(wl->content_type);
+7
View File
@@ -106,6 +106,13 @@ struct vo_wayland_state {
void *icc_file;
uint32_t icc_size;
/* color-representation */
struct wp_color_representation_manager_v1 *color_representation_manager;
struct wp_color_representation_surface_v1 *color_representation_surface;
int alpha_map[PL_ALPHA_MODE_COUNT];
int coefficients_map[PL_COLOR_SYSTEM_COUNT];
int range_map[PL_COLOR_SYSTEM_COUNT * 2];
/* content-type */
struct wp_content_type_manager_v1 *content_type_manager;
struct wp_content_type_v1 *content_type;