mirror of
https://github.com/hyprwm/Hyprland
synced 2026-05-07 05:38:11 +02:00
scheduler: keep a strong monitor ref in frame callbacks
This commit is contained in:
parent
0647b5449c
commit
d5b00bbc17
1 changed files with 24 additions and 22 deletions
|
|
@ -17,21 +17,21 @@ bool CMonitorFrameScheduler::newSchedulingEnabled() {
|
|||
}
|
||||
|
||||
void CMonitorFrameScheduler::onSyncFired() {
|
||||
|
||||
if (!newSchedulingEnabled())
|
||||
const auto PMONITOR = m_monitor.lock();
|
||||
if (!PMONITOR || !newSchedulingEnabled())
|
||||
return;
|
||||
|
||||
// Sync fired: reset submitted state, set as rendered. Check the last render time. If we are running
|
||||
// late, we will instantly render here.
|
||||
|
||||
if (std::chrono::duration_cast<std::chrono::microseconds>(hrc::now() - m_lastRenderBegun).count() / 1000.F < 1000.F / m_monitor->m_refreshRate) {
|
||||
if (std::chrono::duration_cast<std::chrono::microseconds>(hrc::now() - m_lastRenderBegun).count() / 1000.F < 1000.F / PMONITOR->m_refreshRate) {
|
||||
// we are in. Frame is valid. We can just render as normal.
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> onSyncFired, didn't miss.", m_monitor->m_name);
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> onSyncFired, didn't miss.", PMONITOR->m_name);
|
||||
m_renderAtFrame = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> onSyncFired, missed.", m_monitor->m_name);
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> onSyncFired, missed.", PMONITOR->m_name);
|
||||
|
||||
// we are out. The frame is taking too long to render. Begin rendering immediately, but don't commit yet.
|
||||
m_pendingThird = true;
|
||||
|
|
@ -43,7 +43,7 @@ void CMonitorFrameScheduler::onSyncFired() {
|
|||
// FIXME: this is horrible. "renderMonitor" should not be able to do that.
|
||||
auto self = m_self;
|
||||
|
||||
g_pHyprRenderer->renderMonitor(m_monitor.lock(), false);
|
||||
g_pHyprRenderer->renderMonitor(PMONITOR, false);
|
||||
|
||||
if (!self)
|
||||
return;
|
||||
|
|
@ -52,21 +52,22 @@ void CMonitorFrameScheduler::onSyncFired() {
|
|||
}
|
||||
|
||||
void CMonitorFrameScheduler::onPresented() {
|
||||
if (!newSchedulingEnabled())
|
||||
const auto PMONITOR = m_monitor.lock();
|
||||
if (!PMONITOR || !newSchedulingEnabled())
|
||||
return;
|
||||
|
||||
if (!m_pendingThird)
|
||||
return;
|
||||
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> onPresented, missed, committing pending.", m_monitor->m_name);
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> onPresented, missed, committing pending.", PMONITOR->m_name);
|
||||
|
||||
m_pendingThird = false;
|
||||
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> onPresented, missed, committing pending at the earliest convenience.", m_monitor->m_name);
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> onPresented, missed, committing pending at the earliest convenience.", PMONITOR->m_name);
|
||||
|
||||
m_pendingThird = false;
|
||||
|
||||
g_pEventLoopManager->doLater([m = m_monitor.lock()] {
|
||||
g_pEventLoopManager->doLater([m = PMONITOR] {
|
||||
if (!m)
|
||||
return;
|
||||
g_pHyprRenderer->commitPendingAndDoExplicitSync(m); // commit the pending frame. If it didn't fire yet (is not rendered) it doesn't matter. Syncs will wait.
|
||||
|
|
@ -79,35 +80,36 @@ void CMonitorFrameScheduler::onPresented() {
|
|||
}
|
||||
|
||||
void CMonitorFrameScheduler::onFrame() {
|
||||
if (!canRender())
|
||||
const auto PMONITOR = m_monitor.lock();
|
||||
if (!PMONITOR || !canRender())
|
||||
return;
|
||||
|
||||
m_monitor->recheckSolitary();
|
||||
PMONITOR->recheckSolitary();
|
||||
|
||||
m_monitor->m_tearingState.busy = false;
|
||||
PMONITOR->m_tearingState.busy = false;
|
||||
|
||||
if (m_monitor->m_tearingState.activelyTearing && m_monitor->m_solitaryClient.lock() /* can be invalidated by a recheck */) {
|
||||
if (PMONITOR->m_tearingState.activelyTearing && PMONITOR->m_solitaryClient.lock() /* can be invalidated by a recheck */) {
|
||||
|
||||
if (!m_monitor->m_tearingState.frameScheduledWhileBusy)
|
||||
if (!PMONITOR->m_tearingState.frameScheduledWhileBusy)
|
||||
return; // we did not schedule a frame yet to be displayed, but we are tearing. Why render?
|
||||
|
||||
m_monitor->m_tearingState.nextRenderTorn = true;
|
||||
m_monitor->m_tearingState.frameScheduledWhileBusy = false;
|
||||
PMONITOR->m_tearingState.nextRenderTorn = true;
|
||||
PMONITOR->m_tearingState.frameScheduledWhileBusy = false;
|
||||
}
|
||||
|
||||
if (!newSchedulingEnabled()) {
|
||||
m_monitor->m_lastPresentationTimer.reset();
|
||||
PMONITOR->m_lastPresentationTimer.reset();
|
||||
|
||||
g_pHyprRenderer->renderMonitor(m_monitor.lock());
|
||||
g_pHyprRenderer->renderMonitor(PMONITOR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_renderAtFrame) {
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> frame event, but m_renderAtFrame = false.", m_monitor->m_name);
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> frame event, but m_renderAtFrame = false.", PMONITOR->m_name);
|
||||
return;
|
||||
}
|
||||
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> frame event, render = true, rendering normally.", m_monitor->m_name);
|
||||
Log::logger->log(Log::TRACE, "CMonitorFrameScheduler: {} -> frame event, render = true, rendering normally.", PMONITOR->m_name);
|
||||
|
||||
m_lastRenderBegun = hrc::now();
|
||||
|
||||
|
|
@ -115,7 +117,7 @@ void CMonitorFrameScheduler::onFrame() {
|
|||
// FIXME: this is horrible. "renderMonitor" should not be able to do that.
|
||||
auto self = m_self;
|
||||
|
||||
g_pHyprRenderer->renderMonitor(m_monitor.lock());
|
||||
g_pHyprRenderer->renderMonitor(PMONITOR);
|
||||
|
||||
if (!self)
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue