Merge pull request #3410 from lioncash/hires

HiresTextures: Minor changes
This commit is contained in:
Markus Wick 2015-12-29 20:44:58 +01:00
commit f8d7becba9
3 changed files with 41 additions and 34 deletions

View File

@ -8,6 +8,7 @@
#include <mutex> #include <mutex>
#include <string> #include <string>
#include <thread> #include <thread>
#include <unordered_map>
#include <utility> #include <utility>
#include <xxhash.h> #include <xxhash.h>
#include <SOIL/SOIL.h> #include <SOIL/SOIL.h>
@ -16,6 +17,7 @@
#include "Common/FileSearch.h" #include "Common/FileSearch.h"
#include "Common/FileUtil.h" #include "Common/FileUtil.h"
#include "Common/Flag.h" #include "Common/Flag.h"
#include "Common/Hash.h"
#include "Common/MemoryUtil.h" #include "Common/MemoryUtil.h"
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Common/Thread.h" #include "Common/Thread.h"
@ -39,6 +41,11 @@ static std::thread s_prefetcher;
static const std::string s_format_prefix = "tex1_"; static const std::string s_format_prefix = "tex1_";
HiresTexture::Level::Level()
: data(nullptr, SOIL_free_image_data)
{
}
void HiresTexture::Init() void HiresTexture::Init()
{ {
s_check_native_format = false; 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 // 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 // Also TODO: remove s_textureCacheAquireMutex afterwards. It won't be needed as the main mutex will be locked rarely
//lk.unlock(); //lk.unlock();
HiresTexture* t = Load(base_filename, 0, 0); std::unique_ptr<HiresTexture> texture = Load(base_filename, 0, 0);
//lk.lock(); //lk.lock();
if (t) if (texture)
{ {
std::shared_ptr<HiresTexture> ptr(t); std::shared_ptr<HiresTexture> ptr(std::move(texture));
iter = s_textureCache.insert(iter, std::make_pair(base_filename, ptr)); iter = s_textureCache.insert(iter, std::make_pair(base_filename, ptr));
} }
} }
@ -364,9 +371,9 @@ std::shared_ptr<HiresTexture> HiresTexture::Search(const u8* texture, size_t tex
return ptr; return ptr;
} }
HiresTexture* HiresTexture::Load(const std::string& base_filename, u32 width, u32 height) std::unique_ptr<HiresTexture> HiresTexture::Load(const std::string& base_filename, u32 width, u32 height)
{ {
HiresTexture* ret = nullptr; std::unique_ptr<HiresTexture> ret;
for (int level = 0;; level++) for (int level = 0;; level++)
{ {
std::string filename = base_filename; 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()); file.ReadBytes(buffer.data(), file.GetSize());
int channels; 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; l.data_size = (size_t)l.width * l.height * 4;
if (l.data == nullptr) 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.", 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); l.width, l.height, filename.c_str(), width, height);
SOIL_free_image_data(l.data); l.data.reset();
break; break;
} }
@ -418,8 +425,8 @@ HiresTexture* HiresTexture::Load(const std::string& base_filename, u32 width, u3
height >>= 1; height >>= 1;
if (!ret) if (!ret)
ret = new HiresTexture(); ret = std::unique_ptr<HiresTexture>(new HiresTexture);
ret->m_levels.push_back(l); ret->m_levels.push_back(std::move(l));
} }
else else
{ {
@ -432,9 +439,4 @@ HiresTexture* HiresTexture::Load(const std::string& base_filename, u32 width, u3
HiresTexture::~HiresTexture() HiresTexture::~HiresTexture()
{ {
for (auto& l : m_levels)
{
SOIL_free_image_data(l.data);
}
} }

View File

@ -6,13 +6,15 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_map> #include <vector>
#include "VideoCommon/TextureDecoder.h"
#include "VideoCommon/VideoCommon.h" #include "Common/CommonTypes.h"
class HiresTexture class HiresTexture
{ {
public: public:
using SOILPointer = std::unique_ptr<u8, void(*)(unsigned char*)>;
static void Init(); static void Init();
static void Update(); static void Update();
static void Shutdown(); static void Shutdown();
@ -36,14 +38,17 @@ public:
struct Level struct Level
{ {
u8* data; Level();
size_t data_size;
u32 width, height; SOILPointer data;
size_t data_size = 0;
u32 width = 0;
u32 height = 0;
}; };
std::vector<Level> m_levels; std::vector<Level> m_levels;
private: private:
static HiresTexture* Load(const std::string& base_filename, u32 width, u32 height); static std::unique_ptr<HiresTexture> Load(const std::string& base_filename, u32 width, u32 height);
static void Prefetch(); static void Prefetch();
HiresTexture() {} HiresTexture() {}

View File

@ -605,16 +605,16 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
if (hires_tex) if (hires_tex)
{ {
auto& l = hires_tex->m_levels[0]; const auto& level = hires_tex->m_levels[0];
if (l.width != width || l.height != height) if (level.width != width || level.height != height)
{ {
width = l.width; width = level.width;
height = l.height; height = level.height;
} }
expandedWidth = l.width; expandedWidth = level .width;
expandedHeight = l.height; expandedHeight = level.height;
CheckTempSize(l.data_size); CheckTempSize(level.data_size);
memcpy(temp, l.data, l.data_size); memcpy(temp, level.data.get(), level.data_size);
} }
} }
@ -678,12 +678,12 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
if (hires_tex) 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]; const auto& level = hires_tex->m_levels[level_index];
CheckTempSize(l.data_size); CheckTempSize(level.data_size);
memcpy(temp, l.data, l.data_size); memcpy(temp, level.data.get(), level.data_size);
entry->Load(l.width, l.height, l.width, level); entry->Load(level.width, level.height, level.width, level_index);
} }
} }
else else