From 2991eb79348cdf606dd64686ad79ea9339102cd8 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Wed, 29 Apr 2026 16:23:23 +0200 Subject: [PATCH] deadline: account for vrr, vfr and tearing. account for vrr, vfr, and tearing. --- meta/hl.meta.lua | 4 ++++ src/helpers/Monitor.cpp | 7 +++++-- src/render/GLRenderer.cpp | 8 +++----- src/render/Renderer.cpp | 22 +++++++++++----------- src/render/Renderer.hpp | 6 +----- 5 files changed, 24 insertions(+), 23 deletions(-) diff --git a/meta/hl.meta.lua b/meta/hl.meta.lua index 4e31d4a34..b78ef4a66 100644 --- a/meta/hl.meta.lua +++ b/meta/hl.meta.lua @@ -148,6 +148,8 @@ ---| "ecosystem.enforce_permissions" ---| "ecosystem.no_donation_nag" ---| "ecosystem.no_update_news" +---| "experimental.deadline_client_buffer" +---| "experimental.deadline_main_buffer" ---| "experimental.wp_cm_1_2" ---| "general.allow_tearing" ---| "general.border_size" @@ -957,6 +959,8 @@ hl = {} ---@field ['ecosystem.enforce_permissions'] boolean ---@field ['ecosystem.no_donation_nag'] boolean ---@field ['ecosystem.no_update_news'] boolean +---@field ['experimental.deadline_client_buffer'] boolean +---@field ['experimental.deadline_main_buffer'] boolean ---@field ['experimental.wp_cm_1_2'] boolean ---@field ['general.allow_tearing'] boolean ---@field ['general.border_size'] integer|boolean diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index fdb52b3ca..678b3e4eb 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -158,8 +158,11 @@ void CMonitor::onConnect(bool noRule) { }); } - auto minVBlankInterval = std::chrono::duration_cast(std::chrono::duration(1.0 / m_refreshRate)); - m_estimatedNextVblank = (ts ? Time::fromTimespec(ts) : Time::steadyNow()) + minVBlankInterval; + if (m_pendingFrame) { // if no pending frame, VFR etc we cant estimate this. + auto minVBlankInterval = std::chrono::duration_cast(std::chrono::duration(1.0 / m_refreshRate)); + m_estimatedNextVblank = (ts ? Time::fromTimespec(ts) + minVBlankInterval : Time::steadyNow()) + minVBlankInterval; + } else + m_estimatedNextVblank = std::nullopt; m_frameScheduler->onPresented(); diff --git a/src/render/GLRenderer.cpp b/src/render/GLRenderer.cpp index 13e80baa1..1e1640db6 100644 --- a/src/render/GLRenderer.cpp +++ b/src/render/GLRenderer.cpp @@ -50,7 +50,7 @@ void CHyprGLRenderer::initRender() { bool CHyprGLRenderer::initRenderBuffer(SP buffer, uint32_t fmt) { try { - m_currentRenderbuffer = getOrCreateRenderbuffer(m_currentBuffer.buffer, fmt); + m_currentRenderbuffer = getOrCreateRenderbuffer(m_currentBuffer, fmt); } catch (std::exception& e) { Log::logger->log(Log::ERR, "getOrCreateRenderbuffer failed for {}", NFormatUtils::drmFormatName(fmt)); return false; @@ -72,8 +72,6 @@ bool CHyprGLRenderer::beginFullFakeRenderInternal(PHLMONITOR pMonitor, CRegion& } bool CHyprGLRenderer::beginRenderInternal(PHLMONITOR pMonitor, CRegion& damage, bool simple) { - - m_currentBuffer.fence = DRM::exportFence(m_currentBuffer.buffer->dmabuf().fds[0]); m_currentRenderbuffer->bind(); if (simple) g_pHyprOpenGL->beginSimple(pMonitor, damage, m_currentRenderbuffer); @@ -93,7 +91,7 @@ void CHyprGLRenderer::endRender(const std::function& renderingDoneCallba if (m_currentRenderbuffer) m_currentRenderbuffer->unbind(); m_currentRenderbuffer = nullptr; - m_currentBuffer = {}; + m_currentBuffer = nullptr; }); if (m_renderMode != RENDER_MODE_TO_BUFFER_READ_ONLY) @@ -108,7 +106,7 @@ void CHyprGLRenderer::endRender(const std::function& renderingDoneCallba return; if (m_renderMode == RENDER_MODE_NORMAL) - PMONITOR->m_output->state->setBuffer(m_currentBuffer.buffer); + PMONITOR->m_output->state->setBuffer(m_currentBuffer); if (!explicitSyncSupported()) { Log::logger->log(Log::TRACE, "renderer: Explicit sync unsupported, falling back to implicit in endRender"); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 0ecfd8d83..5f8cc614a 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1655,17 +1655,17 @@ bool IHyprRenderer::beginRender(PHLMONITOR pMonitor, CRegion& damage, eRenderMod int bufferAge = 0; if (!buffer) { - m_currentBuffer.buffer = pMonitor->m_output->swapchain->next(&bufferAge); - if (!m_currentBuffer.buffer) { + m_currentBuffer = pMonitor->m_output->swapchain->next(&bufferAge); + if (!m_currentBuffer) { Log::logger->log(Log::ERR, "Failed to acquire swapchain buffer for {}", pMonitor->m_name); return false; } } else - m_currentBuffer.buffer = buffer; + m_currentBuffer = buffer; initRender(); - if (!initRenderBuffer(m_currentBuffer.buffer, pMonitor->m_output->state->state().drmFormat)) { + if (!initRenderBuffer(m_currentBuffer, pMonitor->m_output->state->state().drmFormat)) { Log::logger->log(Log::ERR, "failed to start a render pass for output {}, no RBO could be obtained", pMonitor->m_name); return false; } @@ -1916,6 +1916,8 @@ void IHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) { const float ZOOMFACTOR = pMonitor->m_cursorZoom->value(); + auto cleanup = CScopeGuard([pMonitor]() { pMonitor->m_estimatedNextVblank = std::nullopt; }); + if (pMonitor->m_pixelSize.x < 1 || pMonitor->m_pixelSize.y < 1) { Log::logger->log(Log::ERR, "Refusing to render a monitor because of an invalid pixel size: {}", pMonitor->m_pixelSize); return; @@ -2350,15 +2352,13 @@ bool IHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { handleFullscreenSettings(pMonitor); static const auto DEADLINE = CConfigValue("experimental:deadline_main_buffer"); - - if (*DEADLINE) { + if (*DEADLINE && m_currentBuffer) { auto deadline = pMonitor->isMultiGPU() || pMonitor->m_vrrActive || pMonitor->m_tearingState.activelyTearing || !pMonitor->m_estimatedNextVblank.has_value() ? Time::steadyNow() + std::chrono::microseconds(100) : - pMonitor->m_estimatedNextVblank; - if (deadline) { - DRM::setDeadline(deadline.value(), m_currentBuffer.fence); - pMonitor->m_estimatedNextVblank = std::nullopt; - } + pMonitor->m_estimatedNextVblank.value(); + auto fence = DRM::exportFence(m_currentBuffer->dmabuf().fds[0]); + + DRM::setDeadline(deadline, fence); } bool ok = pMonitor->m_state.commit(); diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 2a0579184..fff08a211 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -276,11 +276,7 @@ namespace Render { bool m_intel = false; bool m_software = false; bool m_mgpu = false; - - struct SBuffer { - SP buffer = nullptr; - Hyprutils::OS::CFileDescriptor fence; - } m_currentBuffer; + SP m_currentBuffer = nullptr; struct { bool hiddenOnTouch = false;