mirror of https://github.com/PCSX2/pcsx2.git
Cleanup for VsyncInThread, lots of source code comments. (it's fun reading! ...maybe)
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2318 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
6b5e302f82
commit
acbe1ed547
|
@ -30,7 +30,6 @@
|
|||
using namespace Threading;
|
||||
|
||||
extern u8 psxhblankgate;
|
||||
extern void ApplyPatch( int place = 1);
|
||||
|
||||
static const uint EECNT_FUTURE_TARGET = 0x10000000;
|
||||
|
||||
|
@ -293,7 +292,6 @@ void frameLimitReset()
|
|||
// Framelimiter - Measures the delta time between calls and stalls until a
|
||||
// certain amount of time passes if such time hasn't passed yet.
|
||||
// See the GS FrameSkip function for details on why this is here and not in the GS.
|
||||
extern int limitOn;
|
||||
static __forceinline void frameLimit()
|
||||
{
|
||||
// 999 means the user would rather just have framelimiting turned off...
|
||||
|
@ -325,8 +323,10 @@ static __forceinline void frameLimit()
|
|||
if( sDeltaTime >= 0 ) return;
|
||||
|
||||
// If we're way ahead then we can afford to sleep the thread a bit.
|
||||
// (note, sleep(1) thru sleep(2) tend to be the least accurate sleeps, and longer
|
||||
// sleeps tend to be pretty reliable, so that's why the convoluted if/else below)
|
||||
// (note, on Windows sleep(1) thru sleep(2) tend to be the least accurate sleeps,
|
||||
// and longer sleeps tend to be pretty reliable, so that's why the convoluted if/
|
||||
// else below. The same generally isn't true for Linux, but no harm either way
|
||||
// really.)
|
||||
|
||||
s32 msec = (int)((sDeltaTime*-1000) / (s64)GetTickFrequency());
|
||||
if( msec > 4 ) Threading::Sleep( msec );
|
||||
|
@ -339,8 +339,18 @@ static __forceinline void frameLimit()
|
|||
|
||||
static __forceinline void VSyncStart(u32 sCycle)
|
||||
{
|
||||
EECNT_LOG( "///////// EE COUNTER VSYNC START \\\\\\\\\\\\\\\\\\\\ (frame: %d)", iFrame );
|
||||
vSyncDebugStuff( iFrame ); // EE Profiling and Debug code
|
||||
Cpu->CheckExecutionState();
|
||||
SysCoreThread::Get().VsyncInThread();
|
||||
|
||||
EECNT_LOG( "///////// EE COUNTER VSYNC START (frame: %6d) \\\\\\\\\\\\\\\\\\\\ ", iFrame );
|
||||
|
||||
// EE Profiling and Debug code.
|
||||
// FIXME: should probably be moved to VsyncInThread, and handled
|
||||
// by UI implementations. (ie, AppCoreThread in PCSX2-wx interface).
|
||||
vSyncDebugStuff( iFrame );
|
||||
|
||||
if (CHECK_MICROVU0) vsyncVUrec(0);
|
||||
if (CHECK_MICROVU1) vsyncVUrec(1);
|
||||
|
||||
if ((CSRw & 0x8))
|
||||
{
|
||||
|
@ -355,7 +365,6 @@ static __forceinline void VSyncStart(u32 sCycle)
|
|||
psxVBlankStart();
|
||||
|
||||
if (gates) rcntStartGate(true, sCycle); // Counters Start Gate code
|
||||
if (EmuConfig.EnablePatches) ApplyPatch(); // fixme - Apply patches
|
||||
|
||||
// INTC - VB Blank Start Hack --
|
||||
// Hack fix! This corrects a freezeup in Granda 2 where it decides to spin
|
||||
|
@ -445,8 +454,6 @@ __forceinline void rcntUpdate_vSync()
|
|||
|
||||
if (vsyncCounter.Mode == MODE_VSYNC)
|
||||
{
|
||||
Cpu->CheckExecutionState();
|
||||
|
||||
VSyncEnd(vsyncCounter.sCycle);
|
||||
|
||||
vsyncCounter.sCycle += vSyncInfo.Blank;
|
||||
|
@ -464,9 +471,6 @@ __forceinline void rcntUpdate_vSync()
|
|||
// Accumulate hsync rounding errors:
|
||||
hsyncCounter.sCycle += vSyncInfo.hSyncError;
|
||||
|
||||
if (CHECK_MICROVU0) vsyncVUrec(0);
|
||||
if (CHECK_MICROVU1) vsyncVUrec(1);
|
||||
|
||||
# ifdef VSYNC_DEBUG
|
||||
vblankinc++;
|
||||
if( vblankinc > 1 )
|
||||
|
|
|
@ -390,7 +390,6 @@ static void intExecute()
|
|||
|
||||
static void intCheckExecutionState()
|
||||
{
|
||||
SysCoreThread::Get().OnVsyncInThread();
|
||||
SysCoreThread::Get().StateCheckInThread();
|
||||
}
|
||||
|
||||
|
@ -407,12 +406,15 @@ static void intClear(u32 Addr, u32 Size)
|
|||
static void intShutdown() {
|
||||
}
|
||||
|
||||
R5900cpu intCpu = {
|
||||
R5900cpu intCpu =
|
||||
{
|
||||
intAlloc,
|
||||
intShutdown,
|
||||
|
||||
intReset,
|
||||
intStep,
|
||||
intExecute,
|
||||
|
||||
intCheckExecutionState,
|
||||
intClear,
|
||||
intShutdown
|
||||
};
|
||||
|
|
|
@ -1147,6 +1147,11 @@ void PluginManager::Freeze( PluginsEnum_t pid, SaveStateBase& state )
|
|||
|
||||
bool PluginManager::KeyEvent( const keyEvent& evt )
|
||||
{
|
||||
// [TODO] : The plan here is to give plugins "first chance" handling of keys.
|
||||
// Handling order will be fixed (GS, SPU2, PAD, etc), and the first plugin to
|
||||
// pick up the key and return "true" (for handled) will cause the loop to break.
|
||||
// The current version of PS2E doesn't support it yet, though.
|
||||
|
||||
const PluginInfo* pi = tbl_PluginInfo; do {
|
||||
if( pi->id != PluginId_PAD )
|
||||
m_info[pi->id].CommonBindings.KeyEvent( const_cast<keyEvent*>(&evt) );
|
||||
|
|
|
@ -263,16 +263,102 @@ void __fastcall intDoBranch(u32 target);
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// R5900 Public Interface / API
|
||||
|
||||
//
|
||||
// [TODO] : This is on the list to get converted to a proper C++ class. I'm putting it
|
||||
// off until I get my new IOPint and IOPrec re-merged. --air
|
||||
//
|
||||
struct R5900cpu
|
||||
{
|
||||
void (*Allocate)(); // throws exceptions on failure.
|
||||
// Memory allocation function, for allocating virtual memory spaces needed by
|
||||
// the emulator. (ints/recs are free to allocate additional memory while running
|
||||
// code, however any virtual mapped memory should always be allocated as soon
|
||||
// as possible, to claim the memory before some plugin does..)
|
||||
//
|
||||
// Thread Affinity:
|
||||
// Can be called from any thread. Execute status must be suspended or stopped
|
||||
// to prevent multi-thread race conditions.
|
||||
//
|
||||
// Notable Exception Throws:
|
||||
// OutOfMemory - Not enough memory, or the memory areas required were already
|
||||
// reserved.
|
||||
//
|
||||
void (*Allocate)();
|
||||
|
||||
// Deallocates ram allocated by Allocate and/or by runtime code execution.
|
||||
//
|
||||
// Thread Affinity:
|
||||
// Can be called from any thread. Execute status must be suspended or stopped
|
||||
// to prevent multi-thread race conditions.
|
||||
//
|
||||
// Exception Throws: None. This function is a destructor, and should not throw.
|
||||
//
|
||||
void (*Shutdown)();
|
||||
|
||||
// Initializes / Resets code execution states. Typically implementation is only
|
||||
// needed for recompilers, as interpreters have no internal execution states and
|
||||
// rely on the CPU/VM states almost entirely.
|
||||
//
|
||||
// Thread Affinity:
|
||||
// Can be called from any thread. Execute status must be suspended or stopped
|
||||
// to prevent multi-thread race conditions.
|
||||
//
|
||||
// Exception Throws: Emulator-defined. Common exception types to look for:
|
||||
// OutOfMemory, Stream Exceptions
|
||||
//
|
||||
void (*Reset)();
|
||||
|
||||
// Steps a single instruction. Meant to be used by debuggers. Is currently unused
|
||||
// and unimplemented. Future note: recompiler "step" should *always* fall back
|
||||
// on interpreters.
|
||||
//
|
||||
// Exception Throws: [TODO] (possible execution-related throws to be added)
|
||||
//
|
||||
void (*Step)();
|
||||
|
||||
// Executes code until a break is signaled. Execution can be paused or suspended
|
||||
// via thread-style signals that are handled by CheckExecutionState callbacks.
|
||||
// Execution Breakages are handled the same way, where-by a signal causes the Execute
|
||||
// call to return at the nearest state check (typically handled internally using
|
||||
// either C++ exceptions or setjmp/longjmp).
|
||||
//
|
||||
// Exception Throws: [TODO] (possible execution-related throws to be added)
|
||||
//
|
||||
void (*Execute)();
|
||||
|
||||
// Checks for execution suspension or cancellation. In pthreads terms this provides
|
||||
// a "cancellation point." Execution state checks are typically performed at Vsyncs
|
||||
// by the generic VM event handlers in R5900.cpp/Counters.cpp (applies to both recs
|
||||
// and ints).
|
||||
//
|
||||
// Implementation note: Because of the nuances of recompiled code execution, setjmp
|
||||
// may be used in place of thread cancellation or C++ exceptions (non-SEH exceptions
|
||||
// cannot unwind through the recompiled code stackframes).
|
||||
//
|
||||
// Thread Affinity:
|
||||
// Must be called on the same thread as Execute only.
|
||||
//
|
||||
// Exception Throws:
|
||||
// May throw threading/Pthreads cancellations if the compiler supports SEH.
|
||||
// ThreadTimedOut - For canceling VM execution in response to MTGS deadlock. (if the
|
||||
// core emulator does not support multithreaded GS then this will not be a throw
|
||||
// exception).
|
||||
//
|
||||
void (*CheckExecutionState)();
|
||||
|
||||
// Manual recompiled code cache clear; typically useful to recompilers only. Size is
|
||||
// in MIPS words (32 bits). Dev note: this callback is nearly obsolete, and might be
|
||||
// better off replaced with some generic API callbacks from VTLB block protection.
|
||||
// Also: the calls from COP0's TLB remap code should be replaced with full recompiler
|
||||
// resets, since TLB remaps affect more than just the code they contain (code that
|
||||
// may reference the remaped blocks via memory loads/stores, for example).
|
||||
//
|
||||
// Thread Affinity Rule:
|
||||
// Can be called from any thread (namely for being called from debugging threads)
|
||||
//
|
||||
// Exception Throws: [TODO] Emulator defined? (probably shouldn't throw, probably
|
||||
// doesn't matter if we're stripping it out soon. ;)
|
||||
//
|
||||
void (*Clear)(u32 Addr, u32 Size);
|
||||
void (*Shutdown)(); // deallocates memory reserved by Allocate
|
||||
};
|
||||
|
||||
extern R5900cpu *Cpu;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "Counters.h"
|
||||
#include "GS.h"
|
||||
#include "Elfheader.h"
|
||||
#include "Patch.h"
|
||||
#include "PageFaultSource.h"
|
||||
#include "SysThreads.h"
|
||||
|
||||
|
@ -279,10 +280,37 @@ void SysCoreThread::_reset_stuff_as_needed()
|
|||
}
|
||||
}
|
||||
|
||||
void SysCoreThread::OnVsyncInThread()
|
||||
// Called by the VsyncInThread() if a valid keyEvent is pending and is unhandled by other
|
||||
// PS2 core plugins.
|
||||
void SysCoreThread::DispatchKeyEventToUI( const keyEvent& evt )
|
||||
{
|
||||
}
|
||||
|
||||
// This is called from the PS2 VM at the start of every vsync (either 59.94 or 50 hz by PS2
|
||||
// clock scale, which does not correlate to the actual host machine vsync).
|
||||
//
|
||||
// Default tasks: Updates PADs and applies vsync patches. Derived classes can override this
|
||||
// to change either PAD and/or Patching behaviors.
|
||||
//
|
||||
// [TODO]: Should probably also handle profiling and debugging updates, once those are
|
||||
// re-implemented.
|
||||
//
|
||||
void SysCoreThread::VsyncInThread()
|
||||
{
|
||||
if( !pxAssert(g_plugins!=NULL) ) return;
|
||||
const keyEvent* ev = PADkeyEvent();
|
||||
if( ev != NULL && (ev->key != 0) )
|
||||
{
|
||||
// Give plugins first try to handle keys. If none of them handles the key, it will
|
||||
// be passed to the main user interface.
|
||||
|
||||
if( !g_plugins->KeyEvent( *ev ) )
|
||||
DispatchKeyEventToUI( *ev );
|
||||
}
|
||||
|
||||
if (EmuConfig.EnablePatches) ApplyPatch();
|
||||
}
|
||||
|
||||
void SysCoreThread::StateCheckInThread()
|
||||
{
|
||||
GetMTGS().RethrowException();
|
||||
|
@ -290,8 +318,6 @@ void SysCoreThread::StateCheckInThread()
|
|||
if( !m_hasValidState )
|
||||
throw Exception::RuntimeError( "Invalid emulation state detected; Virtual machine threads have been cancelled." );
|
||||
|
||||
//OnVsyncInThread();
|
||||
|
||||
_reset_stuff_as_needed();
|
||||
}
|
||||
|
||||
|
|
|
@ -217,7 +217,8 @@ public:
|
|||
|
||||
bool HasPendingStateChangeRequest() const;
|
||||
virtual void StateCheckInThread();
|
||||
virtual void OnVsyncInThread();
|
||||
virtual void VsyncInThread();
|
||||
virtual void DispatchKeyEventToUI( const keyEvent& evt );
|
||||
|
||||
virtual const wxString& GetElfOverride() const { return m_elf_override; }
|
||||
virtual void SetElfOverride( const wxString& elf );
|
||||
|
|
|
@ -542,7 +542,8 @@ protected:
|
|||
virtual void OnResumeInThread( bool IsSuspended );
|
||||
virtual void OnSuspendInThread();
|
||||
virtual void OnCleanupInThread();
|
||||
virtual void OnVsyncInThread();
|
||||
//virtual void VsyncInThread();
|
||||
virtual void DispatchKeyEventToUI( const keyEvent& ev );
|
||||
virtual void ExecuteTaskInThread();
|
||||
};
|
||||
|
||||
|
|
|
@ -163,23 +163,15 @@ void AppCoreThread::OnCleanupInThread()
|
|||
extern int TranslateGDKtoWXK( u32 keysym );
|
||||
#endif
|
||||
|
||||
void AppCoreThread::OnVsyncInThread()
|
||||
void AppCoreThread::DispatchKeyEventToUI( const keyEvent& ev )
|
||||
{
|
||||
_parent::OnVsyncInThread();
|
||||
|
||||
if( !pxAssert(g_plugins!=NULL) ) return;
|
||||
|
||||
const keyEvent* ev = PADkeyEvent();
|
||||
if( ev == NULL || (ev->key == 0) ) return;
|
||||
|
||||
g_plugins->KeyEvent( *ev );
|
||||
m_kevt.SetEventType( ( ev->evt == KEYPRESS ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP );
|
||||
const bool isDown = (ev->evt == KEYPRESS);
|
||||
m_kevt.SetEventType( ( ev.evt == KEYPRESS ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP );
|
||||
const bool isDown = (ev.evt == KEYPRESS);
|
||||
|
||||
#ifdef __WXMSW__
|
||||
const int vkey = wxCharCodeMSWToWX( ev->key );
|
||||
const int vkey = wxCharCodeMSWToWX( ev.key );
|
||||
#elif defined( __WXGTK__ )
|
||||
const int vkey = TranslateGDKtoWXK( ev->key );
|
||||
const int vkey = TranslateGDKtoWXK( ev.key );
|
||||
#else
|
||||
# error Unsupported Target Platform.
|
||||
#endif
|
||||
|
|
|
@ -656,8 +656,6 @@ static jmp_buf m_SetJmp_StateCheck;
|
|||
|
||||
static void recCheckExecutionState()
|
||||
{
|
||||
SysCoreThread::Get().OnVsyncInThread();
|
||||
|
||||
#if PCSX2_SEH
|
||||
SysCoreThread::Get().StateCheckInThread();
|
||||
|
||||
|
@ -1733,10 +1731,12 @@ StartRecomp:
|
|||
R5900cpu recCpu =
|
||||
{
|
||||
recAlloc,
|
||||
recShutdown,
|
||||
|
||||
recResetEE,
|
||||
recStep,
|
||||
recExecute,
|
||||
|
||||
recCheckExecutionState,
|
||||
recClear,
|
||||
recShutdown
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue