From 82baeb5e925bf838ac0fa4e1c613125d3854dafa Mon Sep 17 00:00:00 2001 From: NotPppp1116 <264624490+NotPppp1116@users.noreply.github.com> Date: Thu, 16 Jul 2026 19:12:32 +0100 Subject: [PATCH] render: handle explicit sync fallback safely (#14986) * render: handle explicit sync fallback safely * render: avoid blocking explicit sync fallback * ci: retry flaky Hyprland VM tests * render: avoid blocking explicit sync fallback --------- Co-authored-by: Pppp1116 Co-authored-by: Pppp1116 --- src/output/Monitor.cpp | 6 ++++-- src/output/MonitorFrameScheduler.cpp | 7 +++++++ src/render/GLRenderer.cpp | 12 ++++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) 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(); }