Move SDL subsystem init into appropriate components to fix gamepad detection issue

This commit is contained in:
Cameron Gutman 2018-07-20 18:15:46 -07:00
parent e516861366
commit 4c507f1179
4 changed files with 71 additions and 15 deletions

View file

@ -53,12 +53,8 @@ int main(int argc, char *argv[])
if (engine.rootObjects().isEmpty()) if (engine.rootObjects().isEmpty())
return -1; return -1;
// Ensure that SDL is always initialized since we may need to use it
// for non-streaming purposes (like checking on audio devices)
SDL_SetMainReady(); SDL_SetMainReady();
if (SDL_Init(SDL_INIT_VIDEO | if (SDL_Init(0) != 0) {
SDL_INIT_AUDIO |
SDL_INIT_GAMECONTROLLER) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_Init() failed: %s", "SDL_Init() failed: %s",
SDL_GetError()); SDL_GetError());

View file

@ -23,6 +23,14 @@ int Session::sdlDetermineAudioConfiguration()
{ {
SDL_AudioSpec want, have; SDL_AudioSpec want, have;
SDL_AudioDeviceID dev; SDL_AudioDeviceID dev;
int ret;
if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_InitSubSystem(SDL_INIT_AUDIO) failed: %s",
SDL_GetError());
return AUDIO_CONFIGURATION_STEREO;
}
SDL_zero(want); SDL_zero(want);
want.freq = 48000; want.freq = 48000;
@ -38,7 +46,8 @@ int Session::sdlDetermineAudioConfiguration()
"Failed to open audio device"); "Failed to open audio device");
// We'll probably have issues during audio stream init, but we'll // We'll probably have issues during audio stream init, but we'll
// try anyway // try anyway
return AUDIO_CONFIGURATION_STEREO; ret = AUDIO_CONFIGURATION_STEREO;
goto Exit;
} }
SDL_CloseAudioDevice(dev); SDL_CloseAudioDevice(dev);
@ -50,11 +59,15 @@ int Session::sdlDetermineAudioConfiguration()
// We don't support quadraphonic or 7.1 surround, but SDL // We don't support quadraphonic or 7.1 surround, but SDL
// should be able to downmix or upmix better from 5.1 than // should be able to downmix or upmix better from 5.1 than
// from stereo, so use 5.1 in non-stereo cases. // from stereo, so use 5.1 in non-stereo cases.
return AUDIO_CONFIGURATION_51_SURROUND; ret = AUDIO_CONFIGURATION_51_SURROUND;
} }
else { else {
return AUDIO_CONFIGURATION_STEREO; ret = AUDIO_CONFIGURATION_STEREO;
} }
Exit:
SDL_QuitSubSystem(SDL_INIT_AUDIO);
return ret;
} }
int Session::sdlAudioInit(int /* audioConfiguration */, int Session::sdlAudioInit(int /* audioConfiguration */,
@ -64,6 +77,14 @@ int Session::sdlAudioInit(int /* audioConfiguration */,
SDL_AudioSpec want, have; SDL_AudioSpec want, have;
int error; int error;
SDL_assert(!SDL_WasInit(SDL_INIT_AUDIO));
if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_InitSubSystem(SDL_INIT_AUDIO) failed: %s",
SDL_GetError());
return AUDIO_CONFIGURATION_STEREO;
}
SDL_zero(want); SDL_zero(want);
want.freq = opusConfig->sampleRate; want.freq = opusConfig->sampleRate;
want.format = AUDIO_S16; want.format = AUDIO_S16;
@ -80,6 +101,7 @@ int Session::sdlAudioInit(int /* audioConfiguration */,
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to open audio device: %s", "Failed to open audio device: %s",
SDL_GetError()); SDL_GetError());
SDL_QuitSubSystem(SDL_INIT_AUDIO);
return -1; return -1;
} }
@ -95,6 +117,7 @@ int Session::sdlAudioInit(int /* audioConfiguration */,
error); error);
SDL_CloseAudioDevice(s_AudioDevice); SDL_CloseAudioDevice(s_AudioDevice);
s_AudioDevice = 0; s_AudioDevice = 0;
SDL_QuitSubSystem(SDL_INIT_AUDIO);
return -2; return -2;
} }
@ -140,7 +163,10 @@ void Session::sdlAudioCleanup()
s_AudioDevice = 0; s_AudioDevice = 0;
opus_multistream_decoder_destroy(s_OpusDecoder); opus_multistream_decoder_destroy(s_OpusDecoder);
s_OpusDecoder = NULL; s_OpusDecoder = nullptr;
SDL_QuitSubSystem(SDL_INIT_AUDIO);
SDL_assert(!SDL_WasInit(SDL_INIT_AUDIO));
} }
void Session::sdlAudioDecodeAndPlaySample(char* sampleData, int sampleLength) void Session::sdlAudioDecodeAndPlaySample(char* sampleData, int sampleLength)

View file

@ -23,6 +23,15 @@ const int SdlInputHandler::k_ButtonMap[] = {
SdlInputHandler::SdlInputHandler(bool multiController) SdlInputHandler::SdlInputHandler(bool multiController)
: m_MultiController(multiController) : m_MultiController(multiController)
{ {
// We need to reinit this each time, since you only get
// an initial set of gamepad arrival events once per init.
SDL_assert(!SDL_WasInit(SDL_INIT_GAMECONTROLLER));
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) failed: %s",
SDL_GetError());
}
if (!m_MultiController) { if (!m_MultiController) {
// Player 1 is always present in non-MC mode // Player 1 is always present in non-MC mode
m_GamepadMask = 0x1; m_GamepadMask = 0x1;
@ -38,6 +47,9 @@ SdlInputHandler::~SdlInputHandler()
SDL_GameControllerClose(m_GamepadState[i].controller); SDL_GameControllerClose(m_GamepadState[i].controller);
} }
} }
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
SDL_assert(!SDL_WasInit(SDL_INIT_GAMECONTROLLER));
} }
void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event) void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)

View file

@ -149,23 +149,35 @@ bool Session::isHardwareDecodeAvailable(StreamingPreferences::VideoDecoderSelect
{ {
IVideoDecoder* decoder; IVideoDecoder* decoder;
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_InitSubSystem(SDL_INIT_VIDEO) failed: %s",
SDL_GetError());
return false;
}
SDL_Window* window = SDL_CreateWindow("", 0, 0, width, height, SDL_WINDOW_HIDDEN); SDL_Window* window = SDL_CreateWindow("", 0, 0, width, height, SDL_WINDOW_HIDDEN);
if (!window) { if (!window) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to create window for hardware decode test: %s", "Failed to create window for hardware decode test: %s",
SDL_GetError()); SDL_GetError());
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return false; return false;
} }
if (!chooseDecoder(vds, window, videoFormat, width, height, frameRate, decoder)) { if (!chooseDecoder(vds, window, videoFormat, width, height, frameRate, decoder)) {
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return false; return false;
} }
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
bool ret = decoder->isHardwareAccelerated(); bool ret = decoder->isHardwareAccelerated();
delete decoder; delete decoder;
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return ret; return ret;
} }
@ -335,9 +347,6 @@ class DeferredSessionCleanupTask : public QRunnable
{ {
// Finish cleanup of the connection state // Finish cleanup of the connection state
LiStopConnection(); LiStopConnection();
if (Session::s_ActiveSession->m_Window != nullptr) {
SDL_DestroyWindow(Session::s_ActiveSession->m_Window);
}
// Allow another session to start now that we're cleaned up // Allow another session to start now that we're cleaned up
Session::s_ActiveSession = nullptr; Session::s_ActiveSession = nullptr;
@ -473,6 +482,16 @@ void Session::exec()
return; return;
} }
SDL_assert(!SDL_WasInit(SDL_INIT_VIDEO));
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_InitSubSystem(SDL_INIT_VIDEO) failed: %s",
SDL_GetError());
emit displayLaunchError(QString::fromLocal8Bit(SDL_GetError()));
s_ActiveSessionSemaphore.release();
return;
}
int flags = SDL_WINDOW_HIDDEN; int flags = SDL_WINDOW_HIDDEN;
int x, y, width, height; int x, y, width, height;
if (m_Preferences.fullScreen) { if (m_Preferences.fullScreen) {
@ -493,6 +512,7 @@ void Session::exec()
"SDL_CreateWindow() failed: %s", "SDL_CreateWindow() failed: %s",
SDL_GetError()); SDL_GetError());
s_ActiveSessionSemaphore.release(); s_ActiveSessionSemaphore.release();
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return; return;
} }
@ -519,6 +539,7 @@ void Session::exec()
// We already displayed an error dialog in the stage failure // We already displayed an error dialog in the stage failure
// listener. // listener.
s_ActiveSessionSemaphore.release(); s_ActiveSessionSemaphore.release();
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return; return;
} }
@ -634,9 +655,6 @@ DispatchDeferredCleanup:
// so we can return to the Qt GUI ASAP. // so we can return to the Qt GUI ASAP.
SDL_SetRelativeMouseMode(SDL_FALSE); SDL_SetRelativeMouseMode(SDL_FALSE);
SDL_EnableScreenSaver(); SDL_EnableScreenSaver();
if (m_Window != nullptr) {
SDL_HideWindow(m_Window);
}
// Destroy the decoder, since this must be done on the main thread // Destroy the decoder, since this must be done on the main thread
SDL_AtomicLock(&m_DecoderLock); SDL_AtomicLock(&m_DecoderLock);
@ -644,6 +662,10 @@ DispatchDeferredCleanup:
m_VideoDecoder = nullptr; m_VideoDecoder = nullptr;
SDL_AtomicUnlock(&m_DecoderLock); SDL_AtomicUnlock(&m_DecoderLock);
SDL_DestroyWindow(m_Window);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
SDL_assert(!SDL_WasInit(SDL_INIT_VIDEO));
// Cleanup can take a while, so dispatch it to a worker thread. // Cleanup can take a while, so dispatch it to a worker thread.
// When it is complete, it will release our s_ActiveSessionSemaphore // When it is complete, it will release our s_ActiveSessionSemaphore
// reference. // reference.