mirror of
https://github.com/hyprwm/Hyprland
synced 2025-12-20 07:50:03 +01:00
renderer: Fix CM for DS and SDR passthrough (#11503)
This commit is contained in:
parent
790e544689
commit
05a1c0aa73
7 changed files with 186 additions and 83 deletions
|
|
@ -141,12 +141,12 @@ std::string CHyprCtl::getSolitaryBlockedReason(Hyprutils::Memory::CSharedPointer
|
||||||
|
|
||||||
const std::array<const char*, CMonitor::DS_CHECKS_COUNT> DS_REASONS_JSON = {
|
const std::array<const char*, CMonitor::DS_CHECKS_COUNT> DS_REASONS_JSON = {
|
||||||
"\"UNKNOWN\"", "\"USER\"", "\"WINDOWED\"", "\"CONTENT\"", "\"MIRROR\"", "\"RECORD\"", "\"SW\"",
|
"\"UNKNOWN\"", "\"USER\"", "\"WINDOWED\"", "\"CONTENT\"", "\"MIRROR\"", "\"RECORD\"", "\"SW\"",
|
||||||
"\"CANDIDATE\"", "\"SURFACE\"", "\"TRANSFORM\"", "\"DMA\"", "\"TEARING\"", "\"FAILED\"",
|
"\"CANDIDATE\"", "\"SURFACE\"", "\"TRANSFORM\"", "\"DMA\"", "\"TEARING\"", "\"FAILED\"", "\"CM\"",
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::array<const char*, CMonitor::DS_CHECKS_COUNT> DS_REASONS_TEXT = {
|
const std::array<const char*, CMonitor::DS_CHECKS_COUNT> DS_REASONS_TEXT = {
|
||||||
"unknown reason", "user settings", "windowed mode", "content type", "monitor mirrors", "screen record/screenshot", "software renders/cursors",
|
"unknown reason", "user settings", "windowed mode", "content type", "monitor mirrors", "screen record/screenshot", "software renders/cursors",
|
||||||
"missing candidate", "invalid surface", "surface transformations", "invalid buffer", "tearing", "activation failed",
|
"missing candidate", "invalid surface", "surface transformations", "invalid buffer", "tearing", "activation failed", "color management",
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string CHyprCtl::getDSBlockedReason(Hyprutils::Memory::CSharedPointer<CMonitor> m, eHyprCtlOutputFormat format) {
|
std::string CHyprCtl::getDSBlockedReason(Hyprutils::Memory::CSharedPointer<CMonitor> m, eHyprCtlOutputFormat format) {
|
||||||
|
|
|
||||||
|
|
@ -988,8 +988,8 @@ bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
|
||||||
static auto PMINRR = CConfigValue<Hyprlang::INT>("cursor:min_refresh_rate");
|
static auto PMINRR = CConfigValue<Hyprlang::INT>("cursor:min_refresh_rate");
|
||||||
|
|
||||||
// skip scheduling extra frames for fullsreen apps with vrr
|
// skip scheduling extra frames for fullsreen apps with vrr
|
||||||
const bool shouldSkip = m_activeWorkspace && m_activeWorkspace->m_hasFullscreenWindow && m_activeWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN &&
|
const bool shouldSkip = inFullscreenMode() && (*PNOBREAK == 1 || (*PNOBREAK == 2 && m_activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) &&
|
||||||
(*PNOBREAK == 1 || (*PNOBREAK == 2 && m_activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) && m_output->state->state().adaptiveSync;
|
m_output->state->state().adaptiveSync;
|
||||||
|
|
||||||
// keep requested minimum refresh rate
|
// keep requested minimum refresh rate
|
||||||
if (shouldSkip && *PMINRR && m_lastPresentationTimer.getMillis() > 1000.0f / *PMINRR) {
|
if (shouldSkip && *PMINRR && m_lastPresentationTimer.getMillis() > 1000.0f / *PMINRR) {
|
||||||
|
|
@ -1631,25 +1631,28 @@ uint8_t CMonitor::isTearingBlocked(bool full) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*PTEARINGENABLED) {
|
if (!*PTEARINGENABLED) {
|
||||||
Debug::log(WARN, "Tearing commit requested but the master switch general:allow_tearing is off, ignoring");
|
|
||||||
reasons |= TC_USER;
|
reasons |= TC_USER;
|
||||||
if (!full)
|
if (!full) {
|
||||||
|
Debug::log(WARN, "Tearing commit requested but the master switch general:allow_tearing is off, ignoring");
|
||||||
return reasons;
|
return reasons;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (g_pHyprOpenGL->m_renderData.mouseZoomFactor != 1.0) {
|
if (g_pHyprOpenGL->m_renderData.mouseZoomFactor != 1.0) {
|
||||||
Debug::log(WARN, "Tearing commit requested but scale factor is not 1, ignoring");
|
|
||||||
reasons |= TC_ZOOM;
|
reasons |= TC_ZOOM;
|
||||||
if (!full)
|
if (!full) {
|
||||||
|
Debug::log(WARN, "Tearing commit requested but scale factor is not 1, ignoring");
|
||||||
return reasons;
|
return reasons;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_tearingState.canTear) {
|
if (!m_tearingState.canTear) {
|
||||||
Debug::log(WARN, "Tearing commit requested but monitor doesn't support it, ignoring");
|
|
||||||
reasons |= TC_SUPPORT;
|
reasons |= TC_SUPPORT;
|
||||||
if (!full)
|
if (!full) {
|
||||||
|
Debug::log(WARN, "Tearing commit requested but monitor doesn't support it, ignoring");
|
||||||
return reasons;
|
return reasons;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_solitaryClient.expired()) {
|
if (m_solitaryClient.expired()) {
|
||||||
reasons |= TC_CANDIDATE;
|
reasons |= TC_CANDIDATE;
|
||||||
|
|
@ -1671,6 +1674,7 @@ bool CMonitor::updateTearing() {
|
||||||
uint16_t CMonitor::isDSBlocked(bool full) {
|
uint16_t CMonitor::isDSBlocked(bool full) {
|
||||||
uint16_t reasons = 0;
|
uint16_t reasons = 0;
|
||||||
static auto PDIRECTSCANOUT = CConfigValue<Hyprlang::INT>("render:direct_scanout");
|
static auto PDIRECTSCANOUT = CConfigValue<Hyprlang::INT>("render:direct_scanout");
|
||||||
|
static auto PPASS = CConfigValue<Hyprlang::INT>("render:cm_fs_passthrough");
|
||||||
|
|
||||||
if (*PDIRECTSCANOUT == 0) {
|
if (*PDIRECTSCANOUT == 0) {
|
||||||
reasons |= DS_BLOCK_USER;
|
reasons |= DS_BLOCK_USER;
|
||||||
|
|
@ -1734,8 +1738,14 @@ uint16_t CMonitor::isDSBlocked(bool full) {
|
||||||
|
|
||||||
// we can't scanout shm buffers.
|
// we can't scanout shm buffers.
|
||||||
const auto params = PSURFACE->m_current.buffer->dmabuf();
|
const auto params = PSURFACE->m_current.buffer->dmabuf();
|
||||||
if (!params.success || !PSURFACE->m_current.texture->m_eglImage /* dmabuf */)
|
if (!params.success || !PSURFACE->m_current.texture->m_eglImage /* dmabuf */) {
|
||||||
reasons |= DS_BLOCK_DMA;
|
reasons |= DS_BLOCK_DMA;
|
||||||
|
if (!full)
|
||||||
|
return reasons;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canNoShaderCM() && (!inHDR() || (PSURFACE->m_colorManagement.valid() && PSURFACE->m_colorManagement->isWindowsScRGB())) && *PPASS != 1)
|
||||||
|
reasons |= DS_BLOCK_CM;
|
||||||
|
|
||||||
return reasons;
|
return reasons;
|
||||||
}
|
}
|
||||||
|
|
@ -1935,6 +1945,52 @@ bool CMonitor::inHDR() {
|
||||||
return m_output->state->state().hdrMetadata.hdmi_metadata_type1.eotf == 2;
|
return m_output->state->state().hdrMetadata.hdmi_metadata_type1.eotf == 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CMonitor::inFullscreenMode() {
|
||||||
|
return m_activeWorkspace && m_activeWorkspace->m_hasFullscreenWindow && m_activeWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<NColorManagement::SImageDescription> CMonitor::getFSImageDescription() {
|
||||||
|
if (!inFullscreenMode())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
const auto FS_WINDOW = m_activeWorkspace->getFullscreenWindow();
|
||||||
|
if (!FS_WINDOW)
|
||||||
|
return {}; // should be unreachable
|
||||||
|
|
||||||
|
const auto ROOT_SURF = FS_WINDOW->m_wlSurface->resource();
|
||||||
|
const auto SURF = ROOT_SURF->findWithCM();
|
||||||
|
return SURF ? SURF->m_colorManagement->imageDescription() : SImageDescription{};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMonitor::needsCM() {
|
||||||
|
return getFSImageDescription() != m_imageDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO support more drm properties
|
||||||
|
bool CMonitor::canNoShaderCM() {
|
||||||
|
const auto SRC_DESC = getFSImageDescription();
|
||||||
|
if (!SRC_DESC.has_value())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (SRC_DESC.value() == m_imageDescription)
|
||||||
|
return true; // no CM needed
|
||||||
|
|
||||||
|
if (SRC_DESC->icc.fd >= 0 || m_imageDescription.icc.fd >= 0)
|
||||||
|
return false; // no ICC support
|
||||||
|
|
||||||
|
// only primaries differ
|
||||||
|
if (SRC_DESC->transferFunction == m_imageDescription.transferFunction && SRC_DESC->transferFunctionPower == m_imageDescription.transferFunctionPower &&
|
||||||
|
SRC_DESC->luminances == m_imageDescription.luminances && SRC_DESC->masteringLuminances == m_imageDescription.masteringLuminances &&
|
||||||
|
SRC_DESC->maxCLL == m_imageDescription.maxCLL && SRC_DESC->maxFALL == m_imageDescription.maxFALL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMonitor::doesNoShaderCM() {
|
||||||
|
return m_noShaderCTM;
|
||||||
|
}
|
||||||
|
|
||||||
CMonitorState::CMonitorState(CMonitor* owner) : m_owner(owner) {
|
CMonitorState::CMonitorState(CMonitor* owner) : m_owner(owner) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -229,8 +229,9 @@ class CMonitor {
|
||||||
DS_BLOCK_DMA = (1 << 10),
|
DS_BLOCK_DMA = (1 << 10),
|
||||||
DS_BLOCK_TEARING = (1 << 11),
|
DS_BLOCK_TEARING = (1 << 11),
|
||||||
DS_BLOCK_FAILED = (1 << 12),
|
DS_BLOCK_FAILED = (1 << 12),
|
||||||
|
DS_BLOCK_CM = (1 << 13),
|
||||||
|
|
||||||
DS_CHECKS_COUNT = 13,
|
DS_CHECKS_COUNT = 14,
|
||||||
};
|
};
|
||||||
|
|
||||||
// keep in sync with HyprCtl
|
// keep in sync with HyprCtl
|
||||||
|
|
@ -319,10 +320,20 @@ class CMonitor {
|
||||||
|
|
||||||
bool inHDR();
|
bool inHDR();
|
||||||
|
|
||||||
|
/// Has an active workspace with a real fullscreen window
|
||||||
|
bool inFullscreenMode();
|
||||||
|
std::optional<NColorManagement::SImageDescription> getFSImageDescription();
|
||||||
|
|
||||||
|
bool needsCM();
|
||||||
|
/// Can do CM without shader
|
||||||
|
bool canNoShaderCM();
|
||||||
|
bool doesNoShaderCM();
|
||||||
|
|
||||||
bool m_enabled = false;
|
bool m_enabled = false;
|
||||||
bool m_renderingInitPassed = false;
|
bool m_renderingInitPassed = false;
|
||||||
WP<CWindow> m_previousFSWindow;
|
WP<CWindow> m_previousFSWindow;
|
||||||
NColorManagement::SImageDescription m_imageDescription;
|
NColorManagement::SImageDescription m_imageDescription;
|
||||||
|
bool m_noShaderCTM = false; // sets drm CTM, restore needed
|
||||||
|
|
||||||
// For the list lookup
|
// For the list lookup
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -423,6 +423,10 @@ SP<CWLSurfaceResource> CWLSurfaceResource::findFirstPreorder(std::function<bool(
|
||||||
return findFirstPreorderHelper(m_self.lock(), fn);
|
return findFirstPreorderHelper(m_self.lock(), fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SP<CWLSurfaceResource> CWLSurfaceResource::findWithCM() {
|
||||||
|
return findFirstPreorder([this](SP<CWLSurfaceResource> surf) { return surf->m_colorManagement.valid() && surf->extends() == extends(); });
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<SP<CWLSurfaceResource>, Vector2D> CWLSurfaceResource::at(const Vector2D& localCoords, bool allowsInput) {
|
std::pair<SP<CWLSurfaceResource>, Vector2D> CWLSurfaceResource::at(const Vector2D& localCoords, bool allowsInput) {
|
||||||
std::vector<std::pair<SP<CWLSurfaceResource>, Vector2D>> surfs;
|
std::vector<std::pair<SP<CWLSurfaceResource>, Vector2D>> surfs;
|
||||||
breadthfirst([&surfs](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) { surfs.emplace_back(std::make_pair<>(surf, offset)); }, &surfs);
|
breadthfirst([&surfs](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) { surfs.emplace_back(std::make_pair<>(surf, offset)); }, &surfs);
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ class CWLSurfaceResource {
|
||||||
|
|
||||||
void breadthfirst(std::function<void(SP<CWLSurfaceResource>, const Vector2D&, void*)> fn, void* data);
|
void breadthfirst(std::function<void(SP<CWLSurfaceResource>, const Vector2D&, void*)> fn, void* data);
|
||||||
SP<CWLSurfaceResource> findFirstPreorder(std::function<bool(SP<CWLSurfaceResource>)> fn);
|
SP<CWLSurfaceResource> findFirstPreorder(std::function<bool(SP<CWLSurfaceResource>)> fn);
|
||||||
|
SP<CWLSurfaceResource> findWithCM();
|
||||||
void presentFeedback(const Time::steady_tp& when, PHLMONITOR pMonitor, bool discarded = false);
|
void presentFeedback(const Time::steady_tp& when, PHLMONITOR pMonitor, bool discarded = false);
|
||||||
void commitState(SSurfaceState& state);
|
void commitState(SSurfaceState& state);
|
||||||
NColorManagement::SImageDescription getPreferredImageDescription();
|
NColorManagement::SImageDescription getPreferredImageDescription();
|
||||||
|
|
|
||||||
|
|
@ -1597,17 +1597,17 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c
|
||||||
tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool canPassHDRSurface = m_renderData.surface.valid() && m_renderData.surface->m_colorManagement.valid() ?
|
const bool isHDRSurface = m_renderData.surface.valid() && m_renderData.surface->m_colorManagement.valid() ? m_renderData.surface->m_colorManagement->isHDR() : false;
|
||||||
m_renderData.surface->m_colorManagement->isHDR() && !m_renderData.surface->m_colorManagement->isWindowsScRGB() :
|
const bool canPassHDRSurface = isHDRSurface && !m_renderData.surface->m_colorManagement->isWindowsScRGB(); // windows scRGB requires CM shader
|
||||||
false; // windows scRGB requires CM shader
|
|
||||||
auto imageDescription = m_renderData.surface.valid() && m_renderData.surface->m_colorManagement.valid() ?
|
auto imageDescription = m_renderData.surface.valid() && m_renderData.surface->m_colorManagement.valid() ?
|
||||||
m_renderData.surface->m_colorManagement->imageDescription() :
|
m_renderData.surface->m_colorManagement->imageDescription() :
|
||||||
(data.cmBackToSRGB ? data.cmBackToSRGBSource->m_imageDescription : SImageDescription{});
|
(data.cmBackToSRGB ? data.cmBackToSRGBSource->m_imageDescription : SImageDescription{});
|
||||||
|
|
||||||
const bool skipCM = !*PENABLECM || !m_cmSupported /* CM unsupported or disabled */
|
const bool skipCM = !*PENABLECM || !m_cmSupported /* CM unsupported or disabled */
|
||||||
|
|| m_renderData.pMonitor->doesNoShaderCM() /* no shader needed */
|
||||||
|| (imageDescription == m_renderData.pMonitor->m_imageDescription && !data.cmBackToSRGB) /* Source and target have the same image description */
|
|| (imageDescription == m_renderData.pMonitor->m_imageDescription && !data.cmBackToSRGB) /* Source and target have the same image description */
|
||||||
|| ((*PPASS == 1 || (*PPASS == 2 && canPassHDRSurface)) && m_renderData.pMonitor->m_activeWorkspace && m_renderData.pMonitor->m_activeWorkspace->m_hasFullscreenWindow &&
|
|| (((*PPASS && canPassHDRSurface) || (*PPASS == 1 && !isHDRSurface)) && m_renderData.pMonitor->inFullscreenMode()) /* Fullscreen window with pass cm enabled */;
|
||||||
m_renderData.pMonitor->m_activeWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN) /* Fullscreen window with pass cm enabled */;
|
|
||||||
|
|
||||||
if (!skipCM && !usingFinalShader && (texType == TEXTURE_RGBA || texType == TEXTURE_RGBX))
|
if (!skipCM && !usingFinalShader && (texType == TEXTURE_RGBA || texType == TEXTURE_RGBX))
|
||||||
shader = &m_shaders->m_shCM;
|
shader = &m_shaders->m_shCM;
|
||||||
|
|
|
||||||
|
|
@ -1485,43 +1485,50 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
|
||||||
static auto PPASS = CConfigValue<Hyprlang::INT>("render:cm_fs_passthrough");
|
static auto PPASS = CConfigValue<Hyprlang::INT>("render:cm_fs_passthrough");
|
||||||
static auto PAUTOHDR = CConfigValue<Hyprlang::INT>("render:cm_auto_hdr");
|
static auto PAUTOHDR = CConfigValue<Hyprlang::INT>("render:cm_auto_hdr");
|
||||||
|
|
||||||
|
static bool needsHDRupdate = false;
|
||||||
|
|
||||||
const bool configuredHDR = (pMonitor->m_cmType == CM_HDR_EDID || pMonitor->m_cmType == CM_HDR);
|
const bool configuredHDR = (pMonitor->m_cmType == CM_HDR_EDID || pMonitor->m_cmType == CM_HDR);
|
||||||
bool wantHDR = configuredHDR;
|
bool wantHDR = configuredHDR;
|
||||||
|
|
||||||
|
const auto FS_WINDOW = pMonitor->inFullscreenMode() ? pMonitor->m_activeWorkspace->getFullscreenWindow() : nullptr;
|
||||||
|
|
||||||
if (pMonitor->supportsHDR()) {
|
if (pMonitor->supportsHDR()) {
|
||||||
// HDR metadata determined by
|
// HDR metadata determined by
|
||||||
|
// HDR scRGB - monitor settings
|
||||||
|
// HDR PQ surface & DS is active - surface settings
|
||||||
// PPASS = 0 monitor settings
|
// PPASS = 0 monitor settings
|
||||||
// PPASS = 1
|
// PPASS = 1
|
||||||
// windowed: monitor settings
|
// windowed: monitor settings
|
||||||
// fullscreen surface: surface settings FIXME: fullscreen SDR surface passthrough - pass degamma, ctm, gamma if needed
|
// fullscreen surface: surface settings FIXME: fullscreen SDR surface passthrough - pass degamma, gamma if needed
|
||||||
// PPASS = 2
|
// PPASS = 2
|
||||||
// windowed: monitor settings
|
// windowed: monitor settings
|
||||||
// fullscreen SDR surface: monitor settings
|
// fullscreen SDR surface: monitor settings
|
||||||
// fullscreen HDR surface: surface settings
|
// fullscreen HDR surface: surface settings
|
||||||
|
|
||||||
bool hdrIsHandled = false;
|
bool hdrIsHandled = false;
|
||||||
if (pMonitor->m_activeWorkspace && pMonitor->m_activeWorkspace->m_hasFullscreenWindow && pMonitor->m_activeWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN) {
|
if (FS_WINDOW) {
|
||||||
const auto WINDOW = pMonitor->m_activeWorkspace->getFullscreenWindow();
|
const auto ROOT_SURF = FS_WINDOW->m_wlSurface->resource();
|
||||||
const auto ROOT_SURF = WINDOW->m_wlSurface->resource();
|
const auto SURF = ROOT_SURF->findWithCM();
|
||||||
const auto SURF =
|
|
||||||
ROOT_SURF->findFirstPreorder([ROOT_SURF](SP<CWLSurfaceResource> surf) { return surf->m_colorManagement.valid() && surf->extends() == ROOT_SURF->extends(); });
|
|
||||||
|
|
||||||
// we have a surface with image description
|
// we have a surface with image description
|
||||||
if (SURF && SURF->m_colorManagement.valid() && SURF->m_colorManagement->hasImageDescription()) {
|
if (SURF && SURF->m_colorManagement.valid() && SURF->m_colorManagement->hasImageDescription()) {
|
||||||
const bool surfaceIsHDR = SURF->m_colorManagement->isHDR();
|
const bool surfaceIsHDR = SURF->m_colorManagement->isHDR();
|
||||||
if (*PPASS == 1 || (*PPASS == 2 && surfaceIsHDR)) {
|
if (!SURF->m_colorManagement->isWindowsScRGB() && (*PPASS == 1 || ((*PPASS == 2 || !pMonitor->m_lastScanout.expired()) && surfaceIsHDR))) {
|
||||||
// passthrough
|
// passthrough
|
||||||
bool needsHdrMetadataUpdate = SURF->m_colorManagement->needsHdrMetadataUpdate() || pMonitor->m_previousFSWindow != WINDOW;
|
bool needsHdrMetadataUpdate = SURF->m_colorManagement->needsHdrMetadataUpdate() || pMonitor->m_previousFSWindow != FS_WINDOW || needsHDRupdate;
|
||||||
if (SURF->m_colorManagement->needsHdrMetadataUpdate())
|
if (SURF->m_colorManagement->needsHdrMetadataUpdate()) {
|
||||||
|
Debug::log(INFO, "[CM] Recreating HDR metadata for surface");
|
||||||
SURF->m_colorManagement->setHDRMetadata(createHDRMetadata(SURF->m_colorManagement->imageDescription(), pMonitor));
|
SURF->m_colorManagement->setHDRMetadata(createHDRMetadata(SURF->m_colorManagement->imageDescription(), pMonitor));
|
||||||
if (needsHdrMetadataUpdate)
|
}
|
||||||
|
if (needsHdrMetadataUpdate) {
|
||||||
|
Debug::log(INFO, "[CM] Updating HDR metadata from surface");
|
||||||
pMonitor->m_output->state->setHDRMetadata(SURF->m_colorManagement->hdrMetadata());
|
pMonitor->m_output->state->setHDRMetadata(SURF->m_colorManagement->hdrMetadata());
|
||||||
|
}
|
||||||
hdrIsHandled = true;
|
hdrIsHandled = true;
|
||||||
|
needsHDRupdate = false;
|
||||||
} else if (*PAUTOHDR && surfaceIsHDR)
|
} else if (*PAUTOHDR && surfaceIsHDR)
|
||||||
wantHDR = true; // auto-hdr: hdr on
|
wantHDR = true; // auto-hdr: hdr on
|
||||||
}
|
}
|
||||||
|
|
||||||
pMonitor->m_previousFSWindow = WINDOW;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hdrIsHandled) {
|
if (!hdrIsHandled) {
|
||||||
|
|
@ -1529,11 +1536,15 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
|
||||||
if (*PAUTOHDR && !(pMonitor->inHDR() && configuredHDR)) {
|
if (*PAUTOHDR && !(pMonitor->inHDR() && configuredHDR)) {
|
||||||
// modify or restore monitor image description for auto-hdr
|
// modify or restore monitor image description for auto-hdr
|
||||||
// FIXME ok for now, will need some other logic if monitor image description can be modified some other way
|
// FIXME ok for now, will need some other logic if monitor image description can be modified some other way
|
||||||
pMonitor->applyCMType(wantHDR ? (*PAUTOHDR == 2 ? CM_HDR_EDID : CM_HDR) : pMonitor->m_cmType);
|
const auto targetCM = wantHDR ? (*PAUTOHDR == 2 ? CM_HDR_EDID : CM_HDR) : pMonitor->m_cmType;
|
||||||
|
Debug::log(INFO, "[CM] Auto HDR: changing monitor cm to {}", sc<uint8_t>(targetCM));
|
||||||
|
pMonitor->applyCMType(targetCM);
|
||||||
|
pMonitor->m_previousFSWindow.reset(); // trigger CTM update
|
||||||
}
|
}
|
||||||
|
Debug::log(INFO, wantHDR ? "[CM] Updating HDR metadata from monitor" : "[CM] Restoring SDR mode");
|
||||||
pMonitor->m_output->state->setHDRMetadata(wantHDR ? createHDRMetadata(pMonitor->m_imageDescription, pMonitor) : NO_HDR_METADATA);
|
pMonitor->m_output->state->setHDRMetadata(wantHDR ? createHDRMetadata(pMonitor->m_imageDescription, pMonitor) : NO_HDR_METADATA);
|
||||||
}
|
}
|
||||||
pMonitor->m_previousFSWindow.reset();
|
needsHDRupdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1553,19 +1564,39 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*PCT) {
|
if (*PCT)
|
||||||
if (pMonitor->m_activeWorkspace && pMonitor->m_activeWorkspace->m_hasFullscreenWindow && pMonitor->m_activeWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN) {
|
pMonitor->m_output->state->setContentType(NContentType::toDRM(FS_WINDOW ? FS_WINDOW->getContentType() : CONTENT_TYPE_NONE));
|
||||||
const auto WINDOW = pMonitor->m_activeWorkspace->getFullscreenWindow();
|
|
||||||
pMonitor->m_output->state->setContentType(NContentType::toDRM(WINDOW->getContentType()));
|
if (FS_WINDOW != pMonitor->m_previousFSWindow) {
|
||||||
} else
|
if (!FS_WINDOW || !pMonitor->needsCM() || !pMonitor->canNoShaderCM()) {
|
||||||
pMonitor->m_output->state->setContentType(NContentType::toDRM(CONTENT_TYPE_NONE));
|
if (pMonitor->m_noShaderCTM) {
|
||||||
|
Debug::log(INFO, "[CM] No fullscreen CTM, restoring previous one");
|
||||||
|
pMonitor->m_noShaderCTM = false;
|
||||||
|
pMonitor->m_ctmUpdated = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const auto FS_DESC = pMonitor->getFSImageDescription();
|
||||||
|
if (FS_DESC.has_value()) {
|
||||||
|
Debug::log(INFO, "[CM] Updating fullscreen CTM");
|
||||||
|
pMonitor->m_noShaderCTM = true;
|
||||||
|
const auto mat = FS_DESC->getPrimaries().convertMatrix(pMonitor->m_imageDescription.getPrimaries()).mat();
|
||||||
|
const std::array<float, 9> CTM = {
|
||||||
|
mat[0][0], mat[0][1], mat[0][2], //
|
||||||
|
mat[1][0], mat[1][1], mat[1][2], //
|
||||||
|
mat[2][0], mat[2][1], mat[2][2], //
|
||||||
|
};
|
||||||
|
pMonitor->m_output->state->setCTM(CTM);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMonitor->m_ctmUpdated) {
|
if (pMonitor->m_ctmUpdated && !pMonitor->m_noShaderCTM) {
|
||||||
pMonitor->m_ctmUpdated = false;
|
pMonitor->m_ctmUpdated = false;
|
||||||
pMonitor->m_output->state->setCTM(pMonitor->m_ctm);
|
pMonitor->m_output->state->setCTM(pMonitor->m_ctm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pMonitor->m_previousFSWindow = FS_WINDOW;
|
||||||
|
|
||||||
bool ok = pMonitor->m_state.commit();
|
bool ok = pMonitor->m_state.commit();
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
if (pMonitor->m_inFence.isValid()) {
|
if (pMonitor->m_inFence.isValid()) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue