diff --git a/app/backend/systemproperties.cpp b/app/backend/systemproperties.cpp index 570bfe92..d458d28b 100644 --- a/app/backend/systemproperties.cpp +++ b/app/backend/systemproperties.cpp @@ -51,6 +51,13 @@ void SystemProperties::querySdlVideoInfo() // Never let the maximum drop below 60 FPS maximumStreamingFrameRate = 60; + if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "SDL_InitSubSystem(SDL_INIT_VIDEO) failed: %s", + SDL_GetError()); + return; + } + SDL_DisplayMode bestMode; for (int displayIndex = 0; displayIndex < SDL_GetNumVideoDisplays(); displayIndex++) { SDL_DisplayMode desktopMode; @@ -91,6 +98,7 @@ void SystemProperties::querySdlVideoInfo() SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create window for hardware decode test: %s", SDL_GetError()); + SDL_QuitSubSystem(SDL_INIT_VIDEO); return; } @@ -101,4 +109,6 @@ void SystemProperties::querySdlVideoInfo() 1920, 1080, 60); SDL_DestroyWindow(testWindow); + + SDL_QuitSubSystem(SDL_INIT_VIDEO); } diff --git a/app/main.cpp b/app/main.cpp index e9b1b156..db35d182 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -314,17 +314,24 @@ int main(int argc, char *argv[]) // initializing the SDL video subsystem to have any effect. SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1"); - // Steam Link requires that we initialize video before creating our - // QGuiApplication in order to configure the framebuffer correctly. - // It's fine to do on other platforms too, and it can save some time - // doing initialization and teardown of the video subsystem after streaming. - if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { + if (SDL_InitSubSystem(SDL_INIT_TIMER) != 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER) failed: %s", + "SDL_InitSubSystem(SDL_INIT_TIMER) failed: %s", SDL_GetError()); return -1; } +#ifdef STEAM_LINK + // Steam Link requires that we initialize video before creating our + // QGuiApplication in order to configure the framebuffer correctly. + if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "SDL_InitSubSystem(SDL_INIT_VIDEO) failed: %s", + SDL_GetError()); + return -1; + } +#endif + // Use atexit() to ensure SDL_Quit() is called. This avoids // racing with object destruction where SDL may be used. atexit(SDL_Quit); diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index 85f8b903..eca57380 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -321,12 +321,20 @@ Session::~Session() bool Session::initialize() { + if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "SDL_InitSubSystem(SDL_INIT_VIDEO) failed: %s", + SDL_GetError()); + return false; + } + // Create a hidden window to use for decoder initialization tests SDL_Window* testWindow = SDL_CreateWindow("", 0, 0, 1280, 720, SDL_WINDOW_HIDDEN); if (!testWindow) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create window for hardware decode test: %s", SDL_GetError()); + SDL_QuitSubSystem(SDL_INIT_VIDEO); return false; } @@ -446,7 +454,12 @@ bool Session::initialize() SDL_DestroyWindow(testWindow); - return ret; + if (!ret) { + SDL_QuitSubSystem(SDL_INIT_VIDEO); + return false; + } + + return true; } void Session::emitLaunchWarning(QString text) @@ -875,12 +888,14 @@ void Session::exec(int displayOriginX, int displayOriginY) } catch (const GfeHttpResponseException& e) { delete m_InputHandler; m_InputHandler = nullptr; + SDL_QuitSubSystem(SDL_INIT_VIDEO); emit displayLaunchError("GeForce Experience returned error: " + e.toQString()); QThreadPool::globalInstance()->start(new DeferredSessionCleanupTask(this)); return; } catch (const QtNetworkReplyException& e) { delete m_InputHandler; m_InputHandler = nullptr; + SDL_QuitSubSystem(SDL_INIT_VIDEO); emit displayLaunchError(e.toQString()); QThreadPool::globalInstance()->start(new DeferredSessionCleanupTask(this)); return; @@ -911,6 +926,7 @@ void Session::exec(int displayOriginX, int displayOriginY) // listener. delete m_InputHandler; m_InputHandler = nullptr; + SDL_QuitSubSystem(SDL_INIT_VIDEO); QThreadPool::globalInstance()->start(new DeferredSessionCleanupTask(this)); return; } @@ -934,6 +950,7 @@ void Session::exec(int displayOriginX, int displayOriginY) SDL_GetError()); delete m_InputHandler; m_InputHandler = nullptr; + SDL_QuitSubSystem(SDL_INIT_VIDEO); QThreadPool::globalInstance()->start(new DeferredSessionCleanupTask(this)); return; } @@ -1236,6 +1253,8 @@ DispatchDeferredCleanup: SDL_FreeSurface(iconSurface); } + SDL_QuitSubSystem(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.