1
0
Fork 0
mirror of https://github.com/hyprwm/Hyprland synced 2025-04-10 05:32:09 +02:00

renderer: Simplify and fix hdr metadata setting ()

* simplify and fix hdr metadata setting

* keep incorrect(?) cm skip till 
This commit is contained in:
UjinT34 2025-03-24 15:56:07 +03:00 committed by GitHub
parent e4abf26069
commit a852461c7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 36 additions and 14 deletions

View file

@ -1382,9 +1382,9 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
const auto imageDescription =
m_RenderData.surface.valid() && m_RenderData.surface->colorManagement.valid() ? m_RenderData.surface->colorManagement->imageDescription() : SImageDescription{};
const bool skipCM = !*PENABLECM /* CM disabled by the user */
|| !m_RenderData.surface /* No surface - no point in CM */
|| !m_bCMSupported /* CM unsupported - hw failed to compile the shader probably */
const bool skipCM = !*PENABLECM /* CM disabled by the user */
|| !m_RenderData.surface /* FIXME unknown texture settings should be treated as sRGB and go through CM if monitor isn't in sRGB mode */
|| !m_bCMSupported /* CM unsupported - hw failed to compile the shader probably */
|| (imageDescription == m_RenderData.pMonitor->imageDescription) /* Source and target have the same image description */
|| ((*PPASS == 1 || (*PPASS == 2 && imageDescription.transferFunction == CM_TRANSFER_FUNCTION_ST2084_PQ)) && m_RenderData.pMonitor->activeWorkspace &&
m_RenderData.pMonitor->activeWorkspace->m_bHasFullscreenWindow &&

View file

@ -1411,11 +1411,16 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) {
static const hdr_output_metadata NO_HDR_METADATA = {.hdmi_metadata_type1 = hdr_metadata_infoframe{.eotf = 0}};
static hdr_output_metadata createHDRMetadata(SImageDescription settings, Aquamarine::IOutput::SParsedEDID edid) {
if (settings.transferFunction != CM_TRANSFER_FUNCTION_ST2084_PQ)
return NO_HDR_METADATA; // empty metadata for SDR
uint8_t eotf = 0;
switch (settings.transferFunction) {
case CM_TRANSFER_FUNCTION_SRGB: eotf = 0; break; // used to send primaries and luminances to AQ. ignored for now
case CM_TRANSFER_FUNCTION_ST2084_PQ: eotf = 2; break;
// case CM_TRANSFER_FUNCTION_HLG: eotf = 3; break; TODO check display capabilities first
default: return NO_HDR_METADATA; // empty metadata for SDR
}
const auto toNits = [](uint32_t value) { return uint16_t(std::round(value)); };
const auto to16Bit = [](uint32_t value) { return uint16_t(std::round(value * 50000)); };
const auto to16Bit = [](float value) { return uint16_t(std::round(value * 50000)); };
auto colorimetry = settings.primariesNameSet || settings.primaries == SPCPRimaries{} ? getPrimaries(settings.primariesNamed) : settings.primaries;
auto luminances = settings.masteringLuminances.max > 0 ?
@ -1429,7 +1434,7 @@ static hdr_output_metadata createHDRMetadata(SImageDescription settings, A
.metadata_type = 0,
.hdmi_metadata_type1 =
hdr_metadata_infoframe{
.eotf = 2,
.eotf = eotf,
.metadata_type = 0,
.display_primaries =
{
@ -1454,25 +1459,42 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
Debug::log(TRACE, "ColorManagement supportsBT2020 {}, supportsPQ {}", pMonitor->output->parsedEDID.supportsBT2020, SUPPORTSPQ);
if (pMonitor->output->parsedEDID.supportsBT2020 && SUPPORTSPQ) {
// HDR metadata determined by
// PPASS = 0 monitor settings
// PPASS = 1
// windowed: monitor settings
// fullscreen surface: surface settings FIXME: fullscreen SDR surface passthrough - pass degamma, ctm, gamma if needed
// PPASS = 2
// windowed: monitor settings
// fullscreen SDR surface: monitor settings
// fullscreen HDR surface: surface settings
bool wantHDR = PHDR;
bool hdrIsHandled = false;
if (*PPASS && pMonitor->activeWorkspace && pMonitor->activeWorkspace->m_bHasFullscreenWindow && pMonitor->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN) {
const auto WINDOW = pMonitor->activeWorkspace->getFullscreenWindow();
const auto ROOT_SURF = WINDOW->m_pWLSurface->resource();
const auto SURF =
ROOT_SURF->findFirstPreorder([ROOT_SURF](SP<CWLSurfaceResource> surf) { return surf->colorManagement.valid() && surf->extends() == ROOT_SURF->extends(); });
const bool wantHDR = PHDR && *PPASS == 2;
if (SURF && SURF->colorManagement.valid() && SURF->colorManagement->hasImageDescription()) {
wantHDR = PHDR && *PPASS == 2;
// we have a surface with image description and it's allowed by wantHDR
if (SURF && SURF->colorManagement.valid() && SURF->colorManagement->hasImageDescription() &&
(!wantHDR || SURF->colorManagement->imageDescription().transferFunction == CM_TRANSFER_FUNCTION_ST2084_PQ)) {
bool needsHdrMetadataUpdate = SURF->colorManagement->needsHdrMetadataUpdate() || pMonitor->m_previousFSWindow != WINDOW;
if (SURF->colorManagement->needsHdrMetadataUpdate())
SURF->colorManagement->setHDRMetadata(createHDRMetadata(SURF->colorManagement->imageDescription(), pMonitor->output->parsedEDID));
if (needsHdrMetadataUpdate)
pMonitor->output->state->setHDRMetadata(SURF->colorManagement->hdrMetadata());
} else if ((pMonitor->output->state->state().hdrMetadata.hdmi_metadata_type1.eotf == 2) != wantHDR)
pMonitor->output->state->setHDRMetadata(wantHDR ? createHDRMetadata(pMonitor->imageDescription, pMonitor->output->parsedEDID) : NO_HDR_METADATA);
hdrIsHandled = true;
}
pMonitor->m_previousFSWindow = WINDOW;
} else {
if ((pMonitor->output->state->state().hdrMetadata.hdmi_metadata_type1.eotf == 2) != PHDR)
pMonitor->output->state->setHDRMetadata(PHDR ? createHDRMetadata(pMonitor->imageDescription, pMonitor->output->parsedEDID) : NO_HDR_METADATA);
}
if (!hdrIsHandled) {
if ((pMonitor->output->state->state().hdrMetadata.hdmi_metadata_type1.eotf == 2) != wantHDR)
pMonitor->output->state->setHDRMetadata(wantHDR ? createHDRMetadata(pMonitor->imageDescription, pMonitor->output->parsedEDID) : NO_HDR_METADATA);
pMonitor->m_previousFSWindow.reset();
}
}