Make sure the gpu thread has a chance to run.

If the scheduler puts it on the same core, it may not even do anything
before we check if the framebuffer is dirty, so SyncThread will quit since
it's not even running.

Instead, let's wait until it's at least done something.
This commit is contained in:
Unknown W. Brackets
2013-11-09 23:08:28 -08:00
parent 879060f008
commit afafa5fcd6
3 changed files with 14 additions and 3 deletions
+3
View File
@@ -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.
+10 -3
View File
@@ -24,7 +24,7 @@
template <typename B, typename Event, typename EventType, EventType EVENT_INVALID, EventType EVENT_SYNC, EventType EVENT_FINISH>
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<Event> events_;
recursive_mutex eventsLock_;
condition_variable eventsWait_;
+1
View File
@@ -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;