From 06f4d72631f181c4d1fa5d72273a2bc463165713 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sun, 16 Feb 2020 00:15:05 +0900 Subject: [PATCH] FrontendCommon: Use SDL_InitSubSystem() for lazy initialization --- src/duckstation-qt/qthostinterface.cpp | 2 +- src/duckstation-sdl/main.cpp | 10 +++------ src/frontend-common/CMakeLists.txt | 2 ++ src/frontend-common/frontend-common.vcxproj | 2 ++ .../frontend-common.vcxproj.filters | 2 ++ src/frontend-common/sdl_audio_stream.cpp | 11 ++++++++++ .../sdl_controller_interface.cpp | 21 ++++++++++--------- .../sdl_controller_interface.h | 4 ++-- src/frontend-common/sdl_initializer.cpp | 21 +++++++++++++++++++ src/frontend-common/sdl_initializer.h | 5 +++++ 10 files changed, 60 insertions(+), 20 deletions(-) create mode 100644 src/frontend-common/sdl_initializer.cpp create mode 100644 src/frontend-common/sdl_initializer.h diff --git a/src/duckstation-qt/qthostinterface.cpp b/src/duckstation-qt/qthostinterface.cpp index 4cd025d41..9cb9c4d98 100644 --- a/src/duckstation-qt/qthostinterface.cpp +++ b/src/duckstation-qt/qthostinterface.cpp @@ -783,7 +783,7 @@ void QtHostInterface::threadEntryPoint() m_worker_thread_event_loop = new QEventLoop(); // set up controller interface and immediate poll to pick up the controller attached events - g_sdl_controller_interface.Initialize(this, true); + g_sdl_controller_interface.Initialize(this); g_sdl_controller_interface.PumpSDLEvents(); doUpdateInputMap(); diff --git a/src/duckstation-sdl/main.cpp b/src/duckstation-sdl/main.cpp index 9e831aa2d..c05601f78 100644 --- a/src/duckstation-sdl/main.cpp +++ b/src/duckstation-sdl/main.cpp @@ -2,18 +2,12 @@ #include "common/log.h" #include "core/system.h" #include "sdl_host_interface.h" +#include "frontend-common/sdl_initializer.h" #include #include static int Run(int argc, char* argv[]) { - // init sdl - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) < 0) - { - Panic("SDL initialization failed"); - return -1; - } - // parameters std::optional state_index; const char* boot_filename = nullptr; @@ -82,6 +76,8 @@ int main(int argc, char* argv[]) // Log::SetFilterLevel(LOGLEVEL_DEV); #endif + FrontendCommon::EnsureSDLInitialized(); + // return NoGUITest(); return Run(argc, argv); } diff --git a/src/frontend-common/CMakeLists.txt b/src/frontend-common/CMakeLists.txt index a16b3df24..6b4db6749 100644 --- a/src/frontend-common/CMakeLists.txt +++ b/src/frontend-common/CMakeLists.txt @@ -7,6 +7,8 @@ add_library(frontend-common sdl_audio_stream.h sdl_controller_interface.cpp sdl_controller_interface.h + sdl_initializer.cpp + sdl_initializer.h ) target_include_directories(frontend-common PRIVATE ${SDL2_INCLUDE_DIRS}) diff --git a/src/frontend-common/frontend-common.vcxproj b/src/frontend-common/frontend-common.vcxproj index 158d815bf..62dad0cd0 100644 --- a/src/frontend-common/frontend-common.vcxproj +++ b/src/frontend-common/frontend-common.vcxproj @@ -50,12 +50,14 @@ + + diff --git a/src/frontend-common/frontend-common.vcxproj.filters b/src/frontend-common/frontend-common.vcxproj.filters index 3bb58c520..32e24c37c 100644 --- a/src/frontend-common/frontend-common.vcxproj.filters +++ b/src/frontend-common/frontend-common.vcxproj.filters @@ -5,12 +5,14 @@ + + diff --git a/src/frontend-common/sdl_audio_stream.cpp b/src/frontend-common/sdl_audio_stream.cpp index 490cdbc63..f928de341 100644 --- a/src/frontend-common/sdl_audio_stream.cpp +++ b/src/frontend-common/sdl_audio_stream.cpp @@ -1,4 +1,5 @@ #include "sdl_audio_stream.h" +#include "sdl_initializer.h" #include "common/assert.h" #include "common/log.h" #include @@ -21,6 +22,14 @@ bool SDLAudioStream::OpenDevice() { DebugAssert(!m_is_open); + FrontendCommon::EnsureSDLInitialized(); + + if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) + { + Log_ErrorPrintf("SDL_InitSubSystem(SDL_INIT_AUDIO) failed"); + return false; + } + SDL_AudioSpec spec = {}; spec.freq = m_output_sample_rate; spec.channels = static_cast(m_channels); @@ -32,6 +41,7 @@ bool SDLAudioStream::OpenDevice() if (SDL_OpenAudio(&spec, nullptr) < 0) { Log_ErrorPrintf("SDL_OpenAudio failed"); + SDL_QuitSubSystem(SDL_INIT_AUDIO); return false; } @@ -48,6 +58,7 @@ void SDLAudioStream::CloseDevice() { DebugAssert(m_is_open); SDL_CloseAudio(); + SDL_QuitSubSystem(SDL_INIT_AUDIO); m_is_open = false; } diff --git a/src/frontend-common/sdl_controller_interface.cpp b/src/frontend-common/sdl_controller_interface.cpp index a85e66638..08aa5579c 100644 --- a/src/frontend-common/sdl_controller_interface.cpp +++ b/src/frontend-common/sdl_controller_interface.cpp @@ -4,6 +4,7 @@ #include "core/controller.h" #include "core/host_interface.h" #include "core/system.h" +#include "sdl_initializer.h" #include Log_SetChannel(SDLControllerInterface); @@ -16,19 +17,19 @@ SDLControllerInterface::~SDLControllerInterface() Assert(m_controllers.empty()); } -bool SDLControllerInterface::Initialize(HostInterface* host_interface, bool init_sdl) +bool SDLControllerInterface::Initialize(HostInterface* host_interface) { - if (init_sdl) + FrontendCommon::EnsureSDLInitialized(); + + if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) < 0) { - if (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) < 0) - { - Log_ErrorPrintf("SDL_Init() failed"); - return false; - } + Log_ErrorPrintf("SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) failed"); + return false; } // we should open the controllers as the connected events come in, so no need to do any more here m_host_interface = host_interface; + m_initialized = true; return true; } @@ -37,10 +38,10 @@ void SDLControllerInterface::Shutdown() while (!m_controllers.empty()) CloseGameController(m_controllers.begin()->first); - if (m_sdl_initialized_by_us) + if (m_initialized) { - SDL_Quit(); - m_sdl_initialized_by_us = false; + SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC); + m_initialized = false; } m_host_interface = nullptr; diff --git a/src/frontend-common/sdl_controller_interface.h b/src/frontend-common/sdl_controller_interface.h index 003352b9f..54837aa58 100644 --- a/src/frontend-common/sdl_controller_interface.h +++ b/src/frontend-common/sdl_controller_interface.h @@ -26,7 +26,7 @@ public: SDLControllerInterface(); ~SDLControllerInterface(); - bool Initialize(HostInterface* host_interface, bool init_sdl); + bool Initialize(HostInterface* host_interface); void Shutdown(); // Removes all bindings. Call before setting new bindings. @@ -101,7 +101,7 @@ private: std::mutex m_event_intercept_mutex; Hook::Callback m_event_intercept_callback; - bool m_sdl_initialized_by_us = false; + bool m_initialized = false; }; extern SDLControllerInterface g_sdl_controller_interface; diff --git a/src/frontend-common/sdl_initializer.cpp b/src/frontend-common/sdl_initializer.cpp new file mode 100644 index 000000000..e69e6b204 --- /dev/null +++ b/src/frontend-common/sdl_initializer.cpp @@ -0,0 +1,21 @@ +#include "sdl_initializer.h" +#include "common/assert.h" +#include + +namespace FrontendCommon { +static bool s_sdl_initialized = false; + +void EnsureSDLInitialized() +{ + if (s_sdl_initialized) + return; + + if (SDL_Init(0) < 0) + { + Panic("SDL_Init(0) failed"); + return; + } + + s_sdl_initialized = true; +} +} // namespace FrontendCommon diff --git a/src/frontend-common/sdl_initializer.h b/src/frontend-common/sdl_initializer.h new file mode 100644 index 000000000..22af3c439 --- /dev/null +++ b/src/frontend-common/sdl_initializer.h @@ -0,0 +1,5 @@ +#pragma once + +namespace FrontendCommon { +void EnsureSDLInitialized(); +} \ No newline at end of file