diff --git a/src/sdl/surface.cpp b/src/sdl/surface.cpp index 67031c043365..9a27c480e10f 100644 --- a/src/sdl/surface.cpp +++ b/src/sdl/surface.cpp @@ -14,8 +14,29 @@ #include "sdl/surface.hpp" #include "sdl/rect.hpp" +#include "sdl/utils.hpp" #include "video.hpp" +void surface::free_surface() +{ + if(surface_) { + /* Workaround for an SDL bug. + * SDL 2.0.6 frees the blit map unconditionally in SDL_FreeSurface() without checking + * if the reference count has fallen to zero. However, many SDL functions such as + * SDL_ConvertSurface() assume that the blit map is present. + * Thus, we only call SDL_FreeSurface() if this is the last reference to the surface. + * Otherwise we just decrement the reference count ourselves. + * + * - Jyrki, 2017-09-23 + */ + if(surface_->refcount > 1 && sdl_get_version() >= version_info(2, 0, 6)) { + --surface_->refcount; + } else { + SDL_FreeSurface(surface_); + } + } +} + surface_restorer::surface_restorer() : target_(nullptr) , rect_(sdl::empty_rect) diff --git a/src/sdl/surface.hpp b/src/sdl/surface.hpp index b45c6487bdbe..5d31e1307714 100644 --- a/src/sdl/surface.hpp +++ b/src/sdl/surface.hpp @@ -80,25 +80,7 @@ class surface surface_ = surf; } - void free_surface() - { - if(surface_) { - /* Workaround for an SDL bug. - * SDL 2.0.6 frees the blit map unconditionally in SDL_FreeSurface() without checking - * if the reference count has fallen to zero. However, many SDL functions such as - * SDL_ConvertSurface() assume that the blit map is present. - * Thus, we only call SDL_FreeSurface() if this is the last reference to the surface. - * Otherwise we just decrement the reference count ourselves. - * - * - Jyrki, 2017-09-23 - */ - if(surface_->refcount > 1) { - --surface_->refcount; - } else { - SDL_FreeSurface(surface_); - } - } - } + void free_surface(); SDL_Surface* surface_; }; diff --git a/src/sdl/utils.cpp b/src/sdl/utils.cpp index d7ba2870bd2f..5fe539ec5a64 100644 --- a/src/sdl/utils.cpp +++ b/src/sdl/utils.cpp @@ -32,6 +32,13 @@ #include +version_info sdl_get_version() +{ + SDL_version sdl_version; + SDL_GetVersion(&sdl_version); + return version_info(sdl_version.major, sdl_version.minor, sdl_version.patch); +} + bool is_neutral(const surface& surf) { return (surf->format->BytesPerPixel == 4 && diff --git a/src/sdl/utils.hpp b/src/sdl/utils.hpp index 5996e05dc947..7f4a2d1d4cda 100644 --- a/src/sdl/utils.hpp +++ b/src/sdl/utils.hpp @@ -20,6 +20,7 @@ #include "color.hpp" #include "sdl/surface.hpp" #include "utils/math.hpp" +#include "version.hpp" #include @@ -27,6 +28,8 @@ #include #include +version_info sdl_get_version(); + inline void sdl_blit(const surface& src, SDL_Rect* src_rect, surface& dst, SDL_Rect* dst_rect){ SDL_BlitSurface(src, src_rect, dst, dst_rect); } diff --git a/src/video.cpp b/src/video.cpp index 5be0e524be77..6b2477b23fc2 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -19,6 +19,7 @@ #include "image.hpp" #include "log.hpp" #include "preferences/general.hpp" +#include "sdl/utils.hpp" #include "sdl/window.hpp" #include "sdl/userevent.hpp" @@ -196,9 +197,12 @@ void CVideo::update_framebuffer() if(!frameBuffer) { frameBuffer = fb; } else { - // Because SDL has already freed the old framebuffer, - // ensure that we won't attempt to free it. - frameBuffer.clear_without_free(); + if(sdl_get_version() >= version_info(2, 0, 6)) { + // Because SDL has already freed the old framebuffer, + // ensure that we won't attempt to free it. + frameBuffer.clear_without_free(); + } + frameBuffer.assign(fb); } }