From b8084b4f0235237d88566adfd3409cb1cd7e7595 Mon Sep 17 00:00:00 2001 From: popcoder565 <339285150+popcoder565@users.noreply.github.com> Date: Thu, 8 Oct 2026 04:29:57 -0400 Subject: [PATCH] fix(videoout): pace vblanks with a high-resolution timer On Windows the vblank thread's condition_variable::wait_until went through winpthreads, which ends a timed wait on a 15.6 ms GetTickCount64 step even with the scheduler tick raised to 0.5 ms. Vblank intervals ranged from 2 ms to 34 ms instead of 16.68 ms. The thread now sleeps to each deadline with PreciseSleepUs and checks for a stop or a presentation failure after each sleep. Co-Authored-By: Claude Opus 5.5 --- core/libs/prx/libSceVideoOut/src/VideoOutDriver.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/libs/prx/libSceVideoOut/src/VideoOutDriver.cpp b/core/libs/prx/libSceVideoOut/src/VideoOutDriver.cpp index b61d35d41..be2a9fa12 100644 --- a/core/libs/prx/libSceVideoOut/src/VideoOutDriver.cpp +++ b/core/libs/prx/libSceVideoOut/src/VideoOutDriver.cpp @@ -20,6 +20,7 @@ #include "prx/libSceAgcDriver/Execution/include/Presentation.hpp" #include "prx/libSceAgcDriver/Execution/include/PerformanceTimer.hpp" #include "prx/libSceAgcDriver/Submit/include/Dcb.hpp" +#include "prx/libc/include/PreciseWait.hpp" #include "prx/libc/include/Shutdown.hpp" namespace { @@ -541,9 +542,10 @@ void VideoOutDriver::vblankLoop(std::stop_token token) { try { for (int64_t frame = 1; !token.stop_requested(); ++frame) { const auto next = start + std::chrono::duration_cast(Frame(frame)); + const auto remaining = std::chrono::duration_cast(next - std::chrono::steady_clock::now()).count(); + if (remaining > 0) PreciseSleepUs(static_cast(remaining)); { - std::unique_lock lock(flipQueue->mutex); - flipQueue->changed.wait_until(lock, next, [&] { return token.stop_requested() || flipQueue->failure; }); + std::lock_guard lock(flipQueue->mutex); if (token.stop_requested() || flipQueue->failure) return; } vblankEnd();