diff --git a/include/sway/output.h b/include/sway/output.h index 06f8bac23..787527ee7 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -131,6 +131,8 @@ struct sway_container *output_find_container(struct sway_output *output, void output_get_box(struct sway_output *output, struct wlr_box *box); +bool output_supports_hdr(struct wlr_output *output, const char **unsupported_reason_ptr); + enum sway_container_layout output_get_default_layout( struct sway_output *output); diff --git a/sway/config/output.c b/sway/config/output.c index ab2cd2006..2e3c05db3 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -348,22 +348,26 @@ static void set_modeline(struct wlr_output *output, #endif } +bool output_supports_hdr(struct wlr_output *output, const char **unsupported_reason_ptr) { + const char *unsupported_reason = NULL; + if (!(output->supported_primaries & WLR_COLOR_NAMED_PRIMARIES_BT2020)) { + unsupported_reason = "BT2020 primaries not supported by output"; + } else if (!(output->supported_transfer_functions & WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ)) { + unsupported_reason = "PQ transfer function not supported by output"; + } else if (!server.renderer->features.output_color_transform) { + unsupported_reason = "renderer doesn't support output color transforms"; + } + if (unsupported_reason_ptr != NULL) { + *unsupported_reason_ptr = unsupported_reason; + } + return unsupported_reason == NULL; +} + static void set_hdr(struct wlr_output *output, struct wlr_output_state *pending, bool enabled) { - enum wlr_color_named_primaries primaries = WLR_COLOR_NAMED_PRIMARIES_BT2020; - enum wlr_color_transfer_function tf = WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ; - if (enabled && !(output->supported_primaries & primaries)) { - sway_log(SWAY_ERROR, "Cannot enable HDR on output %s: BT2020 primaries not supported by output", - output->name); - enabled = false; - } - if (enabled && !(output->supported_transfer_functions & WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ)) { - sway_log(SWAY_ERROR, "Cannot enable HDR on output %s: PQ transfer function not supported by output", - output->name); - enabled = false; - } - if (enabled && !server.renderer->features.output_color_transform) { - sway_log(SWAY_ERROR, "Cannot enable HDR on output %s: renderer doesn't support output color transforms", - output->name); + const char *unsupported_reason = NULL; + if (!output_supports_hdr(output, &unsupported_reason)) { + sway_log(SWAY_ERROR, "Cannot enable HDR on output %s: %s", + output->name, unsupported_reason); enabled = false; } @@ -377,8 +381,8 @@ static void set_hdr(struct wlr_output *output, struct wlr_output_state *pending, sway_log(SWAY_DEBUG, "Enabling HDR on output %s", output->name); const struct wlr_output_image_description image_desc = { - .primaries = primaries, - .transfer_function = tf, + .primaries = WLR_COLOR_NAMED_PRIMARIES_BT2020, + .transfer_function = WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ, }; wlr_output_state_set_image_description(pending, &image_desc); } diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 30ed24304..3933f3ef7 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -323,6 +323,8 @@ static void ipc_json_describe_wlr_output(struct wlr_output *wlr_output, json_obj json_object_object_add(features_object, "adaptive_sync", json_object_new_boolean(wlr_output->adaptive_sync_supported || wlr_output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED)); + json_object_object_add(features_object, "hdr", + json_object_new_boolean(output_supports_hdr(wlr_output, NULL))); json_object_object_add(object, "features", features_object); } diff --git a/swaymsg/main.c b/swaymsg/main.c index 1c6e807cb..d58f29e2c 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -212,9 +212,10 @@ static void pretty_print_output(json_object *o) { json_object_object_get_ex(current_mode, "width", &width); json_object_object_get_ex(current_mode, "height", &height); json_object_object_get_ex(current_mode, "refresh", &refresh); - json_object *features, *features_adaptive_sync; + json_object *features, *features_adaptive_sync, *features_hdr; json_object_object_get_ex(o, "features", &features); json_object_object_get_ex(features, "adaptive_sync", &features_adaptive_sync); + json_object_object_get_ex(features, "hdr", &features_hdr); if (json_object_get_boolean(non_desktop)) { printf( @@ -263,7 +264,12 @@ static void pretty_print_output(json_object *o) { printf(" Allow tearing: %s\n", json_object_get_boolean(allow_tearing) ? "yes" : "no"); - printf(" HDR: %s\n", json_object_get_boolean(hdr) ? "on" : "off"); + + const char *hdr_str = "unsupported"; + if (json_object_get_boolean(features_hdr)) { + hdr_str = json_object_get_boolean(hdr) ? "on" : "off"; + } + printf(" HDR: %s\n", hdr_str); } else { printf( "Output %s '%s %s %s' (disabled)\n",