From 2d39d19af92274cf4127dbc2d16137db2852dcdd Mon Sep 17 00:00:00 2001 From: Charles Dang Date: Wed, 7 Jun 2017 04:57:43 +1100 Subject: [PATCH] Texture: converted internal handling to use a shared_ptr This allows multiple texture objects to refer to the same texture without destroying them prematurely. This is different from the SDL_Surface wrapper's implementation since surfaces have their own internal refcounting system; textures do not. --- src/sdl/texture.cpp | 44 +++++++++++++++++++++----------------------- src/sdl/texture.hpp | 16 +++++++++------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/sdl/texture.cpp b/src/sdl/texture.cpp index f43e7b7a608b..e65da96ebf46 100644 --- a/src/sdl/texture.cpp +++ b/src/sdl/texture.cpp @@ -20,16 +20,31 @@ static lg::log_domain log_sdl("SDL"); #define ERR_SDL LOG_STREAM(err, log_sdl) +namespace +{ // The default pixel format to create textures with. -static int default_texture_format = SDL_PIXELFORMAT_ARGB8888; +int default_texture_format = SDL_PIXELFORMAT_ARGB8888; + +/** + * Constructs a new shared_ptr around the provided texture with the appropriate deleter. + * Should only be passed the result of texture creation functions or the texture might + * get destroys too early. + */ +std::shared_ptr make_texture_ptr(SDL_Texture* tex) +{ + return std::shared_ptr(tex, &SDL_DestroyTexture); +} + +} // end anon namespace texture::texture() : texture_(nullptr) { } +// TODO: should we have this? See possible issues noted above. texture::texture(SDL_Texture* txt) - : texture_(txt) + : texture_(make_texture_ptr(txt)) { finalize(); } @@ -42,7 +57,7 @@ texture::texture(const surface& surf) return; } - texture_ = SDL_CreateTextureFromSurface(renderer, surf); + texture_ = make_texture_ptr(SDL_CreateTextureFromSurface(renderer, surf)); if(!texture_) { ERR_SDL << "When creating texture from surface: " << SDL_GetError() << std::endl; } @@ -54,14 +69,9 @@ texture::texture(int w, int h, SDL_TextureAccess access) reset(w, h, access); } -texture::~texture() -{ - destroy_texture(); -} - void texture::finalize() { - SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND); + SDL_SetTextureBlendMode(texture_.get(), SDL_BLENDMODE_BLEND); } void texture::reset(int w, int h, SDL_TextureAccess access) @@ -74,7 +84,7 @@ void texture::reset(int w, int h, SDL_TextureAccess access) return; } - texture_ = SDL_CreateTexture(renderer, default_texture_format, access, w, h); + texture_ = make_texture_ptr(SDL_CreateTexture(renderer, default_texture_format, access, w, h)); if(!texture_) { ERR_SDL << "When creating texture: " << SDL_GetError() << std::endl; } @@ -85,22 +95,10 @@ void texture::reset(int w, int h, SDL_TextureAccess access) void texture::destroy_texture() { if(texture_) { - SDL_DestroyTexture(texture_); + texture_.reset(); } } -#if 0 -texture& texture::operator=(texture&& t) -{ - destroy_texture(); - - texture_ = t.texture_; - t.texture_ = nullptr; - - return *this; -} -#endif - texture::info::info(const texture& t) : format(0) , access(0) diff --git a/src/sdl/texture.hpp b/src/sdl/texture.hpp index 9fccea80f503..75ea5a62f886 100644 --- a/src/sdl/texture.hpp +++ b/src/sdl/texture.hpp @@ -15,6 +15,8 @@ #include +#include + class surface; /** @@ -27,6 +29,8 @@ class texture /** Default ctor. Texture will be a nullptr. */ texture(); + texture(const texture&) = default; + /** Assigns the given texture to this one. */ explicit texture(SDL_Texture* txt); @@ -36,8 +40,6 @@ class texture /** Construct a texture of the specified size and access type. */ texture(int w, int h, SDL_TextureAccess access); - ~texture(); - /** Small wrapper that queries metadata about the provided texture. */ struct info { @@ -58,14 +60,14 @@ class texture /** Destroys the managed texture and creates a new one. */ void reset(int w, int h, SDL_TextureAccess access); -#if 0 + texture& operator=(const texture& t) = default; + /** Move assignment. Frees the managed texture from the passed object. */ - texture& operator=(texture&& t); -#endif + texture& operator=(texture&& t) = default; operator SDL_Texture*() const { - return texture_; + return texture_.get(); } bool null() const @@ -78,5 +80,5 @@ class texture void destroy_texture(); - SDL_Texture* texture_; + std::shared_ptr texture_; };