DC idle skipping part 2: video thread is woken up when "OnIdle".

For testing purpose only (I can't test with lots of games) because it may break some sync. Besides, I'm not satisfied with the way things are done.
So just uncomment "//#define THREAD_VIDEO_WAKEUP_ONIDLE" in thread.h in order to test it.
Works fine with movies, 2D and simple 3D in ZWW at least.
If it's ok I'll clean up the code.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@658 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
memberTwo.mb2 2008-09-24 10:52:58 +00:00
parent e4725675fd
commit da088e62ad
6 changed files with 56 additions and 8 deletions

View File

@ -28,6 +28,10 @@
#include "Thread.h"
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
HANDLE g_hEventOnIdle=NULL;
#endif
namespace Common
{
#ifdef _WIN32

View File

@ -32,6 +32,14 @@
#include "Common.h"
// for testing purpose
//#define THREAD_VIDEO_WAKEUP_ONIDLE
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
extern HANDLE g_hEventOnIdle;
#endif
namespace Common
{
class CriticalSection

View File

@ -367,10 +367,17 @@ THREAD_RETURN EmuThread(void *pArg)
}
else
{
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
g_hEventOnIdle = CreateEvent( NULL, FALSE, FALSE, "EventOnIdle");
if (g_hEventOnIdle == NULL) PanicAlert("EmuThread() -> Create EventOnIdle error");
#endif
cpuThread = new Common::Thread(CpuThread, pArg);
PluginVideo::Video_Prepare(); //wglMakeCurrent
Common::SetCurrentThreadName("Video thread");
PluginVideo::Video_EnterLoop();
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
CloseHandle(g_hEventOnIdle);
#endif
}
// Wait for CPU thread to exit - it should have been signaled to do so by now

View File

@ -459,9 +459,10 @@ void CatchUpGPU()
void UpdateFifoRegister()
{
// update the distance
#ifdef _WIN32
if (Core::g_CoreStartupParameter.bUseDualCore) EnterCriticalSection(&fifo.sync);
#endif
//#ifdef _WIN32
// not needed since we are already in the critical section in DC mode -> see write16(...) (unique reference)
// if (Core::g_CoreStartupParameter.bUseDualCore) EnterCriticalSection(&fifo.sync);
//#endif
int wp = fifo.CPWritePointer;
int rp = fifo.CPReadPointer;
if (wp >= rp)
@ -469,9 +470,10 @@ void UpdateFifoRegister()
else
fifo.CPReadWriteDistance = (wp - fifo.CPBase) +
(fifo.CPEnd - rp);
#ifdef _WIN32
if (Core::g_CoreStartupParameter.bUseDualCore) LeaveCriticalSection(&fifo.sync);
#endif
//#ifdef _WIN32
// not needed since we are already in the critical section in DC mode (see write16)
// if (Core::g_CoreStartupParameter.bUseDualCore) LeaveCriticalSection(&fifo.sync);
//#endif
if (!Core::g_CoreStartupParameter.bUseDualCore) CatchUpGPU();
}

View File

@ -33,6 +33,8 @@
#include "../Host.h"
#include "thread.h" // for g_hEventOnIdle
namespace PowerPC
{
// STATE_TO_SAVE
@ -293,6 +295,10 @@ namespace PowerPC
//DualCore OnIdle
void OnIdleDC(void)
{
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
if (g_hEventOnIdle==NULL) PanicAlert("Idle() -> EventOnIdle NULL");
if (! SetEvent(g_hEventOnIdle) ) { PanicAlert("Idle() -> SetEvent EventOnIdle failed");}
#endif
CoreTiming::Idle();
}
}

View File

@ -127,20 +127,36 @@ void Video_SendFifoData(u8* _uData)
void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
{
SCPFifoStruct &_fifo = *video_initialize.pCPFifo;
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
HANDLE hEventOnIdle= OpenEventA(EVENT_ALL_ACCESS,FALSE,(LPCSTR)"EventOnIdle");
if (hEventOnIdle==NULL) PanicAlert("Fifo_EnterLoop() -> EventOnIdle NULL");
#endif
// TODO(ector): Don't peek so often!
while (video_initialize.pPeekMessages())
{
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
if (MsgWaitForMultipleObjects(1, &hEventOnIdle, FALSE, 1L, QS_ALLEVENTS) == WAIT_ABANDONED)
break;
#endif
if (_fifo.CPReadWriteDistance < 1) //fifo.CPLoWatermark)
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
continue;
#else
Common::SleepCurrentThread(1);
#endif
//etc...
// check if we are able to run this buffer
if ((_fifo.bFF_GPReadEnable) && !(_fifo.bFF_BPEnable && _fifo.bFF_Breakpoint))
{
int count = 200;
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
while(_fifo.CPReadWriteDistance > 0)
#else
int count = 200;
while(_fifo.CPReadWriteDistance > 0 && count)
{
#endif
{
// check if we are on a breakpoint
if (_fifo.bFF_BPEnable)
{
@ -169,10 +185,15 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
_fifo.CPReadPointer = _fifo.CPBase;
//LOG(COMMANDPROCESSOR, "BUFFER LOOP");
}
#ifndef THREAD_VIDEO_WAKEUP_ONIDLE
count--;
#endif
}
}
}
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
CloseHandle(hEventOnIdle);
#endif
}