mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-11-02 11:50:05 +00:00
Hold a reference to current images in the placefile manager, removing old, unused images
This commit is contained in:
parent
9165d66a33
commit
bbaae5d1ba
5 changed files with 68 additions and 63 deletions
|
|
@ -48,11 +48,12 @@ public:
|
|||
static std::shared_ptr<boost::gil::rgba8_image_t>
|
||||
LoadImage(const std::string& imagePath);
|
||||
|
||||
std::unordered_map<std::string, std::string> texturePathMap_ {};
|
||||
std::shared_mutex texturePathMutex_ {};
|
||||
std::vector<std::shared_ptr<boost::gil::rgba8_image_t>>
|
||||
registeredTextures_ {};
|
||||
std::shared_mutex registeredTextureMutex_ {};
|
||||
|
||||
std::shared_mutex textureCacheMutex_ {};
|
||||
std::unordered_map<std::string, std::shared_ptr<boost::gil::rgba8_image_t>>
|
||||
std::unordered_map<std::string, std::weak_ptr<boost::gil::rgba8_image_t>>
|
||||
textureCache_ {};
|
||||
|
||||
std::vector<boost::gil::rgba8_image_t> atlasArray_ {};
|
||||
|
|
@ -76,12 +77,14 @@ std::uint64_t TextureAtlas::BuildCount() const
|
|||
void TextureAtlas::RegisterTexture(const std::string& name,
|
||||
const std::string& path)
|
||||
{
|
||||
std::unique_lock lock(p->texturePathMutex_);
|
||||
p->texturePathMap_.insert_or_assign(name, path);
|
||||
std::unique_lock lock(p->registeredTextureMutex_);
|
||||
|
||||
std::shared_ptr<boost::gil::rgba8_image_t> image = CacheTexture(name, path);
|
||||
p->registeredTextures_.emplace_back(std::move(image));
|
||||
}
|
||||
|
||||
bool TextureAtlas::CacheTexture(const std::string& name,
|
||||
const std::string& path)
|
||||
std::shared_ptr<boost::gil::rgba8_image_t>
|
||||
TextureAtlas::CacheTexture(const std::string& name, const std::string& path)
|
||||
{
|
||||
// Attempt to load the image
|
||||
std::shared_ptr<boost::gil::rgba8_image_t> image =
|
||||
|
|
@ -93,12 +96,12 @@ bool TextureAtlas::CacheTexture(const std::string& name,
|
|||
// Store it in the texture cache
|
||||
std::unique_lock lock(p->textureCacheMutex_);
|
||||
|
||||
p->textureCache_.insert_or_assign(name, std::move(image));
|
||||
p->textureCache_.insert_or_assign(name, image);
|
||||
|
||||
return true;
|
||||
return image;
|
||||
}
|
||||
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TextureAtlas::BuildAtlas(std::size_t width, std::size_t height)
|
||||
|
|
@ -118,50 +121,28 @@ void TextureAtlas::BuildAtlas(std::size_t width, std::size_t height)
|
|||
ImageVector images {};
|
||||
std::vector<stbrp_rect> stbrpRects {};
|
||||
|
||||
// Load images
|
||||
{
|
||||
// Take a read lock on the texture path map
|
||||
std::shared_lock lock(p->texturePathMutex_);
|
||||
|
||||
// For each registered texture
|
||||
std::for_each(
|
||||
p->texturePathMap_.cbegin(),
|
||||
p->texturePathMap_.cend(),
|
||||
[&](const auto& pair)
|
||||
{
|
||||
// Load texture image
|
||||
std::shared_ptr<boost::gil::rgba8_image_t> image =
|
||||
Impl::LoadImage(pair.second);
|
||||
|
||||
if (image != nullptr && image->width() > 0u && image->height() > 0u)
|
||||
{
|
||||
// Store STB rectangle pack data in a vector
|
||||
stbrpRects.push_back(
|
||||
stbrp_rect {0,
|
||||
static_cast<stbrp_coord>(image->width()),
|
||||
static_cast<stbrp_coord>(image->height()),
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
|
||||
// Store image data in a vector
|
||||
images.emplace_back(pair.first, std::move(image));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Cached images
|
||||
{
|
||||
// Take a read lock on the texture cache map while adding textures images
|
||||
// to the atlas vector.
|
||||
std::shared_lock textureCacheLock(p->textureCacheMutex_);
|
||||
// Take a lock on the texture cache map while adding textures images to
|
||||
// the atlas vector.
|
||||
std::unique_lock textureCacheLock(p->textureCacheMutex_);
|
||||
|
||||
// For each cached texture
|
||||
for (auto& texture : p->textureCache_)
|
||||
for (auto it = p->textureCache_.begin(); it != p->textureCache_.end();)
|
||||
{
|
||||
auto& image = texture.second;
|
||||
auto& texture = *it;
|
||||
auto image = texture.second.lock();
|
||||
|
||||
if (image != nullptr && image->width() > 0u && image->height() > 0u)
|
||||
if (image == nullptr)
|
||||
{
|
||||
logger_->trace("Removing texture from the cache: {}",
|
||||
texture.first);
|
||||
|
||||
// If the image is no longer cached, erase the iterator and continue
|
||||
it = p->textureCache_.erase(it);
|
||||
continue;
|
||||
}
|
||||
else if (image->width() > 0u && image->height() > 0u)
|
||||
{
|
||||
// Store STB rectangle pack data in a vector
|
||||
stbrpRects.push_back(
|
||||
|
|
@ -175,6 +156,9 @@ void TextureAtlas::BuildAtlas(std::size_t width, std::size_t height)
|
|||
// Store image data in a vector
|
||||
images.push_back({texture.first, image});
|
||||
}
|
||||
|
||||
// Increment iterator
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <string>
|
||||
|
||||
#include <boost/gil/point.hpp>
|
||||
#include <boost/gil/typedefs.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
|
|
@ -73,7 +74,8 @@ public:
|
|||
std::uint64_t BuildCount() const;
|
||||
|
||||
void RegisterTexture(const std::string& name, const std::string& path);
|
||||
bool CacheTexture(const std::string& name, const std::string& path);
|
||||
std::shared_ptr<boost::gil::rgba8_image_t>
|
||||
CacheTexture(const std::string& name, const std::string& path);
|
||||
void BuildAtlas(std::size_t width, std::size_t height);
|
||||
void BufferAtlas(gl::OpenGLFunctions& gl, GLuint texture);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue