renderer: allow tearing with DS with invisible cursors (#13155)
This commit is contained in:
parent
cfbbfb591a
commit
9f9dbb0dc5
5 changed files with 27 additions and 22 deletions
|
|
@ -144,13 +144,13 @@ 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\"", "\"CM\"",
|
"\"CANDIDATE\"", "\"SURFACE\"", "\"TRANSFORM\"", "\"DMA\"", "\"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", "color management",
|
"missing candidate", "invalid surface", "surface transformations", "invalid buffer", "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) {
|
||||||
|
|
@ -173,14 +173,13 @@ std::string CHyprCtl::getDSBlockedReason(Hyprutils::Memory::CSharedPointer<CMoni
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::array<const char*, CMonitor::TC_CHECKS_COUNT> TEARING_REASONS_JSON = {
|
const std::array<const char*, CMonitor::TC_CHECKS_COUNT> TEARING_REASONS_JSON = {
|
||||||
"\"UNKNOWN\"", "\"NOT_TORN\"", "\"USER\"", "\"ZOOM\"", "\"SUPPORT\"", "\"CANDIDATE\"", "\"WINDOW\"",
|
"\"UNKNOWN\"", "\"NOT_TORN\"", "\"USER\"", "\"ZOOM\"", "\"SUPPORT\"", "\"CANDIDATE\"", "\"WINDOW\"", "\"HW_CURSOR\"",
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::array<const char*, CMonitor::TC_CHECKS_COUNT> TEARING_REASONS_TEXT = {
|
const std::array<const char*, CMonitor::TC_CHECKS_COUNT> TEARING_REASONS_TEXT = {"unknown reason", "next frame is not torn", "user settings", "zoom",
|
||||||
"unknown reason", "next frame is not torn", "user settings", "zoom", "not supported by monitor", "missing candidate", "window settings",
|
"not supported by monitor", "missing candidate", "window settings", "hw cursor"};
|
||||||
};
|
|
||||||
|
|
||||||
std::string CHyprCtl::getTearingBlockedReason(Hyprutils::Memory::CSharedPointer<CMonitor> m, eHyprCtlOutputFormat format) {
|
std::string CHyprCtl::getTearingBlockedReason(Hyprutils::Memory::CSharedPointer<CMonitor> m, eHyprCtlOutputFormat format) {
|
||||||
const auto reasons = m->isTearingBlocked(true);
|
const auto reasons = m->isTearingBlocked(true);
|
||||||
if (!reasons || (reasons == CMonitor::TC_NOT_TORN && m->m_tearingState.activelyTearing))
|
if (!reasons || (reasons == CMonitor::TC_NOT_TORN && m->m_tearingState.activelyTearing))
|
||||||
return "null";
|
return "null";
|
||||||
|
|
|
||||||
|
|
@ -1724,6 +1724,10 @@ uint8_t CMonitor::isTearingBlocked(bool full) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove this when kernel allows tearing + hw cursor updated
|
||||||
|
if (g_pPointerManager->hasVisibleHWCursor(m_self.lock()))
|
||||||
|
reasons |= TC_HW_CURSOR;
|
||||||
|
|
||||||
if (m_solitaryClient.expired()) {
|
if (m_solitaryClient.expired()) {
|
||||||
reasons |= TC_CANDIDATE;
|
reasons |= TC_CANDIDATE;
|
||||||
return reasons;
|
return reasons;
|
||||||
|
|
@ -1765,12 +1769,6 @@ uint16_t CMonitor::isDSBlocked(bool full) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_tearingState.activelyTearing) {
|
|
||||||
reasons |= DS_BLOCK_TEARING;
|
|
||||||
if (!full)
|
|
||||||
return reasons;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_mirrors.empty() || isMirror()) {
|
if (!m_mirrors.empty() || isMirror()) {
|
||||||
reasons |= DS_BLOCK_MIRROR;
|
reasons |= DS_BLOCK_MIRROR;
|
||||||
if (!full)
|
if (!full)
|
||||||
|
|
@ -1862,7 +1860,7 @@ bool CMonitor::attemptDirectScanout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//#TODO this entire bit is bootleg deluxe, above bit is to not make vrr go down the drain, returning early here means fifo gets forever locked.
|
//#TODO this entire bit is bootleg deluxe, above bit is to not make vrr go down the drain, returning early here means fifo gets forever locked.
|
||||||
if (PSURFACE->m_fifo && *PSAMEFIFO)
|
if (PSURFACE->m_fifo && !m_tearingState.activelyTearing && *PSAMEFIFO)
|
||||||
PSURFACE->m_stateQueue.unlockFirst(LOCK_REASON_FIFO);
|
PSURFACE->m_stateQueue.unlockFirst(LOCK_REASON_FIFO);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -233,9 +233,8 @@ class CMonitor {
|
||||||
DS_BLOCK_SURFACE = (1 << 8),
|
DS_BLOCK_SURFACE = (1 << 8),
|
||||||
DS_BLOCK_TRANSFORM = (1 << 9),
|
DS_BLOCK_TRANSFORM = (1 << 9),
|
||||||
DS_BLOCK_DMA = (1 << 10),
|
DS_BLOCK_DMA = (1 << 10),
|
||||||
DS_BLOCK_TEARING = (1 << 11),
|
DS_BLOCK_FAILED = (1 << 11),
|
||||||
DS_BLOCK_FAILED = (1 << 12),
|
DS_BLOCK_CM = (1 << 12),
|
||||||
DS_BLOCK_CM = (1 << 13),
|
|
||||||
|
|
||||||
DS_CHECKS_COUNT = 14,
|
DS_CHECKS_COUNT = 14,
|
||||||
};
|
};
|
||||||
|
|
@ -276,8 +275,9 @@ class CMonitor {
|
||||||
TC_SUPPORT = (1 << 4),
|
TC_SUPPORT = (1 << 4),
|
||||||
TC_CANDIDATE = (1 << 5),
|
TC_CANDIDATE = (1 << 5),
|
||||||
TC_WINDOW = (1 << 6),
|
TC_WINDOW = (1 << 6),
|
||||||
|
TC_HW_CURSOR = (1 << 7),
|
||||||
|
|
||||||
TC_CHECKS_COUNT = 7,
|
TC_CHECKS_COUNT = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,10 @@ void CPointerManager::lockSoftwareForMonitor(PHLMONITOR mon) {
|
||||||
void CPointerManager::unlockSoftwareForMonitor(PHLMONITOR mon) {
|
void CPointerManager::unlockSoftwareForMonitor(PHLMONITOR mon) {
|
||||||
auto const state = stateFor(mon);
|
auto const state = stateFor(mon);
|
||||||
state->softwareLocks--;
|
state->softwareLocks--;
|
||||||
if (state->softwareLocks < 0)
|
if (state->softwareLocks < 0) {
|
||||||
state->softwareLocks = 0;
|
state->softwareLocks = 0;
|
||||||
|
Log::logger->log(Log::WARN, "Unlocking SW for monitor while it's not locked");
|
||||||
|
}
|
||||||
|
|
||||||
if (state->softwareLocks == 0)
|
if (state->softwareLocks == 0)
|
||||||
updateCursorBackend();
|
updateCursorBackend();
|
||||||
|
|
@ -81,7 +83,12 @@ void CPointerManager::unlockSoftwareForMonitor(PHLMONITOR mon) {
|
||||||
|
|
||||||
bool CPointerManager::softwareLockedFor(PHLMONITOR mon) {
|
bool CPointerManager::softwareLockedFor(PHLMONITOR mon) {
|
||||||
auto const state = stateFor(mon);
|
auto const state = stateFor(mon);
|
||||||
return state->softwareLocks > 0 || state->hardwareFailed;
|
return state->softwareLocks > 0 || (state->hardwareFailed && hasCursor() && g_pHyprRenderer->shouldRenderCursor());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPointerManager::hasVisibleHWCursor(PHLMONITOR pMonitor) {
|
||||||
|
auto const state = stateFor(pMonitor);
|
||||||
|
return state->softwareLocks == 0 && !state->hardwareFailed && hasCursor() && g_pHyprRenderer->shouldRenderCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2D CPointerManager::position() {
|
Vector2D CPointerManager::position() {
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ class CPointerManager {
|
||||||
void lockSoftwareAll();
|
void lockSoftwareAll();
|
||||||
void unlockSoftwareAll();
|
void unlockSoftwareAll();
|
||||||
bool softwareLockedFor(PHLMONITOR pMonitor);
|
bool softwareLockedFor(PHLMONITOR pMonitor);
|
||||||
|
bool hasVisibleHWCursor(PHLMONITOR pMonitor);
|
||||||
|
|
||||||
void renderSoftwareCursorsFor(PHLMONITOR pMonitor, const Time::steady_tp& now, CRegion& damage /* logical */, std::optional<Vector2D> overridePos = {} /* monitor-local */,
|
void renderSoftwareCursorsFor(PHLMONITOR pMonitor, const Time::steady_tp& now, CRegion& damage /* logical */, std::optional<Vector2D> overridePos = {} /* monitor-local */,
|
||||||
bool forceRender = false);
|
bool forceRender = false);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue