utils/edid: add color and HDR information

This commit is contained in:
Xaver Hugl 2023-04-28 21:39:13 +02:00
parent 124d915408
commit 2fb95eb80c
2 changed files with 84 additions and 0 deletions

View file

@ -19,6 +19,7 @@
#include <QCryptographicHash>
extern "C" {
#include <libdisplay-info/cta.h>
#include <libdisplay-info/edid.h>
#include <libdisplay-info/info.h>
}
@ -108,6 +109,7 @@ Edid::Edid(const void *data, uint32_t size)
const di_edid_vendor_product *productInfo = di_edid_get_vendor_product(edid);
const di_edid_screen_size *screenSize = di_edid_get_screen_size(edid);
// basic output information
m_physicalSize = QSize(screenSize->width_cm, screenSize->height_cm) * 10;
m_eisaId = parseEisaId(bytes);
UniqueCPtr<char> monitorName{di_info_get_model(info)};
@ -118,6 +120,55 @@ Edid::Edid(const void *data, uint32_t size)
hash.addData(m_raw);
m_hash = QString::fromLatin1(hash.result().toHex());
// colorimetry and HDR metadata
const auto chromaticity = di_edid_get_chromaticity_coords(edid);
if (chromaticity) {
m_colorimetry = {
.redPrimary = {chromaticity->red_x, chromaticity->red_y},
.greenPrimary = {chromaticity->green_x, chromaticity->green_y},
.bluePrimary = {chromaticity->blue_x, chromaticity->blue_y},
.whitePoint = {chromaticity->white_x, chromaticity->white_y},
};
} else {
// assume sRGB
m_colorimetry = {
.redPrimary = {0.64, 0.33},
.greenPrimary = {0.30, 0.60},
.bluePrimary = {0.15, 0.06},
.whitePoint = {0.3127, 0.3290},
};
}
const di_edid_cta *cta = nullptr;
const di_edid_ext *const *exts = di_edid_get_extensions(edid);
const di_cta_hdr_static_metadata_block *hdr_static_metadata = nullptr;
const di_cta_colorimetry_block *colorimetry = nullptr;
for (; *exts != nullptr; exts++) {
if ((cta = di_edid_ext_get_cta(*exts))) {
break;
}
}
if (cta) {
const di_cta_data_block *const *blocks = di_edid_cta_get_data_blocks(cta);
for (; *blocks != nullptr; blocks++) {
if (!hdr_static_metadata && (hdr_static_metadata = di_cta_data_block_get_hdr_static_metadata(*blocks))) {
continue;
}
if (!colorimetry && (colorimetry = di_cta_data_block_get_colorimetry(*blocks))) {
continue;
}
}
if (hdr_static_metadata) {
m_hdrMetadata = HDRMetadata{
.desiredContentMinLuminance = hdr_static_metadata->desired_content_min_luminance,
.desiredContentMaxLuminance = hdr_static_metadata->desired_content_max_luminance,
.desiredMaxFrameAverageLuminance = hdr_static_metadata->desired_content_max_frame_avg_luminance,
.supportsPQ = hdr_static_metadata->eotfs->pq,
.supportsBT2020 = colorimetry && colorimetry->bt2020_rgb,
};
}
}
m_isValid = true;
di_info_destroy(info);
}
@ -189,4 +240,14 @@ QString Edid::hash() const
return m_hash;
}
Edid::Colorimetry Edid::colorimetry() const
{
return m_colorimetry;
}
std::optional<Edid::HDRMetadata> Edid::hdrMetadata() const
{
return m_hdrMetadata;
}
} // namespace KWin

View file

@ -12,7 +12,9 @@
#include "kwin_export.h"
#include <QByteArray>
#include <QList>
#include <QSize>
#include <QVector2D>
namespace KWin
{
@ -76,6 +78,25 @@ public:
QString hash() const;
struct Colorimetry
{
QVector2D redPrimary;
QVector2D greenPrimary;
QVector2D bluePrimary;
QVector2D whitePoint;
};
Colorimetry colorimetry() const;
struct HDRMetadata
{
float desiredContentMinLuminance;
float desiredContentMaxLuminance;
float desiredMaxFrameAverageLuminance;
bool supportsPQ;
bool supportsBT2020;
};
std::optional<HDRMetadata> hdrMetadata() const;
private:
QSize m_physicalSize;
QByteArray m_vendor;
@ -83,6 +104,8 @@ private:
QByteArray m_monitorName;
QByteArray m_serialNumber;
QString m_hash;
Colorimetry m_colorimetry;
std::optional<HDRMetadata> m_hdrMetadata;
QByteArray m_raw;
bool m_isValid = false;