compositor: add color_characteristics weston.ini option

This adds an option to program basic display color characteristics from
weston.ini. In the future there will be a way to set this information
from EDID, but because EDID is unreliable that will probably not be the
default. An ICC profile will likely override most or all of this. The
main reason to add this option is to be able to characterise HDR
monitors.

An 'output' section can have a key 'color_characteristics' (string)
set to a name. The name refers to any 'color_characteristics' section
with 'name' set to the same string.

The 'name' key of a 'color_characteristics' section cannot contain a
colon ':'. Names with colon in 'output' section key
'color_characteristics' value are reserved for future use, e.g. to
indicate that the metadata is to be taken from EDID instead of a
weston.ini section.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
Pekka Paalanen 2022-03-16 13:25:13 +02:00 committed by Pekka Paalanen
parent 3696d9b6a1
commit 518d72a37b
3 changed files with 264 additions and 1 deletions

View File

@ -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 <dlfcn.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <sys/wait.h>
@ -54,6 +55,7 @@
#include "git-version.h"
#include <libweston/version.h>
#include "weston.h"
#include "weston-private.h"
#include <libweston/backend-drm.h>
#include <libweston/backend-headless.h>
@ -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",
&section_name, "<unnamed>");
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);
}

View File

@ -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 <libweston/libweston.h>
#include <libweston/config-parser.h>
int
wet_output_set_color_characteristics(struct weston_output *output,
struct weston_config *wc,
struct weston_config_section *section);

View File

@ -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),