From a7a47503f19338fe29b7db3ba1fc48e15e207944 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Wed, 20 Sep 2023 15:23:09 +0300 Subject: [PATCH] frontend: add colorimetry-mode to weston.ini This output section key is used to program the KMS connector property "Colorspace" when used with the DRM-backend. This is an essential part in defining the color encoding used in the video signal, and may allow wide color gamut even on SDR. Signed-off-by: Pekka Paalanen --- frontend/main.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++ man/weston.ini.man | 30 ++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/frontend/main.c b/frontend/main.c index 20dbd5a8..af5b62a2 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -1473,6 +1473,79 @@ wet_output_set_eotf_mode(struct weston_output *output, return 0; } +static int +wet_output_set_colorimetry_mode(struct weston_output *output, + struct weston_config_section *section, + bool have_color_manager) +{ + static const struct { + const char *name; + enum weston_colorimetry_mode cmode; + } modes[] = { + { "default", WESTON_COLORIMETRY_MODE_DEFAULT }, + { "bt2020cycc", WESTON_COLORIMETRY_MODE_BT2020_CYCC }, + { "bt2020ycc", WESTON_COLORIMETRY_MODE_BT2020_YCC }, + { "bt2020rgb", WESTON_COLORIMETRY_MODE_BT2020_RGB }, + { "p3d65", WESTON_COLORIMETRY_MODE_P3D65 }, + { "p3dci", WESTON_COLORIMETRY_MODE_P3DCI }, + { "ictcp", WESTON_COLORIMETRY_MODE_ICTCP }, + }; + enum weston_colorimetry_mode cmode = WESTON_COLORIMETRY_MODE_DEFAULT; + char *str = NULL; + unsigned i; + + if (section) { + weston_config_section_get_string(section, "colorimetry-mode", + &str, NULL); + } + + if (!str) { + /* The default RGB mode is always supported. */ + assert(weston_output_get_supported_colorimetry_modes(output) & cmode); + weston_output_set_colorimetry_mode(output, cmode); + return 0; + } + + for (i = 0; i < ARRAY_LENGTH(modes); i++) + if (strcmp(str, modes[i].name) == 0) + break; + + if (i == ARRAY_LENGTH(modes)) { + weston_log("Error in config for output '%s': '%s' is not a valid colorimetry mode. Try one of:", + output->name, str); + for (i = 0; i < ARRAY_LENGTH(modes); i++) + weston_log_continue(" %s", modes[i].name); + weston_log_continue("\n"); + free(str); + return -1; + } + cmode = modes[i].cmode; + + if ((weston_output_get_supported_colorimetry_modes(output) & cmode) == 0) { + weston_log("Error: output '%s' does not support colorimetry mode %s.\n", + output->name, str); +#if !HAVE_LIBDISPLAY_INFO + weston_log_continue(STAMP_SPACE "Weston was built without libdisplay-info, " + "so colorimetry capabilities cannot be detected.\n"); +#endif + free(str); + return -1; + } + + if (cmode != WESTON_COLORIMETRY_MODE_DEFAULT && + !have_color_manager) { + weston_log("Error: Colorimetry mode %s on output '%s' requires color-management=true in weston.ini\n", + str, output->name); + free(str); + return -1; + } + + weston_output_set_colorimetry_mode(output, cmode); + + free(str); + return 0; +} + struct wet_color_characteristics_keys { const char *name; enum weston_color_characteristics_groups group; @@ -2214,6 +2287,8 @@ drm_backend_output_configure(struct weston_output *output, if (wet_output_set_eotf_mode(output, section, wet->use_color_manager) < 0) return -1; + if (wet_output_set_colorimetry_mode(output, section, wet->use_color_manager) < 0) + return -1; if (wet_output_set_color_characteristics(output, wet->config, section) < 0) @@ -3128,6 +3203,8 @@ headless_backend_output_configure(struct weston_output *output) section = weston_config_get_section(wc, "output", "name", output->name); if (wet_output_set_eotf_mode(output, section, wet->use_color_manager) < 0) return -1; + if (wet_output_set_colorimetry_mode(output, section, wet->use_color_manager) < 0) + return -1; if (wet_output_set_color_characteristics(output, wc, section) < 0) return -1; diff --git a/man/weston.ini.man b/man/weston.ini.man index a6b10b40..28718033 100644 --- a/man/weston.ini.man +++ b/man/weston.ini.man @@ -596,6 +596,36 @@ A comma separated list of the IDs of applications to place on this output. These IDs should match the application IDs as set with the xdg_shell.set_app_id request. Currently, this option is supported by kiosk-shell. .TP 7 +.BI "colorimetry-mode=" default +Sets the colorimetry mode on the output. The colorimetry mode together with +the EOTF mode below define the color encoding used in the video signal. The +colorimetry mode is used for choosing between the default sink defined +colorimetry (intended to be described by EDID), and standardised other +encodings that support wide color gamut (WCG). + +The display driver, the graphics card, and the video sink (monitor) need to +support the chosen mode, otherwise the result is undefined or fails. + +The mode can be one of the following strings: +.PP +.RS 10 +.nf +.BR "default " "default (RGB) colorimetry, video sink dependant" +.BR "bt2020cycc " "Rec. ITU-R BT.2020 constant luminance YCbCr" +.BR "bt2020ycc " "Rec. ITU-R BT.2020 non-constant luminance YCbCr" +.BR "bt2020rgb " "Rec. ITU-R BT.2020 RGB" +.BR "p3d65 " "SMPTE ST 2113 DCI-P3 RGB D65" +.BR "p3dci " "SMPTE ST 2113 DCI-P3 RGB Theater" +.BR "ictcp " "Rec. ITU-R BT.2100 ICtCp" +.fi +.RE +.IP +Defaults to +.BR default ". Non-default modes require " "color-management=true" . + +Note: The operating system might not honor the choice between RGB and YCbCr, +that may be picked by a Linux display driver automatically. +.TP 7 .BI "eotf-mode=" sdr Sets the EOTF mode on the output. This is used for choosing between standard dynamic range (SDR) mode and the various high dynamic range (HDR) modes. The