From eafac57d1d684ce9f26466c296789565d85b07ec Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Thu, 14 Oct 2021 19:35:49 +0200 Subject: [PATCH] fixes #834 (major renderer memory leak) --- src/common/FBBackendSDL2.cxx | 15 ++++++--------- src/common/FBBackendSDL2.hxx | 4 +--- src/gui/Dialog.cxx | 2 +- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/common/FBBackendSDL2.cxx b/src/common/FBBackendSDL2.cxx index 566d9d713..e205ac28b 100644 --- a/src/common/FBBackendSDL2.cxx +++ b/src/common/FBBackendSDL2.cxx @@ -230,7 +230,6 @@ bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode, return false; const bool fullScreen = mode.fsIndex != -1; - bool forceCreateRenderer = false; Int32 displayIndex = std::min(myNumDisplays - 1, winIdx); int posX, posY; @@ -292,6 +291,9 @@ bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode, if(d != displayIndex || uInt32(w) != mode.screenS.w || uInt32(h) != mode.screenS.h || adaptRefresh) { + // Renderer has to be destroyed *before* the window gets destroyed to avoid memory leaks + SDL_DestroyRenderer(myRenderer); + myRenderer = nullptr; SDL_DestroyWindow(myWindow); myWindow = nullptr; } @@ -305,7 +307,6 @@ bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode, } else { - forceCreateRenderer = true; myWindow = SDL_CreateWindow(myScreenTitle.c_str(), posX, posY, mode.screenS.w, mode.screenS.h, flags); if(myWindow == nullptr) @@ -337,7 +338,7 @@ bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode, } #endif - return createRenderer(forceCreateRenderer); + return createRenderer(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -400,16 +401,15 @@ bool FBBackendSDL2::adaptRefreshRate(Int32 displayIndex, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FBBackendSDL2::createRenderer(bool force) +bool FBBackendSDL2::createRenderer() { ASSERT_MAIN_THREAD; // A new renderer is only created when necessary: - // - new myWindow (force = true) // - no renderer existing // - different renderer flags // - different renderer name - bool recreate = force || myRenderer == nullptr; + bool recreate = myRenderer == nullptr; uInt32 renderFlags = SDL_RENDERER_ACCELERATED; const string& video = myOSystem.settings().getString("video"); // Render hint SDL_RendererInfo renderInfo; @@ -426,9 +426,6 @@ bool FBBackendSDL2::createRenderer(bool force) if(recreate) { //cerr << "Create new renderer for buffer type #" << int(myBufferType) << endl; - if(myRenderer) - SDL_DestroyRenderer(myRenderer); - if(video != "") SDL_SetHint(SDL_HINT_RENDER_DRIVER, video.c_str()); diff --git a/src/common/FBBackendSDL2.hxx b/src/common/FBBackendSDL2.hxx index 32da839d2..5ada52c6c 100644 --- a/src/common/FBBackendSDL2.hxx +++ b/src/common/FBBackendSDL2.hxx @@ -208,11 +208,9 @@ class FBBackendSDL2 : public FBBackend /** Create a new renderer if required. - @param force If true, force new renderer creation - @return False on any errors, else true */ - bool createRenderer(bool force); + bool createRenderer(); /** This method must be called after all drawing is done, and indicates diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index c615ed8fb..9b7f59f64 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -346,7 +346,7 @@ void Dialog::render() _renderCallback(); // A dialog is still on top if a non-shading dialog (e.g. ContextMenu) - // is opended above it. + // is opened above it. bool onTop = parent().myDialogStack.top() == this || (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this && !parent().myDialogStack.top()->isShading());