From ea7768203b0ec8188426a63af50605fee929b0c7 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 18 Mar 2024 22:34:41 +0000 Subject: [PATCH] e --- src/managers/FrameSchedulingManager.cpp | 17 +++++++++-------- src/managers/FrameSchedulingManager.hpp | 6 +++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/managers/FrameSchedulingManager.cpp b/src/managers/FrameSchedulingManager.cpp index 59794498..eb54e4ca 100644 --- a/src/managers/FrameSchedulingManager.cpp +++ b/src/managers/FrameSchedulingManager.cpp @@ -36,7 +36,6 @@ void CFrameSchedulingManager::onFrameNeeded(CMonitor* pMonitor) { return; } - DATA->noVblankTimer = true; onPresent(pMonitor, nullptr); } @@ -52,7 +51,6 @@ void CFrameSchedulingManager::gpuDone(wlr_buffer* pBuffer) { // delayed frame, let's render immediately, our shit will be presented soon // if we finish rendering before the next vblank somehow, kernel will be mad, but oh well - DATA->noVblankTimer = true; g_pHyprRenderer->renderMonitor(DATA->pMonitor); DATA->delayedFrameSubmitted = true; } @@ -97,7 +95,6 @@ void CFrameSchedulingManager::onPresent(CMonitor* pMonitor, wlr_output_event_pre if (DATA->delayedFrameSubmitted) { DATA->delayedFrameSubmitted = false; - DATA->activelyPushing = false; return; } @@ -127,18 +124,22 @@ void CFrameSchedulingManager::onPresent(CMonitor* pMonitor, wlr_output_event_pre } // we can't do this on wayland - if (!wlr_backend_is_wl(pMonitor->output->backend) && !DATA->noVblankTimer && presentationData) { + float msUntilVblank = 0; + + if (presentationData) { const std::chrono::system_clock::time_point LASTVBLANK{std::chrono::duration_cast( std::chrono::seconds{presentationData->when->tv_sec} + std::chrono::nanoseconds{presentationData->when->tv_nsec})}; - const float MSUNTILVBLANK = (presentationData->refresh ? presentationData->refresh / 1000000.0 : pMonitor->refreshRate / 1000.0) - + msUntilVblank = (presentationData->refresh ? presentationData->refresh / 1000000.0 : pMonitor->refreshRate / 1000.0) - std::chrono::duration_cast(std::chrono::system_clock::now() - LASTVBLANK).count(); + } else + msUntilVblank = std::chrono::duration_cast(DATA->nextVblank - std::chrono::system_clock::now()).count(); + + if (msUntilVblank > 0) { wl_event_source_timer_update(DATA->event, 0); - wl_event_source_timer_update(DATA->event, std::floor(MSUNTILVBLANK)); + wl_event_source_timer_update(DATA->event, std::floor(msUntilVblank)); } renderMonitor(DATA); - - DATA->noVblankTimer = false; } CFrameSchedulingManager::SSchedulingData* CFrameSchedulingManager::dataFor(CMonitor* pMonitor) { diff --git a/src/managers/FrameSchedulingManager.hpp b/src/managers/FrameSchedulingManager.hpp index a26aadd4..0ab356ee 100644 --- a/src/managers/FrameSchedulingManager.hpp +++ b/src/managers/FrameSchedulingManager.hpp @@ -43,9 +43,6 @@ class CFrameSchedulingManager { // whether the frame was submitted from gpuDone bool delayedFrameSubmitted = false; - // don't plant a vblank timer - bool noVblankTimer = false; - // we need to render a few full frames at the beginning to catch all buffers int forceFrames = 5; @@ -64,6 +61,9 @@ class CFrameSchedulingManager { // legacy scheduler: for backends that do not send us reliable present events // these rely on onFrame bool legacyScheduler = false; + + // next predicted vblank + std::chrono::system_clock::time_point nextVblank; }; std::vector m_vSchedulingData;