diff --git a/src/common/FBSurfaceSDL2.cxx b/src/common/FBSurfaceSDL2.cxx index 0178af4d6..385f4aff5 100644 --- a/src/common/FBSurfaceSDL2.cxx +++ b/src/common/FBSurfaceSDL2.cxx @@ -37,7 +37,10 @@ FBSurfaceSDL2::FBSurfaceSDL2(FrameBufferSDL2& buffer, FBSurfaceSDL2::~FBSurfaceSDL2() { if(mySurface) + { SDL_FreeSurface(mySurface); + mySurface = nullptr; + } free(); } diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 61baf8e0b..9ac36fcfa 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -59,6 +59,12 @@ FrameBufferSDL2::~FrameBufferSDL2() if(myRenderer) { + // Make sure to free surfaces/textures before destroying the renderer itself + // Most platforms are fine with doing this in either order, but it seems + // that OpenBSD in particular crashes when attempting to destroy textures + // *after* the renderer is already destroyed + freeSurfaces(); + SDL_DestroyRenderer(myRenderer); myRenderer = nullptr; } diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index c05674b86..a0aa1f4a7 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -552,6 +552,20 @@ shared_ptr FrameBuffer::allocateSurface(int w, int h, const uInt32* d return mySurfaceList.at(mySurfaceList.size() - 1); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FrameBuffer::freeSurfaces() +{ + for(auto& s: mySurfaceList) + s->free(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FrameBuffer::reloadSurfaces() +{ + for(auto& s: mySurfaceList) + s->reload(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBuffer::resetSurfaces() { @@ -561,10 +575,8 @@ void FrameBuffer::resetSurfaces() // Any derived FrameBuffer classes that call this method should be // aware of these restrictions, and act accordingly - for(auto& s: mySurfaceList) - s->free(); - for(auto& s: mySurfaceList) - s->reload(); + freeSurfaces(); + reloadSurfaces(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index a23d3db00..5958fed79 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -352,6 +352,16 @@ class FrameBuffer virtual unique_ptr createSurface(uInt32 w, uInt32 h, const uInt32* data) const = 0; + /** + Calls 'free()' on all surfaces that the framebuffer knows about. + */ + void freeSurfaces(); + + /** + Calls 'reload()' on all surfaces that the framebuffer knows about. + */ + void reloadSurfaces(); + /** Grabs or ungrabs the mouse based on the given boolean value. */ @@ -386,8 +396,7 @@ class FrameBuffer void drawMessage(); /** - Issues a 'free' and 'reload' instruction to all surfaces that the - framebuffer knows about. + Frees and reloads all surfaces that the framebuffer knows about. */ void resetSurfaces();