1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +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="GBI.h" />
<ClInclude Include="gDP.h" />
<ClInclude Include="GLCriticalSection.h" />
<ClInclude Include="glext.h" />
<ClInclude Include="GLideN64.h" />
<ClInclude Include="gSP.h" />

View File

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

View File

@ -1,17 +1,34 @@
#ifndef COMMONPLUGINAPI_H
#define COMMONPLUGINAPI_H
#include <thread>
#include <condition_variable>
#ifdef MUPENPLUSAPI
#include "m64p_plugin.h"
#else
#include "ZilmarGFX_1_3.h"
#define RSPTHREAD
#endif
#include "GLCriticalSection.h"
enum API_COMMAND {
acNone = 0,
acProcessDList,
acUpdateScreen,
acRomClosed
};
class PluginAPI : public GLCriticalSection
class PluginAPI
{
public:
#ifdef RSPTHREAD
~PluginAPI()
{
delete m_pRspThread;
m_pRspThread = NULL;
}
#endif
// Common
void MoveScreen(int /*_xpos*/, int /*_ypos*/) {}
void ProcessRDPList() {}
@ -70,10 +87,24 @@ public:
}
private:
PluginAPI() {}
PluginAPI()
#ifdef RSPTHREAD
: m_pRspThread(NULL), m_command(acNone)
#endif
{}
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()

View File

@ -3,6 +3,7 @@
#else
# include "../winlnxdefs.h"
#endif // _WINDOWS
#include <assert.h>
#include "../PluginAPI.h"
@ -12,16 +13,75 @@
#include "../RSP.h"
#include "../VI.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()
{
Lock lock(this);
LOG(LOG_APIFUNC, "ProcessDList\n");
#ifdef RSPTHREAD
_callAPICommand(acProcessDList);
#else
RSP_ProcessDList();
#endif
}
void PluginAPI::RomClosed()
{
LOG(LOG_APIFUNC, "RomClosed\n");
#ifdef RSPTHREAD
_callAPICommand(acRomClosed);
delete m_pRspThread;
m_pRspThread = NULL;
#else
OGL_Stop();
#endif
#ifdef DEBUG
CloseDebugDlg();
@ -30,9 +90,17 @@ void PluginAPI::RomClosed()
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();
OGL_ResizeWindow();
#endif
#ifdef DEBUG
OpenDebugDlg();
@ -46,11 +114,15 @@ void PluginAPI::ShowCFB()
void PluginAPI::UpdateScreen()
{
Lock lock(this);
LOG(LOG_APIFUNC, "UpdateScreen\n");
#ifdef RSPTHREAD
_callAPICommand(acUpdateScreen);
#else
VI_UpdateScreen();
#endif
}
void PluginAPI::_initiateGFX(const GFX_INFO & _gfxInfo) {
void PluginAPI::_initiateGFX(const GFX_INFO & _gfxInfo) const {
DMEM = _gfxInfo.DMEM;
IMEM = _gfxInfo.IMEM;
RDRAM = _gfxInfo.RDRAM;

View File

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

View File

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