diff --git a/app/src/main/cpp/skyline/gpu/presentation_engine.cpp b/app/src/main/cpp/skyline/gpu/presentation_engine.cpp index 8bcec905..5a913b70 100644 --- a/app/src/main/cpp/skyline/gpu/presentation_engine.cpp +++ b/app/src/main/cpp/skyline/gpu/presentation_engine.cpp @@ -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 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 AChoreographer_postFrameCallback64(AChoreographer_getInstance(), reinterpret_cast(&ChoreographerCallback), engine); @@ -237,6 +238,8 @@ namespace skyline::gpu { presentQueue.Process([this](const PresentableFrame &frame) { PresentFrame(frame); 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) { Logger::Error("{}\nStack Trace:{}", e.what(), state.loader->GetStackTrace(e.frames)); diff --git a/app/src/main/cpp/skyline/gpu/presentation_engine.h b/app/src/main/cpp/skyline/gpu/presentation_engine.h index 7f0c9b6a..7fbfaf27 100644 --- a/app/src/main/cpp/skyline/gpu/presentation_engine.h +++ b/app/src/main/cpp/skyline/gpu/presentation_engine.h @@ -52,6 +52,7 @@ namespace skyline::gpu { perfetto::Track presentationTrack; //!< Perfetto track used for presentation events public: + std::atomic skipSignal; //!< If true, the next signal will be skipped by the choreographer thread std::shared_ptr vsyncEvent; //!< Signalled every time a frame is drawn private: