info: add di_info_get_default_gamma()

Wayland compositors may be interested in this.

DI-EXT is ignored, because libdisplay-info does not parse it yet.

EDID Color Point Descriptors are ignored, because they have not been
found in shipped products.

https://github.com/linuxhw/EDID.git database contains 373 samples for
which edid-decode complains:
  Basic Display Parameters & Features: sRGB is signaled, but the gamma != 2.2.

Therefore I assume that the sRGB flag is more correct when set.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
Pekka Paalanen 2023-07-10 14:48:14 +03:00
parent 0de6fd5f10
commit 5d2af9a882
2 changed files with 69 additions and 0 deletions

View file

@ -234,4 +234,14 @@ struct di_supported_signal_colorimetry {
const struct di_supported_signal_colorimetry * const struct di_supported_signal_colorimetry *
di_info_get_supported_signal_colorimetry(const struct di_info *info); di_info_get_supported_signal_colorimetry(const struct di_info *info);
/**
* Get display default transfer characteristic exponent (gamma)
*
* This should be the display gamma value when the display has been reset to
* its factory defaults, and it is driven with the default RGB colorimetry.
* The value is zero when unknown.
*/
float
di_info_get_default_gamma(const struct di_info *info);
#endif #endif

59
info.c
View file

@ -374,3 +374,62 @@ di_info_get_supported_signal_colorimetry(const struct di_info *info)
{ {
return &info->derived.supported_signal_colorimetry; return &info->derived.supported_signal_colorimetry;
} }
static const struct di_displayid *
edid_get_displayid(const struct di_edid *edid)
{
const struct di_edid_ext *const *ext;
for (ext = di_edid_get_extensions(edid); *ext; ext++) {
enum di_edid_ext_tag tag = di_edid_ext_get_tag(*ext);
if (tag == DI_EDID_EXT_DISPLAYID)
return di_edid_ext_get_displayid(*ext);
}
return NULL;
}
static const struct di_displayid_display_params *
displayid_get_display_params(const struct di_displayid *did)
{
const struct di_displayid_data_block *const *block =
di_displayid_get_data_blocks(did);
for (; *block; block++) {
enum di_displayid_data_block_tag tag = di_displayid_data_block_get_tag(*block);
if (tag == DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS)
return di_displayid_data_block_get_display_params(*block);
}
return NULL;
}
float
di_info_get_default_gamma(const struct di_info *info)
{
const struct di_edid *edid;
const struct di_displayid *did;
const struct di_edid_misc_features *misc;
edid = di_info_get_edid(info);
if (!edid)
return 0.0f;
did = edid_get_displayid(edid);
if (did) {
const struct di_displayid_display_params *did_params;
did_params = displayid_get_display_params(did);
if (did_params)
return did_params->gamma;
}
/* Trust the flag more than the gamma field value. */
misc = di_edid_get_misc_features(edid);
if (misc->srgb_is_primary)
return 2.2f;
return di_edid_get_basic_gamma(edid);
}