Repository navigation
fix(videoout): wait for flips with the high-resolution condition on Windows - #1655
Conversation
|
This breaks loading on Linux. With this PR on main (25cc6fa), |
adriadam10
left a comment
There was a problem hiding this comment.
Thanks @oneandonlydean for catching this. Confirmed from the diff: VideoOutDriver.cpp now calls TimedWait::DeadlineNanos (declared in libkernel/Time/include/TimedWait.hpp:15), a plain function that libkernel.prx contains but doesn't export. libSceVideoOut.prx therefore imports an unresolved symbol and the title stops at load.
To fix, either:
- export the
TimedWaitAPI thatlibSceVideoOutneeds from libkernel (and checkpatched_librariespasses), or - keep the deadline computation inside
libSceVideoOut(e.g. a localsteady_clock-based deadline) and only use what libkernel already exports.
Please also run patched_libraries (and a load of a module importing it) before pushing; the PR CI no longer builds/runs ctest, so it won't show there.
…indows The flip queue's condition variable went through winpthreads, whose timed waits end on GetTickCount64 steps: the present thread's 10 ms poll for SDL events and the pad, taken while no flip is queued, ended 11 to 24 ms later on Windows, and WaitForFlipRoom's 60 s bound had the same granularity. Use TimedWait::Condition, which waits on an event and a high-resolution timer, so the poll ends at 10 ms and a submitted flip still wakes the present thread at once. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ng it from libkernel libkernel.prx does not export TimedWait::*, so libSceVideoOut.prx had an unresolved import and titles stopped at load. Compile TimedWait.cpp into libSceVideoOut, and use NotifyAll for the notify added on main.
25cc6fa to
b41db48
Compare
adriadam10
left a comment
There was a problem hiding this comment.
Thanks @oneandonlydean for catching this. Confirmed: libkernel.prx doesn't export TimedWait::*, so libSceVideoOut.prx had an unresolved import.
Fixed on the branch:
- rebased onto current
main(conflict inFlipRequest::FailafterReleaseLocked; the newnotify_allis nowNotifyAll) TimedWait.cpp(self-contained) is compiled intolibSceVideoOut(CMakeLists.txt) instead of being imported from libkernel
Checked: nm -D libSceVideoOut.prx has no TimedWait undefined symbol; patched_libraries and the VideoOut ctest group pass (flip modes needing a Vulkan window skip). The Windows timing numbers are the author's and weren't reproduced here. Merging on green CI.
What
One of the host waits #1471 lists as still affected:
VideoOutDriver::presentLoopwaits onflipQueue->changed(astd::condition_variable) with a 10 ms timeout while no flip is queued, and pumps SDL events and the pad after each wake. On Windows that wait goes through winpthreads, which ends timed waits onGetTickCount64steps, so the poll ended 11 to 24 ms later instead of 10 ms.WaitForFlipRoomwaits on the same condition with a 60 s bound and has the same granularity.A plain high-resolution sleep is not a replacement here: a flip submitted while the present thread waits must wake it at once. libkernel already has the notify-capable precise wait the guest side uses,
TimedWait::Condition(event plus high-resolution waitable timer per waiting thread,std::condition_variable_anyunderAPS5_COARSE_TIMED_WAITS), and libSceVideoOut already links libkernel. The change makesFlipQueue::changedaTimedWait::Condition, turns the two timed waits intoWaitUntilwith the same bounds and predicates, and the eightnotify_allintoNotifyAll. On LinuxTimedWait::Conditionis thecondition_variable_anypath, so nothing changes there. This is the first use ofTimedWait::Conditionoutside libkernel.Tested
Windows 11 (10.0.26200), WinLibs GCC 15.2.0 (
15.2.0posix-14.0.0-ucrt-r7), Release,BUILD_TESTING=ON.Standalone measurement against the built
libkernel.prx, tick raised to 0.5 ms asTime.cppdoes, 60 iterations each:std::condition_variable::wait_for(10 ms), no notifyTimedWait::Condition::WaitUntil(10 ms), no notifyTimedWait::Condition::WaitUntil(10 ms), notified from another threadstd::condition_variable::wait_for(10 ms), notified from another threadThe notified rows show the wake-on-flip path is unchanged.
cmake --build build --target libSceVideoOut video_out_flip_tests;video_out_flip_tests decodeandvideo_out_flip_tests controlswithSDL_VIDEODRIVER=dummyexit 0 (the modes video_out_flip_tests is not in ctest and its lifetime and reopen modes terminate on main #1040 reports as passing onmain; the others need aparam.json).python tools/check_conventions.py --base upstream/mainandgit diff --checkpass.No title run; no Linux host here (the Linux path is the unchanged
condition_variable_anyfallback insideTimedWait::Condition).Checklist
main; no other open PR implements the same functions (fix(videoout): report GPU driver shutdown failure from the present thread at Shutdown #1225 and fix(avplayer): keep handed-out video frames until later frames are handed out #1601 do not touchpresentLoop; fix(videoout): pace vblanks with a high-resolution timer #1472 and fix(agc): poll for completions with a high-resolution timer on Windows #1474 covered the other VideoOut and queue waits)NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt — none added.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code