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