From d926ef0bbedf49d8560d0320ccf6debcb91dfc6b Mon Sep 17 00:00:00 2001 From: Nathan Fulton Date: Mon, 14 Mar 2016 14:35:15 -0400 Subject: [PATCH] Prevent SDL from rendering when app is backgrounded On some platforms, the game will crash if SDL attempts to render to the screen/window while the game is backgrounded. To prevent this, stop rendering when the game enters a background state and resume rendering when the game enters a foreground state. --- game/sdl/display.cpp | 8 ++++++++ game/sdl/host.cpp | 19 +++++++++++++++++++ game/sdl/htplatform.h | 2 ++ game/sdl/mac/AppDelegate.mm | 4 ++-- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/game/sdl/display.cpp b/game/sdl/display.cpp index 040c154..a24eeb2 100644 --- a/game/sdl/display.cpp +++ b/game/sdl/display.cpp @@ -89,6 +89,7 @@ bool Display::Init() } renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_TARGETTEXTURE); + this->SetShouldRender(true); // Keep the screen size around s_siz.cx = cxScreen; @@ -269,6 +270,9 @@ void Display::FrameComplete(int cfrmm, UpdateMap **apupd, Rect *arc, } void Display::RenderGameSurface() { + if (!m_fshouldRender) + return; + // Create the texture texture = SDL_CreateTextureFromSurface(renderer, m_gameSurface); @@ -311,4 +315,8 @@ float Display::Density() { return m_density; } +void Display::SetShouldRender(bool fsr) { + m_fshouldRender = fsr; +} + } // namespace wi diff --git a/game/sdl/host.cpp b/game/sdl/host.cpp index e4d3f03..a21d1a9 100644 --- a/game/sdl/host.cpp +++ b/game/sdl/host.cpp @@ -220,6 +220,25 @@ bool ProcessSdlEvent(Event *pevt) } break; + case SDL_APP_DIDENTERFOREGROUND: + // Allow the display to render + gpdisp->SetShouldRender(true); + + // SDL may have released its graphics context if the app was previously + // backgrounded. This leaves the screen black when the user returns. + // Hack: Draw dib and render + gpmfrmm->DrawFrame(true); + gpdisp->RenderGameSurface(); + + break; + + case SDL_APP_WILLENTERBACKGROUND: + // Stop display rendering; SDL may release its graphics context when + // backgrounded, so we don't want to try to render to a non-existant context. + gpdisp->SetShouldRender(false); + + break; + case SDL_QUIT: pevt->eType = appStopEvent; break; diff --git a/game/sdl/htplatform.h b/game/sdl/htplatform.h index 3a2c1c3..f397f7b 100644 --- a/game/sdl/htplatform.h +++ b/game/sdl/htplatform.h @@ -123,6 +123,7 @@ public: void SetFormMgrs(FormMgr *pfrmmSim, FormMgr *pfrmmInput); void RenderGameSurface(); float Density(); + void SetShouldRender(bool fsr); private: int m_imode; @@ -145,6 +146,7 @@ private: Uint32 m_32bppColors[256]; int m_pixelCount; float m_density; + bool m_fshouldRender; }; #define kfDtClearLine 1 diff --git a/game/sdl/mac/AppDelegate.mm b/game/sdl/mac/AppDelegate.mm index a09aa58..192ef24 100644 --- a/game/sdl/mac/AppDelegate.mm +++ b/game/sdl/mac/AppDelegate.mm @@ -31,11 +31,11 @@ // as they do something else. - (void)applicationDidBecomeActive:(NSNotification *)notification { - // See host.cpp case SDL_APP_DIDENTERFOREGROUND + wi::HostAppDidEnterForeground(); } - (void)applicationWillResignActive:(NSNotification *)notification { - // See host.cpp case SDL_APP_WILLENTERBACKGROUND + wi::HostAppWillEnterBackground(); } #endif