1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-04 10:03:36 +00:00

Call PluginAPI methods which use OpenGL in separate thread.

This fixes plugin reset in Project64 1.6
This commit is contained in:
Sergey Lipskiy 2014-09-19 10:10:06 +07:00
parent 245cd1b8b5
commit 475b37eb00
7 changed files with 111 additions and 51 deletions

View File

@ -1,37 +0,0 @@
#ifndef GLCRITICALSECTION_H
#define GLCRITICALSECTION_H
#include <mutex> // std::mutex
class GLCriticalSection
{
public:
void lock()
{
m_mtx.lock();
m_locked = true;
}
void unlock()
{
m_locked = false;
m_mtx.unlock();
}
bool isLocked() const {return m_locked;}
protected:
class Lock {
public:
Lock(GLCriticalSection * _pCS) : m_pCS(_pCS) {m_pCS->lock();}
~Lock() {m_pCS->unlock();}
private:
GLCriticalSection * m_pCS;
};
private:
std::mutex m_mtx;
bool m_locked;
};
#endif // GLCRITICALSECTION_H

View File

@ -345,7 +345,6 @@
<ClInclude Include="FrameBuffer.h" /> <ClInclude Include="FrameBuffer.h" />
<ClInclude Include="GBI.h" /> <ClInclude Include="GBI.h" />
<ClInclude Include="gDP.h" /> <ClInclude Include="gDP.h" />
<ClInclude Include="GLCriticalSection.h" />
<ClInclude Include="glext.h" /> <ClInclude Include="glext.h" />
<ClInclude Include="GLideN64.h" /> <ClInclude Include="GLideN64.h" />
<ClInclude Include="gSP.h" /> <ClInclude Include="gSP.h" />

View File

@ -305,9 +305,6 @@
<ClInclude Include="Log.h"> <ClInclude Include="Log.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="GLCriticalSection.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="Resource.rc"> <ResourceCompile Include="Resource.rc">

View File

@ -1,17 +1,34 @@
#ifndef COMMONPLUGINAPI_H #ifndef COMMONPLUGINAPI_H
#define COMMONPLUGINAPI_H #define COMMONPLUGINAPI_H
#include <thread>
#include <condition_variable>
#ifdef MUPENPLUSAPI #ifdef MUPENPLUSAPI
#include "m64p_plugin.h" #include "m64p_plugin.h"
#else #else
#include "ZilmarGFX_1_3.h" #include "ZilmarGFX_1_3.h"
#define RSPTHREAD
#endif #endif
#include "GLCriticalSection.h" enum API_COMMAND {
acNone = 0,
acProcessDList,
acUpdateScreen,
acRomClosed
};
class PluginAPI : public GLCriticalSection class PluginAPI
{ {
public: public:
#ifdef RSPTHREAD
~PluginAPI()
{
delete m_pRspThread;
m_pRspThread = NULL;
}
#endif
// Common // Common
void MoveScreen(int /*_xpos*/, int /*_ypos*/) {} void MoveScreen(int /*_xpos*/, int /*_ypos*/) {}
void ProcessRDPList() {} void ProcessRDPList() {}
@ -70,10 +87,24 @@ public:
} }
private: private:
PluginAPI() {} PluginAPI()
#ifdef RSPTHREAD
: m_pRspThread(NULL), m_command(acNone)
#endif
{}
PluginAPI(const PluginAPI &); PluginAPI(const PluginAPI &);
void _initiateGFX(const GFX_INFO & _gfxInfo); void _initiateGFX(const GFX_INFO & _gfxInfo) const;
#ifdef RSPTHREAD
void _callAPICommand(API_COMMAND _command);
std::mutex m_rspThreadMtx;
std::mutex m_pluginThreadMtx;
std::condition_variable_any m_rspThreadCv;
std::condition_variable_any m_pluginThreadCv;
std::thread * m_pRspThread;
API_COMMAND m_command;
#endif
}; };
inline PluginAPI & api() inline PluginAPI & api()

View File

@ -3,6 +3,7 @@
#else #else
# include "../winlnxdefs.h" # include "../winlnxdefs.h"
#endif // _WINDOWS #endif // _WINDOWS
#include <assert.h>
#include "../PluginAPI.h" #include "../PluginAPI.h"
@ -12,16 +13,75 @@
#include "../RSP.h" #include "../RSP.h"
#include "../VI.h" #include "../VI.h"
#include "../Debug.h" #include "../Debug.h"
#include "../Log.h"
#ifdef RSPTHREAD
void RSP_ThreadProc(std::mutex * _pRspThreadMtx, std::mutex * _pPluginThreadMtx, std::condition_variable_any * _pRspThreadCv, std::condition_variable_any * _pPluginThreadCv, API_COMMAND * _pCommand)
{
_pRspThreadMtx->lock();
RSP_Init();
OGL_ResizeWindow();
assert(!isGLError());
while (true) {
_pPluginThreadMtx->lock();
_pPluginThreadCv->notify_one();
_pPluginThreadMtx->unlock();
_pRspThreadCv->wait(*_pRspThreadMtx);
switch (*_pCommand) {
case acProcessDList:
RSP_ProcessDList();
break;
case acUpdateScreen:
VI_UpdateScreen();
break;
case acRomClosed:
OGL_Stop();
GBI_Destroy();
*_pCommand = acNone;
_pRspThreadMtx->unlock();
_pPluginThreadMtx->lock();
_pPluginThreadCv->notify_one();
_pPluginThreadMtx->unlock();
return;
}
assert(!isGLError());
*_pCommand = acNone;
}
}
void PluginAPI::_callAPICommand(API_COMMAND _command)
{
m_command = _command;
m_pluginThreadMtx.lock();
m_rspThreadMtx.lock();
m_rspThreadCv.notify_one();
m_rspThreadMtx.unlock();
m_pluginThreadCv.wait(m_pluginThreadMtx);
m_pluginThreadMtx.unlock();
}
#endif
void PluginAPI::ProcessDList() void PluginAPI::ProcessDList()
{ {
Lock lock(this); LOG(LOG_APIFUNC, "ProcessDList\n");
#ifdef RSPTHREAD
_callAPICommand(acProcessDList);
#else
RSP_ProcessDList(); RSP_ProcessDList();
#endif
} }
void PluginAPI::RomClosed() void PluginAPI::RomClosed()
{ {
LOG(LOG_APIFUNC, "RomClosed\n");
#ifdef RSPTHREAD
_callAPICommand(acRomClosed);
delete m_pRspThread;
m_pRspThread = NULL;
#else
OGL_Stop(); OGL_Stop();
#endif
#ifdef DEBUG #ifdef DEBUG
CloseDebugDlg(); CloseDebugDlg();
@ -30,9 +90,17 @@ void PluginAPI::RomClosed()
void PluginAPI::RomOpen() void PluginAPI::RomOpen()
{ {
LOG(LOG_APIFUNC, "RomOpen\n");
#ifdef RSPTHREAD
m_pluginThreadMtx.lock();
m_pRspThread = new std::thread(RSP_ThreadProc, &m_rspThreadMtx, &m_pluginThreadMtx, &m_rspThreadCv, &m_pluginThreadCv, &m_command);
m_pRspThread->detach();
m_pluginThreadCv.wait(m_pluginThreadMtx);
m_pluginThreadMtx.unlock();
#else
RSP_Init(); RSP_Init();
OGL_ResizeWindow(); OGL_ResizeWindow();
#endif
#ifdef DEBUG #ifdef DEBUG
OpenDebugDlg(); OpenDebugDlg();
@ -46,11 +114,15 @@ void PluginAPI::ShowCFB()
void PluginAPI::UpdateScreen() void PluginAPI::UpdateScreen()
{ {
Lock lock(this); LOG(LOG_APIFUNC, "UpdateScreen\n");
#ifdef RSPTHREAD
_callAPICommand(acUpdateScreen);
#else
VI_UpdateScreen(); VI_UpdateScreen();
#endif
} }
void PluginAPI::_initiateGFX(const GFX_INFO & _gfxInfo) { void PluginAPI::_initiateGFX(const GFX_INFO & _gfxInfo) const {
DMEM = _gfxInfo.DMEM; DMEM = _gfxInfo.DMEM;
IMEM = _gfxInfo.IMEM; IMEM = _gfxInfo.IMEM;
RDRAM = _gfxInfo.RDRAM; RDRAM = _gfxInfo.RDRAM;

View File

@ -4,7 +4,6 @@
int PluginAPI::InitiateGFX(const GFX_INFO & _gfxInfo) int PluginAPI::InitiateGFX(const GFX_INFO & _gfxInfo)
{ {
Lock lock(this);
_initiateGFX(_gfxInfo); _initiateGFX(_gfxInfo);
Config_LoadConfig(); Config_LoadConfig();

View File

@ -14,7 +14,6 @@ BOOL CALLBACK FindToolBarProc( HWND hWnd, LPARAM lParam )
int PluginAPI::InitiateGFX(const GFX_INFO & _gfxInfo) int PluginAPI::InitiateGFX(const GFX_INFO & _gfxInfo)
{ {
Lock lock(this);
_initiateGFX(_gfxInfo); _initiateGFX(_gfxInfo);
hWnd = _gfxInfo.hWnd; hWnd = _gfxInfo.hWnd;