diff --git a/src/output/Monitor.cpp b/src/output/Monitor.cpp index f3f271b4b..2ce8885ee 100644 --- a/src/output/Monitor.cpp +++ b/src/output/Monitor.cpp @@ -2188,11 +2188,13 @@ bool CMonitor::attemptDirectScanout() { if (g_pHyprRenderer->explicitSyncSupported() && isMultiGPU()) { auto sync = g_pHyprRenderer->createSyncFDManager(); - if (sync->fd().isValid()) { + if (sync && sync->isValid()) { m_inFence = sync->takeFd(); m_output->state->setExplicitInFence(m_inFence.get()); - } else + } else { + m_inFence.reset(); m_output->state->resetExplicitFences(); // good luck. + } } else m_output->state->resetExplicitFences(); diff --git a/src/output/MonitorFrameScheduler.cpp b/src/output/MonitorFrameScheduler.cpp index 18b09074a..9299bfbbb 100644 --- a/src/output/MonitorFrameScheduler.cpp +++ b/src/output/MonitorFrameScheduler.cpp @@ -129,6 +129,13 @@ void CMonitorFrameScheduler::onFrame() { void CMonitorFrameScheduler::onFinishRender() { m_sync = g_pHyprRenderer->createSyncFDManager(); // this destroys the old sync + if (!m_sync || !m_sync->isValid()) { + Log::logger->log(Log::ERR, "CMonitorFrameScheduler: explicit sync failed, falling back to frame events"); + m_sync.reset(); + m_renderAtFrame = true; + return; + } + g_pEventLoopManager->doOnReadable(m_sync->fd().duplicate(), [this, self = m_self] { if (!self) // might've gotten destroyed return; diff --git a/src/render/GLRenderer.cpp b/src/render/GLRenderer.cpp index 255e5f84a..1dab5a0b7 100644 --- a/src/render/GLRenderer.cpp +++ b/src/render/GLRenderer.cpp @@ -148,9 +148,17 @@ void CHyprGLRenderer::endRender(const std::function& renderingDoneCallba PMONITOR->m_output->state->setExplicitInFence(PMONITOR->m_inFence.get()); } } else { - Log::logger->log(Log::ERR, "renderer: Explicit sync failed, releasing resources"); + Log::logger->log(Log::ERR, "renderer: Explicit sync failed, falling back to implicit sync"); - m_usedAsyncBuffers.clear(); // release all buffer refs and hope implicit sync works + // Establish an implicit synchronization point without blocking the render loop. + glFlush(); + + if (m_renderMode == RENDER_MODE_NORMAL && PMONITOR) { + PMONITOR->m_inFence.reset(); + PMONITOR->m_output->state->resetExplicitFences(); + } + + m_usedAsyncBuffers.clear(); if (renderingDoneCallback) renderingDoneCallback(); }