diff --git a/compositor/main.c b/compositor/main.c index 9a90885e..b9c740f3 100644 --- a/compositor/main.c +++ b/compositor/main.c @@ -1,7 +1,7 @@ /* * Copyright © 2010-2011 Intel Corporation * Copyright © 2008-2011 Kristian Høgsberg - * Copyright © 2012-2018 Collabora, Ltd. + * Copyright © 2012-2018,2022 Collabora, Ltd. * Copyright © 2010-2011 Benjamin Franzke * Copyright © 2013 Jason Ekstrand * Copyright © 2017, 2018 General Electric Company @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ #include "git-version.h" #include #include "weston.h" +#include "weston-private.h" #include #include @@ -1383,6 +1385,156 @@ wet_output_set_eotf_mode(struct weston_output *output, return 0; } +struct wet_color_characteristics_keys { + const char *name; + enum weston_color_characteristics_groups group; + float minval; + float maxval; +}; + +#define COLOR_CHARAC_NAME "color_characteristics" + +static int +parse_color_characteristics(struct weston_color_characteristics *cc_out, + struct weston_config_section *section) +{ + static const struct wet_color_characteristics_keys keys[] = { + { "red_x", WESTON_COLOR_CHARACTERISTICS_GROUP_PRIMARIES, 0.0f, 1.0f }, + { "red_y", WESTON_COLOR_CHARACTERISTICS_GROUP_PRIMARIES, 0.0f, 1.0f }, + { "green_x", WESTON_COLOR_CHARACTERISTICS_GROUP_PRIMARIES, 0.0f, 1.0f }, + { "green_y", WESTON_COLOR_CHARACTERISTICS_GROUP_PRIMARIES, 0.0f, 1.0f }, + { "blue_x", WESTON_COLOR_CHARACTERISTICS_GROUP_PRIMARIES, 0.0f, 1.0f }, + { "blue_y", WESTON_COLOR_CHARACTERISTICS_GROUP_PRIMARIES, 0.0f, 1.0f }, + { "white_x", WESTON_COLOR_CHARACTERISTICS_GROUP_WHITE, 0.0f, 1.0f }, + { "white_y", WESTON_COLOR_CHARACTERISTICS_GROUP_WHITE, 0.0f, 1.0f }, + { "max_L", WESTON_COLOR_CHARACTERISTICS_GROUP_MAXL, 0.0f, 1e5f }, + { "min_L", WESTON_COLOR_CHARACTERISTICS_GROUP_MINL, 0.0f, 1e5f }, + { "maxFALL", WESTON_COLOR_CHARACTERISTICS_GROUP_MAXFALL, 0.0f, 1e5f }, + }; + static const char *msgpfx = "Config error in weston.ini [" COLOR_CHARAC_NAME "]"; + struct weston_color_characteristics cc = {}; + float *const keyvalp[ARRAY_LENGTH(keys)] = { + /* These must be in the same order as keys[]. */ + &cc.primary[0].x, &cc.primary[0].y, + &cc.primary[1].x, &cc.primary[1].y, + &cc.primary[2].x, &cc.primary[2].y, + &cc.white.x, &cc.white.y, + &cc.max_luminance, + &cc.min_luminance, + &cc.maxFALL, + }; + bool found[ARRAY_LENGTH(keys)] = {}; + uint32_t missing_group_mask = 0; + unsigned i; + char *section_name; + int ret = 0; + + weston_config_section_get_string(section, "name", + §ion_name, ""); + if (strchr(section_name, ':') != NULL) { + ret = -1; + weston_log("%s name=%s: reserved name. Do not use ':' character in the name.\n", + msgpfx, section_name); + } + + /* Parse keys if they exist */ + for (i = 0; i < ARRAY_LENGTH(keys); i++) { + double value; + + if (weston_config_section_get_double(section, keys[i].name, + &value, NAN) == 0) { + float f = value; + + found[i] = true; + + /* Range check, NaN shall not pass. */ + if (f >= keys[i].minval && f <= keys[i].maxval) { + /* Key found, parsed, and good value. */ + *keyvalp[i] = f; + continue; + } + + ret = -1; + weston_log("%s name=%s: %s value %f is outside of the range %f - %f.\n", + msgpfx, section_name, keys[i].name, value, + keys[i].minval, keys[i].maxval); + continue; + } + + if (errno == EINVAL) { + found[i] = true; + ret = -1; + weston_log("%s name=%s: failed to parse the value of key %s.\n", + msgpfx, section_name, keys[i].name); + } + } + + /* Collect set and unset groups */ + for (i = 0; i < ARRAY_LENGTH(keys); i++) { + uint32_t group = keys[i].group; + + if (found[i]) + cc.group_mask |= group; + else + missing_group_mask |= group; + } + + /* Ensure groups are given fully or not at all. */ + for (i = 0; i < ARRAY_LENGTH(keys); i++) { + uint32_t group = keys[i].group; + + if ((cc.group_mask & group) && (missing_group_mask & group)) { + ret = -1; + weston_log("%s name=%s: group %d key %s is %s. " + "You must set either none or all keys of a group.\n", + msgpfx, section_name, ffs(group), keys[i].name, + found[i] ? "set" : "missing"); + } + } + + free(section_name); + + if (ret == 0) + *cc_out = cc; + + return ret; +} + +WESTON_EXPORT_FOR_TESTS int +wet_output_set_color_characteristics(struct weston_output *output, + struct weston_config *wc, + struct weston_config_section *section) +{ + char *cc_name = NULL; + struct weston_config_section *cc_section; + struct weston_color_characteristics cc; + + weston_config_section_get_string(section, COLOR_CHARAC_NAME, + &cc_name, NULL); + if (!cc_name) + return 0; + + cc_section = weston_config_get_section(wc, COLOR_CHARAC_NAME, + "name", cc_name); + if (!cc_section) { + weston_log("Config error in weston.ini, output %s: " + "no [" COLOR_CHARAC_NAME "] section with 'name=%s' found.\n", + output->name, cc_name); + goto out_error; + } + + if (parse_color_characteristics(&cc, cc_section) < 0) + goto out_error; + + weston_output_set_color_characteristics(output, &cc); + free(cc_name); + return 0; + +out_error: + free(cc_name); + return -1; +} + static void allow_content_protection(struct weston_output *output, struct weston_config_section *section) @@ -1909,6 +2061,10 @@ drm_backend_output_configure(struct weston_output *output, if (wet_output_set_eotf_mode(output, section) < 0) return -1; + if (wet_output_set_color_characteristics(output, + wet->config, section) < 0) + return -1; + return 0; } @@ -2732,6 +2888,9 @@ headless_backend_output_configure(struct weston_output *output) if (wet_output_set_eotf_mode(output, section) < 0) return -1; + if (wet_output_set_color_characteristics(output, wc, section) < 0) + return -1; + return wet_configure_windowed_output_from_config(output, &defaults); } diff --git a/compositor/weston-private.h b/compositor/weston-private.h new file mode 100644 index 00000000..01b37dcf --- /dev/null +++ b/compositor/weston-private.h @@ -0,0 +1,34 @@ +/* + * Copyright 2022 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once + +#include +#include + +int +wet_output_set_color_characteristics(struct weston_output *output, + struct weston_config *wc, + struct weston_config_section *section); diff --git a/man/weston.ini.man b/man/weston.ini.man index d622e9b6..d9b17d85 100644 --- a/man/weston.ini.man +++ b/man/weston.ini.man @@ -567,6 +567,13 @@ The mode can be one of the following strings: .IP Defaults to .BR sdr ". Non-SDR modes require " "color-management=true" . +.TP 7 +.BI "color_characteristics=" name +Sets the basic output color characteristics by loading the parameters from the +.B color_characteristics +section with the key +.BI "name=" name +\&. If an ICC profile is also set, the ICC profile takes precedence. .\"--------------------------------------------------------------------- .SH "INPUT-METHOD SECTION" .TP 7 @@ -663,6 +670,69 @@ parallel to Weston, so it does not have to immediately exit. Defaults to empty. If set to true, quit Weston after the auto-launched executable exits. Set to false by default. .\"--------------------------------------------------------------------- +.SH "COLOR_CHARACTERISTICS SECTION" +Each +.B color_characteristics +section records one set of basic display or monitor color characterisation +parameters. The parameters are defined in CTA-861-H specification as Static +Metadata Type 1, and they can also be found in EDID. The parameters are +divided into groups. Each group must be given either fully or not at all. +.PP +Each section should be named with +.B name +key by which it can be referenced from other sections. A metadata section is +just a collection of parameter values and does nothing on its own. It has an +effect only when referenced from elsewhere. +.PP +See +.BR output " section key " color_characteristics . +.TP 7 +.BI "name=" name +An arbitrary name for this section. You can choose any name you want as long as +it does not contain the colon +.RB ( : ) +character. Names with at least one colon are reserved. +.SS Primaries group +.TP 7 +.BI "red_x=" x +.TQ +.BI "red_y=" y +.TQ +.BI "green_x=" x +.TQ +.BI "green_y=" y +.TQ +.BI "blue_x=" x +.TQ +.BI "blue_y=" y +The CIE 1931 xy chromaticity coordinates of the display primaries. +These floating point values must reside between 0.0 and 1.0, inclusive. +.SS White point group +.TP 7 +.BI "white_x=" x +.TQ +.BI "white_y=" y +The CIE 1931 xy chromaticity coordinates of the display white point. +These floating point values must reside between 0.0 and 1.0, inclusive. +.SS Independent parameters +Each parameter listed here has its own group and therefore can be given +alone. +.TP 7 +.BI "max_L=" L +Display's desired maximum content luminance (peak) +.IR L \~cd/m², +a floating point value in the range 0.0\(en100000.0. +.TP 7 +.BI "min_L=" L +Display's desired minimum content luminance +.IR L \~cd/m², +a floating point value in the range 0.0\(en100000.0. +.TP 7 +.BI "maxFALL=" L +Display's desired maximum frame-average light level +.IR L \~cd/m², +a floating point value in the range 0.0\(en100000.0. +.\"--------------------------------------------------------------------- .SH "SEE ALSO" .BR weston (1), .BR weston-bindings (7),