Fix crash in OpenBSD framebuffer/texture cleanup.

- It seems that textures must be destroyed *before* the renderer is destroyed
- This isn't mentioned anywhere in the SDL docs, and it works everywhere else, but in any event it is now fixed
This commit is contained in:
Stephen Anthony 2018-06-07 12:46:26 -02:30
parent 0a3977e62c
commit 7f38e8efd4
4 changed files with 36 additions and 6 deletions

View File

@ -37,7 +37,10 @@ FBSurfaceSDL2::FBSurfaceSDL2(FrameBufferSDL2& buffer,
FBSurfaceSDL2::~FBSurfaceSDL2()
{
if(mySurface)
{
SDL_FreeSurface(mySurface);
mySurface = nullptr;
}
free();
}

View File

@ -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;
}

View File

@ -555,6 +555,20 @@ shared_ptr<FBSurface> 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()
{
@ -564,10 +578,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();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -352,6 +352,16 @@ class FrameBuffer
virtual unique_ptr<FBSurface>
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();