mtgs: ensure thread safety, reimplement coreplugins intermediate layer

This commit is contained in:
Gauvain 'GovanifY' Roussel-Tarbouriech 2021-05-11 17:32:41 +02:00 committed by Kojin
parent 160117ffbb
commit ada56a1c03
4 changed files with 10 additions and 139 deletions

View File

@ -23,6 +23,8 @@
#include "Gif_Unit.h"
#include "MTVU.h"
#include "Elfheader.h"
#include "App.h"
#include "gui/Dialogs/ModalPopups.h"
#ifdef _WIN32
#include "PAD/Windows/PAD.h"
#else
@ -209,7 +211,7 @@ void SysMtgsThread::OpenGS()
GSsetBaseMem(RingBuffer.Regs);
GSirqCallback(dummyIrqCallback);
pxAssert(GSopen2((void*)pDsp, 1 | (renderswitch ? 4 : 0)) != 0);
pxAssert(GSopen2((void**)pDsp, 1 | (renderswitch ? 4 : 0)) != 0);
GSsetVsync(EmuConfig.GS.GetVsync());
@ -553,10 +555,10 @@ void SysMtgsThread::ExecuteTaskInThread()
void SysMtgsThread::CloseGS()
{
if (!m_Opened)
if (!m_Opened || GSDump::isRunning)
return;
m_Opened = false;
GetCorePlugins().Close(PluginId_GS);
Suspend();
}
void SysMtgsThread::OnSuspendInThread()
@ -875,9 +877,6 @@ void SysMtgsThread::WaitForOpen()
{
RethrowException();
// Not opened yet, and no exceptions. Weird? You decide!
// [TODO] : implement a user confirmation to cancel the action and exit the
// emulator forcefully, or to continue waiting on the GS.
pxAssert(_("The MTGS thread has become unresponsive while waiting for the GS plugin to open."));
}
}
@ -887,7 +886,7 @@ void SysMtgsThread::WaitForOpen()
void SysMtgsThread::Freeze(int mode, MTGS_FreezeData& data)
{
GetCorePlugins().Open(PluginId_GS);
Resume();
SendPointerPacket(GS_RINGTYPE_FREEZE, mode, &data);
Resume();
WaitGS();

View File

@ -45,6 +45,8 @@ typedef struct _keyEvent
u32 evt;
} keyEvent;
uptr pDsp[2];
typedef void FnType_OnThreadComplete(const wxCommandEvent& evt);
typedef void (Pcsx2App::*FnPtr_Pcsx2App)();

View File

@ -97,7 +97,6 @@ protected:
wxWizardPageSimple& m_page_bios;
wxPanelWithHelpers& m_panel_Intro;
Panels::PluginSelectorPanel& m_panel_PluginSel;
Panels::BiosSelectorPanel& m_panel_BiosSel;
public:
@ -106,11 +105,6 @@ public:
wxWizardPage* GetFirstPage() const { return &m_page_intro; }
void ForceEnumPlugins()
{
m_panel_PluginSel.OnShown();
}
int ShowModal();
protected:
@ -425,4 +419,4 @@ wxWindowID pxIssueConfirmation(wxDialogWithHelpers& confirmDlg, const MsgButtons
namespace GSDump
{
extern bool isRunning;
}
}

View File

@ -467,128 +467,4 @@ namespace Panels
virtual void DoRefresh();
virtual bool ValidateEnumerationStatus();
};
// --------------------------------------------------------------------------------------
// PluginSelectorPanel
// --------------------------------------------------------------------------------------
class PluginSelectorPanel: public BaseSelectorPanel,
public EventListener_Plugins
{
protected:
// ----------------------------------------------------------------------------
class EnumeratedPluginInfo
{
public:
uint PassedTest; // msk specifying which plugin types passed the mask test.
uint TypeMask; // indicates which combo boxes it should be listed in
wxString Name; // string to be pasted into the combo box
wxString Version[PluginId_Count];
EnumeratedPluginInfo()
{
PassedTest = 0;
TypeMask = 0;
}
};
// ----------------------------------------------------------------------------
class EnumThread : public Threading::pxThread
{
public:
std::vector<EnumeratedPluginInfo> Results; // array of plugin results.
protected:
PluginSelectorPanel& m_master;
ScopedBusyCursor m_hourglass;
public:
virtual ~EnumThread()
{
try {
pxThread::Cancel();
}
DESTRUCTOR_CATCHALL
}
EnumThread( PluginSelectorPanel& master );
void DoNextPlugin( int evtidx );
protected:
void ExecuteTaskInThread();
};
// ----------------------------------------------------------------------------
// This panel contains all of the plugin combo boxes. We stick them
// on a panel together so that we can hide/show the whole mess easily.
class ComboBoxPanel : public wxPanelWithHelpers
{
protected:
wxComboBox* m_combobox[PluginId_Count];
wxButton* m_configbutton[PluginId_Count];
DirPickerPanel& m_FolderPicker;
public:
ComboBoxPanel( PluginSelectorPanel* parent );
wxComboBox& Get( PluginsEnum_t pid ) { return *m_combobox[pid]; }
wxButton& GetConfigButton( PluginsEnum_t pid ) { return *m_configbutton[pid]; }
wxDirName GetPluginsPath() const { return m_FolderPicker.GetPath(); }
DirPickerPanel& GetDirPicker() { return m_FolderPicker; }
void Reset();
};
// ----------------------------------------------------------------------------
class StatusPanel : public wxPanelWithHelpers
{
protected:
wxGauge& m_gauge;
wxStaticText& m_label;
int m_progress;
public:
StatusPanel( wxWindow* parent );
void SetGaugeLength( int len );
void AdvanceProgress( const wxString& msg );
void Reset();
};
// ------------------------------------------------------------------------
// PluginSelectorPanel Members
protected:
StatusPanel* m_StatusPanel;
ComboBoxPanel* m_ComponentBoxes;
bool m_Canceled;
std::unique_ptr<wxArrayString> m_FileList; // list of potential plugin files
std::unique_ptr<EnumThread> m_EnumeratorThread;
public:
virtual ~PluginSelectorPanel();
PluginSelectorPanel( wxWindow* parent );
void CancelRefresh(); // used from destructor, stays non-virtual
void Apply();
protected:
void DispatchEvent( const PluginEventType& evt );
void OnConfigure_Clicked( wxCommandEvent& evt );
void OnShowStatusBar( wxCommandEvent& evt );
void OnPluginSelected( wxCommandEvent& evt );
virtual void OnProgress( wxCommandEvent& evt );
virtual void OnEnumComplete( wxCommandEvent& evt );
virtual void AppStatusEvent_OnSettingsApplied();
virtual void DoRefresh();
virtual bool ValidateEnumerationStatus();
int FileCount() const { return m_FileList->Count(); }
const wxString& GetFilename( int i ) const { return (*m_FileList)[i]; }
friend class EnumThread;
};
}
} // namespace Panels