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
|
|
@ -988,8 +988,8 @@ bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
|
|||
static auto PMINRR = CConfigValue<Hyprlang::INT>("cursor:min_refresh_rate");
|
||||
|
||||
// skip scheduling extra frames for fullsreen apps with vrr
|
||||
const bool shouldSkip = m_activeWorkspace && m_activeWorkspace->m_hasFullscreenWindow && m_activeWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN &&
|
||||
(*PNOBREAK == 1 || (*PNOBREAK == 2 && m_activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) && m_output->state->state().adaptiveSync;
|
||||
const bool shouldSkip = inFullscreenMode() && (*PNOBREAK == 1 || (*PNOBREAK == 2 && m_activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) &&
|
||||
m_output->state->state().adaptiveSync;
|
||||
|
||||
// keep requested minimum refresh rate
|
||||
if (shouldSkip && *PMINRR && m_lastPresentationTimer.getMillis() > 1000.0f / *PMINRR) {
|
||||
|
|
@ -1631,24 +1631,27 @@ uint8_t CMonitor::isTearingBlocked(bool full) {
|
|||
}
|
||||
|
||||
if (!*PTEARINGENABLED) {
|
||||
Debug::log(WARN, "Tearing commit requested but the master switch general:allow_tearing is off, ignoring");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_pHyprOpenGL->m_renderData.mouseZoomFactor != 1.0) {
|
||||
Debug::log(WARN, "Tearing commit requested but scale factor is not 1, ignoring");
|
||||
reasons |= TC_ZOOM;
|
||||
if (!full)
|
||||
if (!full) {
|
||||
Debug::log(WARN, "Tearing commit requested but scale factor is not 1, ignoring");
|
||||
return reasons;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_tearingState.canTear) {
|
||||
Debug::log(WARN, "Tearing commit requested but monitor doesn't support it, ignoring");
|
||||
reasons |= TC_SUPPORT;
|
||||
if (!full)
|
||||
if (!full) {
|
||||
Debug::log(WARN, "Tearing commit requested but monitor doesn't support it, ignoring");
|
||||
return reasons;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_solitaryClient.expired()) {
|
||||
|
|
@ -1671,6 +1674,7 @@ bool CMonitor::updateTearing() {
|
|||
uint16_t CMonitor::isDSBlocked(bool full) {
|
||||
uint16_t reasons = 0;
|
||||
static auto PDIRECTSCANOUT = CConfigValue<Hyprlang::INT>("render:direct_scanout");
|
||||
static auto PPASS = CConfigValue<Hyprlang::INT>("render:cm_fs_passthrough");
|
||||
|
||||
if (*PDIRECTSCANOUT == 0) {
|
||||
reasons |= DS_BLOCK_USER;
|
||||
|
|
@ -1734,8 +1738,14 @@ uint16_t CMonitor::isDSBlocked(bool full) {
|
|||
|
||||
// we can't scanout shm buffers.
|
||||
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;
|
||||
if (!full)
|
||||
return reasons;
|
||||
}
|
||||
|
||||
if (!canNoShaderCM() && (!inHDR() || (PSURFACE->m_colorManagement.valid() && PSURFACE->m_colorManagement->isWindowsScRGB())) && *PPASS != 1)
|
||||
reasons |= DS_BLOCK_CM;
|
||||
|
||||
return reasons;
|
||||
}
|
||||
|
|
@ -1935,6 +1945,52 @@ bool CMonitor::inHDR() {
|
|||
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) {
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -229,8 +229,9 @@ class CMonitor {
|
|||
DS_BLOCK_DMA = (1 << 10),
|
||||
DS_BLOCK_TEARING = (1 << 11),
|
||||
DS_BLOCK_FAILED = (1 << 12),
|
||||
DS_BLOCK_CM = (1 << 13),
|
||||
|
||||
DS_CHECKS_COUNT = 13,
|
||||
DS_CHECKS_COUNT = 14,
|
||||
};
|
||||
|
||||
// keep in sync with HyprCtl
|
||||
|
|
@ -273,56 +274,66 @@ class CMonitor {
|
|||
};
|
||||
|
||||
// methods
|
||||
void onConnect(bool noRule);
|
||||
void onDisconnect(bool destroy = false);
|
||||
void applyCMType(eCMType cmType);
|
||||
bool applyMonitorRule(SMonitorRule* pMonitorRule, bool force = false);
|
||||
void addDamage(const pixman_region32_t* rg);
|
||||
void addDamage(const CRegion& rg);
|
||||
void addDamage(const CBox& box);
|
||||
bool shouldSkipScheduleFrameOnMouseEvent();
|
||||
void setMirror(const std::string&);
|
||||
bool isMirror();
|
||||
bool matchesStaticSelector(const std::string& selector) const;
|
||||
float getDefaultScale();
|
||||
void changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false);
|
||||
void changeWorkspace(const WORKSPACEID& id, bool internal = false, bool noMouseMove = false, bool noFocus = false);
|
||||
void setSpecialWorkspace(const PHLWORKSPACE& pWorkspace);
|
||||
void setSpecialWorkspace(const WORKSPACEID& id);
|
||||
void moveTo(const Vector2D& pos);
|
||||
Vector2D middle();
|
||||
void updateMatrix();
|
||||
WORKSPACEID activeWorkspaceID();
|
||||
WORKSPACEID activeSpecialWorkspaceID();
|
||||
CBox logicalBox();
|
||||
void scheduleDone();
|
||||
uint16_t isSolitaryBlocked(bool full = false);
|
||||
void recheckSolitary();
|
||||
uint8_t isTearingBlocked(bool full = false);
|
||||
bool updateTearing();
|
||||
uint16_t isDSBlocked(bool full = false);
|
||||
bool attemptDirectScanout();
|
||||
void setCTM(const Mat3x3& ctm);
|
||||
void onCursorMovedOnMonitor();
|
||||
void setDPMS(bool on);
|
||||
void onConnect(bool noRule);
|
||||
void onDisconnect(bool destroy = false);
|
||||
void applyCMType(eCMType cmType);
|
||||
bool applyMonitorRule(SMonitorRule* pMonitorRule, bool force = false);
|
||||
void addDamage(const pixman_region32_t* rg);
|
||||
void addDamage(const CRegion& rg);
|
||||
void addDamage(const CBox& box);
|
||||
bool shouldSkipScheduleFrameOnMouseEvent();
|
||||
void setMirror(const std::string&);
|
||||
bool isMirror();
|
||||
bool matchesStaticSelector(const std::string& selector) const;
|
||||
float getDefaultScale();
|
||||
void changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false);
|
||||
void changeWorkspace(const WORKSPACEID& id, bool internal = false, bool noMouseMove = false, bool noFocus = false);
|
||||
void setSpecialWorkspace(const PHLWORKSPACE& pWorkspace);
|
||||
void setSpecialWorkspace(const WORKSPACEID& id);
|
||||
void moveTo(const Vector2D& pos);
|
||||
Vector2D middle();
|
||||
void updateMatrix();
|
||||
WORKSPACEID activeWorkspaceID();
|
||||
WORKSPACEID activeSpecialWorkspaceID();
|
||||
CBox logicalBox();
|
||||
void scheduleDone();
|
||||
uint16_t isSolitaryBlocked(bool full = false);
|
||||
void recheckSolitary();
|
||||
uint8_t isTearingBlocked(bool full = false);
|
||||
bool updateTearing();
|
||||
uint16_t isDSBlocked(bool full = false);
|
||||
bool attemptDirectScanout();
|
||||
void setCTM(const Mat3x3& ctm);
|
||||
void onCursorMovedOnMonitor();
|
||||
void setDPMS(bool on);
|
||||
|
||||
void debugLastPresentation(const std::string& message);
|
||||
void debugLastPresentation(const std::string& message);
|
||||
|
||||
bool supportsWideColor();
|
||||
bool supportsHDR();
|
||||
float minLuminance(float defaultValue = 0);
|
||||
int maxLuminance(int defaultValue = 80);
|
||||
int maxAvgLuminance(int defaultValue = 80);
|
||||
bool supportsWideColor();
|
||||
bool supportsHDR();
|
||||
float minLuminance(float defaultValue = 0);
|
||||
int maxLuminance(int defaultValue = 80);
|
||||
int maxAvgLuminance(int defaultValue = 80);
|
||||
|
||||
bool wantsWideColor();
|
||||
bool wantsHDR();
|
||||
bool wantsWideColor();
|
||||
bool wantsHDR();
|
||||
|
||||
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_renderingInitPassed = false;
|
||||
WP<CWindow> m_previousFSWindow;
|
||||
NColorManagement::SImageDescription m_imageDescription;
|
||||
bool m_noShaderCTM = false; // sets drm CTM, restore needed
|
||||
|
||||
// For the list lookup
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue