renderer: avoid races with commited frame

if we have pending scanout a frame might be waiting on the sync and
racing the buffer drops from said commit. try to avoid that from
occuring.
This commit is contained in:
Tom Englund 2025-11-15 20:28:31 +01:00
parent 6aa69c766e
commit 2462f33fdf
2 changed files with 6 additions and 2 deletions

View file

@ -16,7 +16,7 @@ bool CMonitorFrameScheduler::newSchedulingEnabled() {
void CMonitorFrameScheduler::onSyncFired() { void CMonitorFrameScheduler::onSyncFired() {
if (!newSchedulingEnabled()) if (!newSchedulingEnabled() || m_skipThird)
return; return;
// Sync fired: reset submitted state, set as rendered. Check the last render time. If we are running // Sync fired: reset submitted state, set as rendered. Check the last render time. If we are running
@ -58,6 +58,8 @@ void CMonitorFrameScheduler::onPresented() {
if (!newSchedulingEnabled()) if (!newSchedulingEnabled())
return; return;
m_skipThird = false;
if (!m_pendingThird) if (!m_pendingThird)
return; return;
@ -73,6 +75,7 @@ void CMonitorFrameScheduler::onPresented() {
} }
g_pHyprRenderer->commitPendingAndDoExplicitSync(mon, true); // commit the pending frame. If it didn't fire yet (is not rendered) it doesn't matter. Syncs will wait. g_pHyprRenderer->commitPendingAndDoExplicitSync(mon, true); // commit the pending frame. If it didn't fire yet (is not rendered) it doesn't matter. Syncs will wait.
m_skipThird = true;
// schedule a frame: we might have some missed damage, which got cleared due to the above commit. // schedule a frame: we might have some missed damage, which got cleared due to the above commit.
// TODO: this is not always necessary, but doesn't hurt in general. We likely won't hit this if nothing's happening anyways. // TODO: this is not always necessary, but doesn't hurt in general. We likely won't hit this if nothing's happening anyways.
@ -109,7 +112,7 @@ void CMonitorFrameScheduler::onFrame() {
// FIXME: this is horrible. "renderMonitor" should not be able to do that. // FIXME: this is horrible. "renderMonitor" should not be able to do that.
auto self = m_self; auto self = m_self;
g_pHyprRenderer->renderMonitor(m_monitor.lock(), true, m_renderAtFrame); g_pHyprRenderer->renderMonitor(m_monitor.lock(), true, (m_renderAtFrame && !m_pendingThird));
if (!self) if (!self)
return; return;

View file

@ -28,6 +28,7 @@ class CMonitorFrameScheduler {
bool m_renderAtFrame = true; bool m_renderAtFrame = true;
bool m_pendingThird = false; bool m_pendingThird = false;
bool m_skipThird = false;
hrc::time_point m_lastRenderBegun; hrc::time_point m_lastRenderBegun;
PHLMONITORREF m_monitor; PHLMONITORREF m_monitor;