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.
This commit is contained in:
Charles Dang 2017-06-07 04:57:43 +11:00
parent 3e2046b5d8
commit 2d39d19af9
2 changed files with 30 additions and 30 deletions

View file

@ -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<SDL_Texture> make_texture_ptr(SDL_Texture* tex)
{
return std::shared_ptr<SDL_Texture>(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)

View file

@ -15,6 +15,8 @@
#include <SDL_render.h>
#include <memory>
class surface;
/**
@ -27,6 +29,8 @@ public:
/** 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 @@ public:
/** 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 @@ public:
/** 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 @@ private:
void destroy_texture();
SDL_Texture* texture_;
std::shared_ptr<SDL_Texture> texture_;
};