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())
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();
if (SDL_Init(SDL_INIT_VIDEO |
SDL_INIT_AUDIO |
SDL_INIT_GAMECONTROLLER) != 0) {
if (SDL_Init(0) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_Init() failed: %s",
SDL_GetError());

View file

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

View file

@ -23,6 +23,15 @@ const int SdlInputHandler::k_ButtonMap[] = {
SdlInputHandler::SdlInputHandler(bool 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) {
// Player 1 is always present in non-MC mode
m_GamepadMask = 0x1;
@ -38,6 +47,9 @@ SdlInputHandler::~SdlInputHandler()
SDL_GameControllerClose(m_GamepadState[i].controller);
}
}
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
SDL_assert(!SDL_WasInit(SDL_INIT_GAMECONTROLLER));
}
void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)

View file

@ -149,23 +149,35 @@ bool Session::isHardwareDecodeAvailable(StreamingPreferences::VideoDecoderSelect
{
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);
if (!window) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to create window for hardware decode test: %s",
SDL_GetError());
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return false;
}
if (!chooseDecoder(vds, window, videoFormat, width, height, frameRate, decoder)) {
SDL_DestroyWindow(window);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return false;
}
SDL_DestroyWindow(window);
bool ret = decoder->isHardwareAccelerated();
delete decoder;
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return ret;
}
@ -335,9 +347,6 @@ class DeferredSessionCleanupTask : public QRunnable
{
// Finish cleanup of the connection state
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
Session::s_ActiveSession = nullptr;
@ -473,6 +482,16 @@ void Session::exec()
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 x, y, width, height;
if (m_Preferences.fullScreen) {
@ -493,6 +512,7 @@ void Session::exec()
"SDL_CreateWindow() failed: %s",
SDL_GetError());
s_ActiveSessionSemaphore.release();
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return;
}
@ -519,6 +539,7 @@ void Session::exec()
// We already displayed an error dialog in the stage failure
// listener.
s_ActiveSessionSemaphore.release();
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return;
}
@ -634,9 +655,6 @@ DispatchDeferredCleanup:
// so we can return to the Qt GUI ASAP.
SDL_SetRelativeMouseMode(SDL_FALSE);
SDL_EnableScreenSaver();
if (m_Window != nullptr) {
SDL_HideWindow(m_Window);
}
// Destroy the decoder, since this must be done on the main thread
SDL_AtomicLock(&m_DecoderLock);
@ -644,6 +662,10 @@ DispatchDeferredCleanup:
m_VideoDecoder = nullptr;
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.
// When it is complete, it will release our s_ActiveSessionSemaphore
// reference.