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:
parent
e4725675fd
commit
da088e62ad
|
@ -28,6 +28,10 @@
|
||||||
|
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
|
|
||||||
|
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
|
||||||
|
HANDLE g_hEventOnIdle=NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Common
|
namespace Common
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -32,6 +32,14 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#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
|
namespace Common
|
||||||
{
|
{
|
||||||
class CriticalSection
|
class CriticalSection
|
||||||
|
|
|
@ -367,10 +367,17 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
}
|
}
|
||||||
else
|
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);
|
cpuThread = new Common::Thread(CpuThread, pArg);
|
||||||
PluginVideo::Video_Prepare(); //wglMakeCurrent
|
PluginVideo::Video_Prepare(); //wglMakeCurrent
|
||||||
Common::SetCurrentThreadName("Video thread");
|
Common::SetCurrentThreadName("Video thread");
|
||||||
PluginVideo::Video_EnterLoop();
|
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
|
// Wait for CPU thread to exit - it should have been signaled to do so by now
|
||||||
|
|
|
@ -459,9 +459,10 @@ void CatchUpGPU()
|
||||||
void UpdateFifoRegister()
|
void UpdateFifoRegister()
|
||||||
{
|
{
|
||||||
// update the distance
|
// update the distance
|
||||||
#ifdef _WIN32
|
//#ifdef _WIN32
|
||||||
if (Core::g_CoreStartupParameter.bUseDualCore) EnterCriticalSection(&fifo.sync);
|
// not needed since we are already in the critical section in DC mode -> see write16(...) (unique reference)
|
||||||
#endif
|
// if (Core::g_CoreStartupParameter.bUseDualCore) EnterCriticalSection(&fifo.sync);
|
||||||
|
//#endif
|
||||||
int wp = fifo.CPWritePointer;
|
int wp = fifo.CPWritePointer;
|
||||||
int rp = fifo.CPReadPointer;
|
int rp = fifo.CPReadPointer;
|
||||||
if (wp >= rp)
|
if (wp >= rp)
|
||||||
|
@ -469,9 +470,10 @@ void UpdateFifoRegister()
|
||||||
else
|
else
|
||||||
fifo.CPReadWriteDistance = (wp - fifo.CPBase) +
|
fifo.CPReadWriteDistance = (wp - fifo.CPBase) +
|
||||||
(fifo.CPEnd - rp);
|
(fifo.CPEnd - rp);
|
||||||
#ifdef _WIN32
|
//#ifdef _WIN32
|
||||||
if (Core::g_CoreStartupParameter.bUseDualCore) LeaveCriticalSection(&fifo.sync);
|
// not needed since we are already in the critical section in DC mode (see write16)
|
||||||
#endif
|
// if (Core::g_CoreStartupParameter.bUseDualCore) LeaveCriticalSection(&fifo.sync);
|
||||||
|
//#endif
|
||||||
if (!Core::g_CoreStartupParameter.bUseDualCore) CatchUpGPU();
|
if (!Core::g_CoreStartupParameter.bUseDualCore) CatchUpGPU();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
|
|
||||||
#include "../Host.h"
|
#include "../Host.h"
|
||||||
|
|
||||||
|
#include "thread.h" // for g_hEventOnIdle
|
||||||
|
|
||||||
namespace PowerPC
|
namespace PowerPC
|
||||||
{
|
{
|
||||||
// STATE_TO_SAVE
|
// STATE_TO_SAVE
|
||||||
|
@ -293,6 +295,10 @@ namespace PowerPC
|
||||||
//DualCore OnIdle
|
//DualCore OnIdle
|
||||||
void OnIdleDC(void)
|
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();
|
CoreTiming::Idle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,20 +127,36 @@ void Video_SendFifoData(u8* _uData)
|
||||||
void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
||||||
{
|
{
|
||||||
SCPFifoStruct &_fifo = *video_initialize.pCPFifo;
|
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!
|
// TODO(ector): Don't peek so often!
|
||||||
while (video_initialize.pPeekMessages())
|
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 (_fifo.CPReadWriteDistance < 1) //fifo.CPLoWatermark)
|
||||||
|
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
|
||||||
|
continue;
|
||||||
|
#else
|
||||||
Common::SleepCurrentThread(1);
|
Common::SleepCurrentThread(1);
|
||||||
|
#endif
|
||||||
//etc...
|
//etc...
|
||||||
|
|
||||||
// check if we are able to run this buffer
|
// check if we are able to run this buffer
|
||||||
if ((_fifo.bFF_GPReadEnable) && !(_fifo.bFF_BPEnable && _fifo.bFF_Breakpoint))
|
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)
|
while(_fifo.CPReadWriteDistance > 0 && count)
|
||||||
{
|
#endif
|
||||||
|
{
|
||||||
// check if we are on a breakpoint
|
// check if we are on a breakpoint
|
||||||
if (_fifo.bFF_BPEnable)
|
if (_fifo.bFF_BPEnable)
|
||||||
{
|
{
|
||||||
|
@ -169,10 +185,15 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
||||||
_fifo.CPReadPointer = _fifo.CPBase;
|
_fifo.CPReadPointer = _fifo.CPBase;
|
||||||
//LOG(COMMANDPROCESSOR, "BUFFER LOOP");
|
//LOG(COMMANDPROCESSOR, "BUFFER LOOP");
|
||||||
}
|
}
|
||||||
|
#ifndef THREAD_VIDEO_WAKEUP_ONIDLE
|
||||||
count--;
|
count--;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
|
||||||
|
CloseHandle(hEventOnIdle);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue