mirror of https://github.com/PCSX2/pcsx2.git
Qt: Fix SDL initialization crash on macOS
This commit is contained in:
parent
9c61e9eda3
commit
d862f8cd53
|
@ -498,9 +498,9 @@ void EmuThread::reloadInputSources()
|
|||
return;
|
||||
}
|
||||
|
||||
auto lock = Host::GetSettingsLock();
|
||||
std::unique_lock<std::mutex> lock = Host::GetSettingsLock();
|
||||
SettingsInterface* si = Host::GetSettingsInterface();
|
||||
InputManager::ReloadSources(*si);
|
||||
InputManager::ReloadSources(*si, lock);
|
||||
|
||||
// skip loading bindings if we're not running, since it'll get done on startup anyway
|
||||
if (VMManager::HasValidVM())
|
||||
|
|
|
@ -955,19 +955,19 @@ GenericInputBindingMapping InputManager::GetGenericBindingMapping(const std::str
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
static void UpdateInputSourceState(SettingsInterface& si, InputSourceType type, bool default_state)
|
||||
static void UpdateInputSourceState(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock, InputSourceType type, bool default_state)
|
||||
{
|
||||
const bool enabled = si.GetBoolValue("InputSources", InputManager::InputSourceToString(type), default_state);
|
||||
if (enabled)
|
||||
{
|
||||
if (s_input_sources[static_cast<u32>(type)])
|
||||
{
|
||||
s_input_sources[static_cast<u32>(type)]->UpdateSettings(si);
|
||||
s_input_sources[static_cast<u32>(type)]->UpdateSettings(si, settings_lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unique_ptr<InputSource> source = std::make_unique<T>();
|
||||
if (!source->Initialize(si))
|
||||
if (!source->Initialize(si, settings_lock))
|
||||
{
|
||||
Console.Error("(InputManager) Source '%s' failed to initialize.", InputManager::InputSourceToString(type));
|
||||
return;
|
||||
|
@ -994,12 +994,12 @@ static void UpdateInputSourceState(SettingsInterface& si, InputSourceType type,
|
|||
#include "Frontend/SDLInputSource.h"
|
||||
#endif
|
||||
|
||||
void InputManager::ReloadSources(SettingsInterface& si)
|
||||
void InputManager::ReloadSources(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
UpdateInputSourceState<XInputSource>(si, InputSourceType::XInput, false);
|
||||
UpdateInputSourceState<XInputSource>(si, settings_lock, InputSourceType::XInput, false);
|
||||
#endif
|
||||
#ifdef SDL_BUILD
|
||||
UpdateInputSourceState<SDLInputSource>(si, InputSourceType::SDL, true);
|
||||
UpdateInputSourceState<SDLInputSource>(si, settings_lock, InputSourceType::SDL, true);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -229,7 +229,7 @@ namespace InputManager
|
|||
void ReloadBindings(SettingsInterface& si);
|
||||
|
||||
/// Re-parses the sources part of the config and initializes any backends.
|
||||
void ReloadSources(SettingsInterface& si);
|
||||
void ReloadSources(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock);
|
||||
|
||||
/// Shuts down any enabled input sources.
|
||||
void CloseSources();
|
||||
|
@ -271,4 +271,4 @@ namespace Host
|
|||
|
||||
/// Called when an input device is disconnected.
|
||||
void OnInputDeviceDisconnected(const std::string_view& identifier);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ public:
|
|||
InputSource();
|
||||
virtual ~InputSource();
|
||||
|
||||
virtual bool Initialize(SettingsInterface& si) = 0;
|
||||
virtual void UpdateSettings(SettingsInterface& si) = 0;
|
||||
virtual bool Initialize(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) = 0;
|
||||
virtual void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual void PollEvents() = 0;
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include "common/StringUtil.h"
|
||||
#include "common/Console.h"
|
||||
#include <cmath>
|
||||
#ifdef __APPLE__
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
|
||||
static const char* s_sdl_axis_names[] = {
|
||||
"LeftX", // SDL_CONTROLLER_AXIS_LEFTX
|
||||
|
@ -91,7 +94,7 @@ SDLInputSource::SDLInputSource() = default;
|
|||
|
||||
SDLInputSource::~SDLInputSource() { pxAssert(m_controllers.empty()); }
|
||||
|
||||
bool SDLInputSource::Initialize(SettingsInterface& si)
|
||||
bool SDLInputSource::Initialize(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock)
|
||||
{
|
||||
std::optional<std::vector<u8>> controller_db_data = Host::ReadResourceFile("game_controller_db.txt");
|
||||
if (controller_db_data.has_value())
|
||||
|
@ -106,11 +109,14 @@ bool SDLInputSource::Initialize(SettingsInterface& si)
|
|||
}
|
||||
|
||||
LoadSettings(si);
|
||||
settings_lock.unlock();
|
||||
SetHints();
|
||||
return InitializeSubsystem();
|
||||
bool result = InitializeSubsystem();
|
||||
settings_lock.lock();
|
||||
return result;
|
||||
}
|
||||
|
||||
void SDLInputSource::UpdateSettings(SettingsInterface& si)
|
||||
void SDLInputSource::UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock)
|
||||
{
|
||||
const bool old_controller_enhanced_mode = m_controller_enhanced_mode;
|
||||
|
||||
|
@ -118,9 +124,11 @@ void SDLInputSource::UpdateSettings(SettingsInterface& si)
|
|||
|
||||
if (m_controller_enhanced_mode != old_controller_enhanced_mode)
|
||||
{
|
||||
settings_lock.unlock();
|
||||
ShutdownSubsystem();
|
||||
SetHints();
|
||||
InitializeSubsystem();
|
||||
settings_lock.lock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +150,17 @@ void SDLInputSource::SetHints()
|
|||
|
||||
bool SDLInputSource::InitializeSubsystem()
|
||||
{
|
||||
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) < 0)
|
||||
int result;
|
||||
#ifdef __APPLE__
|
||||
// On macOS, SDL_InitSubSystem runs a main-thread-only call to some GameController framework method
|
||||
// So send this to be run on the main thread
|
||||
dispatch_sync_f(dispatch_get_main_queue(), &result, [](void* ctx){
|
||||
*static_cast<int*>(ctx) = SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC);
|
||||
});
|
||||
#else
|
||||
result = SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC);
|
||||
#endif
|
||||
if (result < 0)
|
||||
{
|
||||
Console.Error("SDL_InitSubSystem(SDL_INIT_JOYSTICK |SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) failed");
|
||||
return false;
|
||||
|
@ -160,7 +178,13 @@ void SDLInputSource::ShutdownSubsystem()
|
|||
|
||||
if (m_sdl_subsystem_initialized)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
dispatch_sync_f(dispatch_get_main_queue(), nullptr, [](void*){
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC);
|
||||
});
|
||||
#else
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC);
|
||||
#endif
|
||||
m_sdl_subsystem_initialized = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ public:
|
|||
SDLInputSource();
|
||||
~SDLInputSource();
|
||||
|
||||
bool Initialize(SettingsInterface& si) override;
|
||||
void UpdateSettings(SettingsInterface& si) override;
|
||||
bool Initialize(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
||||
void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
||||
void Shutdown() override;
|
||||
|
||||
void PollEvents() override;
|
||||
|
|
|
@ -94,7 +94,7 @@ XInputSource::XInputSource() = default;
|
|||
|
||||
XInputSource::~XInputSource() = default;
|
||||
|
||||
bool XInputSource::Initialize(SettingsInterface& si)
|
||||
bool XInputSource::Initialize(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock)
|
||||
{
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
// xinput1_3.dll is flawed and obsolete, but it's also commonly used by wrappers.
|
||||
|
@ -142,7 +142,7 @@ bool XInputSource::Initialize(SettingsInterface& si)
|
|||
return true;
|
||||
}
|
||||
|
||||
void XInputSource::UpdateSettings(SettingsInterface& si)
|
||||
void XInputSource::UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -63,8 +63,8 @@ public:
|
|||
XInputSource();
|
||||
~XInputSource();
|
||||
|
||||
bool Initialize(SettingsInterface& si) override;
|
||||
void UpdateSettings(SettingsInterface& si) override;
|
||||
bool Initialize(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
||||
void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
||||
void Shutdown() override;
|
||||
|
||||
void PollEvents() override;
|
||||
|
|
|
@ -292,12 +292,12 @@ SysCpuProviderPack& GetCpuProviders()
|
|||
|
||||
void VMManager::LoadSettings()
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
std::unique_lock<std::mutex> lock = Host::GetSettingsLock();
|
||||
SettingsInterface* si = Host::GetSettingsInterface();
|
||||
SettingsLoadWrapper slw(*si);
|
||||
EmuConfig.LoadSave(slw);
|
||||
PAD::LoadConfig(*si);
|
||||
InputManager::ReloadSources(*si);
|
||||
InputManager::ReloadSources(*si, lock);
|
||||
InputManager::ReloadBindings(*si);
|
||||
|
||||
// Remove any user-specified hacks in the config (we don't want stale/conflicting values when it's globally disabled).
|
||||
|
|
Loading…
Reference in New Issue