From 4b545fdcbd388d92895e7dd8d06c42d7ebdd4f1e Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Thu, 31 Jul 2025 22:12:08 -0700 Subject: [PATCH] chase wlroots: Add support for color-management-v1 v2: Chase wlroots!5122 v3: Chase wlroots!5141 v4: Chase wlroots!5165 v5: Chase wlroots 9b4d9eab v6: Chase wlroots 58f0867c v7: Rebase chase/0.20 v8: Reorder some of the setup code v9: Update wayland-protocols version v10: Chase wlroots 7101a69 v11: Fix code style v12: Remove server protocol declaration --- include/output.h | 3 ++- meson.build | 2 +- src/output-state.c | 5 +++++ src/output.c | 27 +++++++++++++++++---------- src/server.c | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 12 deletions(-) diff --git a/include/output.h b/include/output.h index 39556596..c17defa4 100644 --- a/include/output.h +++ b/include/output.h @@ -72,7 +72,8 @@ void handle_output_power_manager_set_mode(struct wl_listener *listener, void *data); void output_enable_adaptive_sync(struct output *output, bool enabled); void output_enable_hdr(struct output *output, struct wlr_output_state *os, - bool enabled); + bool enabled, bool silent); +void output_state_setup_hdr(struct output *output, bool silent); /** * Notifies whether a fullscreen view is displayed on the given output. diff --git a/meson.build b/meson.build index 2c2d8e57..c6c6dee9 100644 --- a/meson.build +++ b/meson.build @@ -60,7 +60,7 @@ wlroots_has_xwayland = wlroots.get_variable('have_xwayland') == 'true' have_libsfdo = not get_option('icon').disabled() wayland_server = dependency('wayland-server', version: '>=1.22.90') -wayland_protos = dependency('wayland-protocols', version: '>=1.39') +wayland_protos = dependency('wayland-protocols', version: '>=1.47') xkbcommon = dependency('xkbcommon') xcb = dependency('xcb', required: get_option('xwayland')) xcb_ewmh = dependency('xcb-ewmh', required: get_option('xwayland')) diff --git a/src/output-state.c b/src/output-state.c index 7da1108b..5be75866 100644 --- a/src/output-state.c +++ b/src/output-state.c @@ -24,6 +24,10 @@ output_state_init(struct output *output) backup_config, output->wlr_output); wlr_output_head_v1_state_apply(&backup_head->state, &output->pending); + + // This must be applied outside of config + output_state_setup_hdr(output, true); + wlr_output_configuration_v1_destroy(backup_config); } @@ -35,6 +39,7 @@ output_state_commit(struct output *output) if (committed) { wlr_output_state_finish(&output->pending); wlr_output_state_init(&output->pending); + output_state_setup_hdr(output, true); } else { wlr_log(WLR_ERROR, "Failed to commit frame"); } diff --git a/src/output.c b/src/output.c index e207ae38..f358d0f0 100644 --- a/src/output.c +++ b/src/output.c @@ -73,8 +73,8 @@ get_config_render_bit_depth(void) return LAB_RENDER_BIT_DEPTH_8; } -static void -output_state_setup_hdr(struct output *output) +void +output_state_setup_hdr(struct output *output, bool silent) { uint32_t render_format = output->wlr_output->render_format; enum render_bit_depth render_bit_depth = get_config_render_bit_depth(); @@ -88,7 +88,7 @@ output_state_setup_hdr(struct output *output) wlr_output_state_set_render_format(&output->pending, DRM_FORMAT_XBGR8888); } bool hdr = rc.hdr == LAB_HDR_ENABLED; - output_enable_hdr(output, &output->pending, hdr); + output_enable_hdr(output, &output->pending, hdr, silent); } bool @@ -411,7 +411,7 @@ configure_new_output(struct output *output) output_enable_adaptive_sync(output, true); } - output_state_setup_hdr(output); + output_state_setup_hdr(output, false); output_state_commit(output); @@ -695,7 +695,7 @@ output_config_apply(struct wlr_output_configuration_v1 *config) wlr_output_state_set_transform(os, head->state.transform); output_enable_adaptive_sync(output, head->state.adaptive_sync_enabled); - output_state_setup_hdr(output); + output_state_setup_hdr(output, false); } if (!output_state_commit(output)) { /* @@ -1199,25 +1199,32 @@ output_supports_hdr(const struct wlr_output *output, const char **unsupported_re } void -output_enable_hdr(struct output *output, struct wlr_output_state *os, bool enabled) +output_enable_hdr(struct output *output, struct wlr_output_state *os, bool enabled, bool silent) { const char *unsupported_reason = NULL; if (enabled && !output_supports_hdr(output->wlr_output, &unsupported_reason)) { - wlr_log(WLR_INFO, "Cannot enable HDR on output %s: %s", - output->wlr_output->name, unsupported_reason); + if (!silent) { + wlr_log(WLR_INFO, "Cannot enable HDR on output %s: %s", + output->wlr_output->name, unsupported_reason); + } enabled = false; } if (!enabled) { if (output->wlr_output->supported_primaries != 0 || output->wlr_output->supported_transfer_functions != 0) { - wlr_log(WLR_DEBUG, "Disabling HDR on output %s", output->wlr_output->name); + if (!silent) { + wlr_log(WLR_DEBUG, "Disabling HDR on output %s", + output->wlr_output->name); + } wlr_output_state_set_image_description(os, NULL); } return; } - wlr_log(WLR_DEBUG, "Enabling HDR on output %s", output->wlr_output->name); + if (!silent) { + wlr_log(WLR_DEBUG, "Enabling HDR on output %s", output->wlr_output->name); + } const struct wlr_output_image_description image_desc = { .primaries = WLR_COLOR_NAMED_PRIMARIES_BT2020, .transfer_function = WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ, diff --git a/src/server.c b/src/server.c index fd48efed..4f265df0 100644 --- a/src/server.c +++ b/src/server.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -724,6 +725,44 @@ server_init(void) server.tablet_manager = wlr_tablet_v2_create(server.wl_display); + if (server.renderer->features.input_color_transform) { + const enum wp_color_manager_v1_render_intent render_intents[] = { + WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL, + }; + size_t transfer_functions_len = 0; + enum wp_color_manager_v1_transfer_function *transfer_functions = + wlr_color_manager_v1_transfer_function_list_from_renderer( + server.renderer, + &transfer_functions_len + ); + size_t primaries_len = 0; + enum wp_color_manager_v1_primaries *primaries = + wlr_color_manager_v1_primaries_list_from_renderer( + server.renderer, + &primaries_len + ); + struct wlr_color_manager_v1 *cm = wlr_color_manager_v1_create( + server.wl_display, 2, &(struct wlr_color_manager_v1_options){ + .features = { + .parametric = true, + .set_mastering_display_primaries = true, + }, + .render_intents = render_intents, + .render_intents_len = ARRAY_SIZE(render_intents), + .transfer_functions = transfer_functions, + .transfer_functions_len = transfer_functions_len, + .primaries = primaries, + .primaries_len = primaries_len, + }); + free(transfer_functions); + free(primaries); + if (!cm) { + wlr_log(WLR_ERROR, "Failed to create color manager"); + } else { + wlr_scene_set_color_manager_v1(server.scene, cm); + } + } + layers_init(); /* These get cleaned up automatically on display destroy */