diff --git a/Core/System.cpp b/Core/System.cpp index 285ce3a2a9..a073bb7b67 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -336,6 +336,9 @@ void PSP_RunLoopUntil(u64 globalticks) { } if (cpuThread != NULL) { + // Tell the gpu a new frame is about to begin, before we start the CPU. + gpu->SyncBeginFrame(); + cpuThreadUntil = globalticks; if (CPU_NextState(CPU_THREAD_RUNNING, CPU_THREAD_EXECUTE)) { // The CPU doesn't actually respect cpuThreadUntil well, especially when skipping frames. diff --git a/Core/ThreadEventQueue.h b/Core/ThreadEventQueue.h index 110e63600c..1cfd805901 100644 --- a/Core/ThreadEventQueue.h +++ b/Core/ThreadEventQueue.h @@ -24,7 +24,7 @@ template struct ThreadEventQueue : public B { - ThreadEventQueue() : threadEnabled_(false), eventsRunning_(false) { + ThreadEventQueue() : threadEnabled_(false), eventsRunning_(false), eventsHaveRun_(false) { } void SetThreadEnabled(bool threadEnabled) { @@ -72,6 +72,7 @@ struct ThreadEventQueue : public B { void RunEventsUntil(u64 globalticks) { lock_guard guard(eventsLock_); eventsRunning_ = true; + eventsHaveRun_ = true; do { for (Event ev = GetNextEvent(); EventType(ev) != EVENT_INVALID; ev = GetNextEvent()) { @@ -107,6 +108,11 @@ struct ThreadEventQueue : public B { eventsRunning_ = false; } + void SyncBeginFrame() { + lock_guard guard(eventsLock_); + eventsHaveRun_ = false; + } + // Force ignores coreState. void SyncThread(bool force = false) { if (!threadEnabled_) { @@ -117,8 +123,8 @@ struct ThreadEventQueue : public B { // While processing the last event, HasEvents() will be false even while not done. // So we schedule a nothing event and wait for that to finish. ScheduleEvent(EVENT_SYNC); - while (HasEvents() && eventsRunning_ && (force || coreState == CORE_RUNNING)) { - eventsDrain_.wait_for(eventsLock_, 1); + while (HasEvents() && (eventsRunning_ || !eventsHaveRun_) && (force || coreState == CORE_RUNNING)) { + eventsDrain_.wait_for(eventsLock_, 1000); } } @@ -135,6 +141,7 @@ protected: private: bool threadEnabled_; bool eventsRunning_; + bool eventsHaveRun_; std::deque events_; recursive_mutex eventsLock_; condition_variable eventsWait_; diff --git a/GPU/GPUInterface.h b/GPU/GPUInterface.h index 82f812ec4d..1e3e2e6796 100644 --- a/GPU/GPUInterface.h +++ b/GPU/GPUInterface.h @@ -231,6 +231,7 @@ public: virtual void DeviceLost() = 0; virtual void ReapplyGfxState() = 0; virtual void SyncThread(bool force = false) = 0; + virtual void SyncBeginFrame() = 0; virtual u64 GetTickEstimate() = 0; virtual void DoState(PointerWrap &p) = 0;