diff --git a/Source/Core/VideoCommon/HiresTextures.cpp b/Source/Core/VideoCommon/HiresTextures.cpp index b90dddb557..c76f389cbf 100644 --- a/Source/Core/VideoCommon/HiresTextures.cpp +++ b/Source/Core/VideoCommon/HiresTextures.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,7 @@ #include "Common/FileSearch.h" #include "Common/FileUtil.h" #include "Common/Flag.h" +#include "Common/Hash.h" #include "Common/MemoryUtil.h" #include "Common/StringUtil.h" #include "Common/Thread.h" @@ -39,6 +41,11 @@ static std::thread s_prefetcher; static const std::string s_format_prefix = "tex1_"; +HiresTexture::Level::Level() + : data(nullptr, SOIL_free_image_data) +{ +} + void HiresTexture::Init() { s_check_native_format = false; @@ -165,11 +172,11 @@ void HiresTexture::Prefetch() // But bad luck, SOIL isn't, so TODO: remove SOIL usage here and use libpng directly // Also TODO: remove s_textureCacheAquireMutex afterwards. It won't be needed as the main mutex will be locked rarely //lk.unlock(); - HiresTexture* t = Load(base_filename, 0, 0); + std::unique_ptr texture = Load(base_filename, 0, 0); //lk.lock(); - if (t) + if (texture) { - std::shared_ptr ptr(t); + std::shared_ptr ptr(std::move(texture)); iter = s_textureCache.insert(iter, std::make_pair(base_filename, ptr)); } } @@ -364,9 +371,9 @@ std::shared_ptr HiresTexture::Search(const u8* texture, size_t tex return ptr; } -HiresTexture* HiresTexture::Load(const std::string& base_filename, u32 width, u32 height) +std::unique_ptr HiresTexture::Load(const std::string& base_filename, u32 width, u32 height) { - HiresTexture* ret = nullptr; + std::unique_ptr ret; for (int level = 0;; level++) { std::string filename = base_filename; @@ -385,7 +392,7 @@ HiresTexture* HiresTexture::Load(const std::string& base_filename, u32 width, u3 file.ReadBytes(buffer.data(), file.GetSize()); int channels; - l.data = SOIL_load_image_from_memory(buffer.data(), (int)buffer.size(), (int*)&l.width, (int*)&l.height, &channels, SOIL_LOAD_RGBA); + l.data = SOILPointer(SOIL_load_image_from_memory(buffer.data(), (int)buffer.size(), (int*)&l.width, (int*)&l.height, &channels, SOIL_LOAD_RGBA), SOIL_free_image_data); l.data_size = (size_t)l.width * l.height * 4; if (l.data == nullptr) @@ -409,7 +416,7 @@ HiresTexture* HiresTexture::Load(const std::string& base_filename, u32 width, u3 { ERROR_LOG(VIDEO, "Invalid custom texture size %dx%d for texture %s. This mipmap layer _must_ be %dx%d.", l.width, l.height, filename.c_str(), width, height); - SOIL_free_image_data(l.data); + l.data.reset(); break; } @@ -418,8 +425,8 @@ HiresTexture* HiresTexture::Load(const std::string& base_filename, u32 width, u3 height >>= 1; if (!ret) - ret = new HiresTexture(); - ret->m_levels.push_back(l); + ret = std::unique_ptr(new HiresTexture); + ret->m_levels.push_back(std::move(l)); } else { @@ -432,9 +439,4 @@ HiresTexture* HiresTexture::Load(const std::string& base_filename, u32 width, u3 HiresTexture::~HiresTexture() { - for (auto& l : m_levels) - { - SOIL_free_image_data(l.data); - } } - diff --git a/Source/Core/VideoCommon/HiresTextures.h b/Source/Core/VideoCommon/HiresTextures.h index 65a033de7d..f62eaf0224 100644 --- a/Source/Core/VideoCommon/HiresTextures.h +++ b/Source/Core/VideoCommon/HiresTextures.h @@ -6,13 +6,15 @@ #include #include -#include -#include "VideoCommon/TextureDecoder.h" -#include "VideoCommon/VideoCommon.h" +#include + +#include "Common/CommonTypes.h" class HiresTexture { public: + using SOILPointer = std::unique_ptr; + static void Init(); static void Update(); static void Shutdown(); @@ -36,14 +38,17 @@ public: struct Level { - u8* data; - size_t data_size; - u32 width, height; + Level(); + + SOILPointer data; + size_t data_size = 0; + u32 width = 0; + u32 height = 0; }; std::vector m_levels; private: - static HiresTexture* Load(const std::string& base_filename, u32 width, u32 height); + static std::unique_ptr Load(const std::string& base_filename, u32 width, u32 height); static void Prefetch(); HiresTexture() {} diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 341977d7a8..b4e15ebdae 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -605,16 +605,16 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage) if (hires_tex) { - auto& l = hires_tex->m_levels[0]; - if (l.width != width || l.height != height) + const auto& level = hires_tex->m_levels[0]; + if (level.width != width || level.height != height) { - width = l.width; - height = l.height; + width = level.width; + height = level.height; } - expandedWidth = l.width; - expandedHeight = l.height; - CheckTempSize(l.data_size); - memcpy(temp, l.data, l.data_size); + expandedWidth = level .width; + expandedHeight = level.height; + CheckTempSize(level.data_size); + memcpy(temp, level.data.get(), level.data_size); } } @@ -678,12 +678,12 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage) if (hires_tex) { - for (u32 level = 1; level != texLevels; ++level) + for (u32 level_index = 1; level_index != texLevels; ++level_index) { - auto& l = hires_tex->m_levels[level]; - CheckTempSize(l.data_size); - memcpy(temp, l.data, l.data_size); - entry->Load(l.width, l.height, l.width, level); + const auto& level = hires_tex->m_levels[level_index]; + CheckTempSize(level.data_size); + memcpy(temp, level.data.get(), level.data_size); + entry->Load(level.width, level.height, level.width, level_index); } } else