Attempt to signal the vsync event at present time if possible

Some games rely on the vsync event to schedule frames, by matching its timing with presentation we can reduce needless waiting as the game will immediely be able to queue the next frame after presentation.
This commit is contained in:
Billy Laws 2022-12-27 19:35:00 +00:00
parent 918a493a45
commit cc3c869b9f
2 changed files with 5 additions and 1 deletions

View File

@ -61,7 +61,8 @@ namespace skyline::gpu {
// Record the current cycle's timestamp and signal the V-Sync event to notify the game that a frame has been displayed // Record the current cycle's timestamp and signal the V-Sync event to notify the game that a frame has been displayed
engine->lastChoreographerTime = frameTimeNanos; engine->lastChoreographerTime = frameTimeNanos;
engine->vsyncEvent->Signal(); if (!engine->skipSignal.exchange(false))
engine->vsyncEvent->Signal();
// Post the frame callback to be triggered on the next display refresh // Post the frame callback to be triggered on the next display refresh
AChoreographer_postFrameCallback64(AChoreographer_getInstance(), reinterpret_cast<AChoreographer_frameCallback64>(&ChoreographerCallback), engine); AChoreographer_postFrameCallback64(AChoreographer_getInstance(), reinterpret_cast<AChoreographer_frameCallback64>(&ChoreographerCallback), engine);
@ -237,6 +238,8 @@ namespace skyline::gpu {
presentQueue.Process([this](const PresentableFrame &frame) { presentQueue.Process([this](const PresentableFrame &frame) {
PresentFrame(frame); PresentFrame(frame);
frame.presentCallback(); // We're calling the callback here as it's outside of all the locks in PresentFrame frame.presentCallback(); // We're calling the callback here as it's outside of all the locks in PresentFrame
skipSignal = true;
vsyncEvent->Signal();
}, [] {}); }, [] {});
} catch (const signal::SignalException &e) { } catch (const signal::SignalException &e) {
Logger::Error("{}\nStack Trace:{}", e.what(), state.loader->GetStackTrace(e.frames)); Logger::Error("{}\nStack Trace:{}", e.what(), state.loader->GetStackTrace(e.frames));

View File

@ -52,6 +52,7 @@ namespace skyline::gpu {
perfetto::Track presentationTrack; //!< Perfetto track used for presentation events perfetto::Track presentationTrack; //!< Perfetto track used for presentation events
public: public:
std::atomic<bool> skipSignal; //!< If true, the next signal will be skipped by the choreographer thread
std::shared_ptr<kernel::type::KEvent> vsyncEvent; //!< Signalled every time a frame is drawn std::shared_ptr<kernel::type::KEvent> vsyncEvent; //!< Signalled every time a frame is drawn
private: private: