mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-21 06:33:22 +00:00
Add new icon cache, for caching small images.
It doesn't try to insert or fetch missing things itself, re-fetching is up to the caller. This will be required for handling the many achievement icons. Saving/loading the cache to a single file on disk is implemented but not hooked up yet. It works without it, though of course will have to re-fetch things on the next startup.
This commit is contained in:
parent
9f88dbd656
commit
2bee5b64e4
@ -259,6 +259,7 @@ public:
|
||||
// We pass in width/height here even though it's not strictly needed until we support glTextureStorage
|
||||
// and then we'll also need formats and stuff.
|
||||
GLRTexture *CreateTexture(GLenum target, int width, int height, int depth, int numMips) {
|
||||
_dbg_assert_(target != 0);
|
||||
GLRInitStep &step = initSteps_.push_uninitialized();
|
||||
step.stepType = GLRInitStepType::CREATE_TEXTURE;
|
||||
step.create_texture.texture = new GLRTexture(caps_, width, height, depth, numMips);
|
||||
|
@ -822,7 +822,7 @@ InputLayout *OpenGLContext::CreateInputLayout(const InputLayoutDesc &desc) {
|
||||
return fmt;
|
||||
}
|
||||
|
||||
GLuint TypeToTarget(TextureType type) {
|
||||
static GLuint TypeToTarget(TextureType type) {
|
||||
switch (type) {
|
||||
#ifndef USING_GLES2
|
||||
case TextureType::LINEAR1D: return GL_TEXTURE_1D;
|
||||
@ -875,6 +875,10 @@ private:
|
||||
};
|
||||
|
||||
OpenGLTexture::OpenGLTexture(GLRenderManager *render, const TextureDesc &desc) : render_(render) {
|
||||
_dbg_assert_(desc.format != Draw::DataFormat::UNDEFINED);
|
||||
_dbg_assert_(desc.width > 0 && desc.height > 0 && desc.depth > 0);
|
||||
_dbg_assert_(type_ != Draw::TextureType::UNKNOWN);
|
||||
|
||||
generatedMips_ = false;
|
||||
generateMips_ = desc.generateMips;
|
||||
width_ = desc.width;
|
||||
|
@ -463,10 +463,10 @@ public:
|
||||
class Texture : public RefCountedObject {
|
||||
public:
|
||||
Texture() : RefCountedObject("Texture") {}
|
||||
int Width() { return width_; }
|
||||
int Height() { return height_; }
|
||||
int Depth() { return depth_; }
|
||||
DataFormat Format() { return format_; }
|
||||
int Width() const { return width_; }
|
||||
int Height() const { return height_; }
|
||||
int Depth() const { return depth_; }
|
||||
DataFormat Format() const { return format_; }
|
||||
|
||||
protected:
|
||||
int width_ = -1, height_ = -1, depth_ = -1;
|
||||
|
@ -119,6 +119,29 @@ void IconCache::Decimate() {
|
||||
|
||||
}
|
||||
|
||||
bool IconCache::GetDimensions(const std::string &key, int *width, int *height) {
|
||||
std::unique_lock<std::mutex> lock(lock_);
|
||||
auto iter = cache_.find(key);
|
||||
if (iter == cache_.end()) {
|
||||
// Don't have this entry.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iter->second.texture) {
|
||||
// TODO: Store the width/height in the cache.
|
||||
*width = iter->second.texture->Width();
|
||||
*height = iter->second.texture->Height();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IconCache::Contains(const std::string &key) {
|
||||
std::unique_lock<std::mutex> lock(lock_);
|
||||
return cache_.find(key) != cache_.end();
|
||||
}
|
||||
|
||||
bool IconCache::InsertIcon(const std::string &key, IconFormat format, std::string &&data) {
|
||||
std::unique_lock<std::mutex> lock(lock_);
|
||||
|
||||
@ -141,22 +164,22 @@ bool IconCache::InsertIcon(const std::string &key, IconFormat format, std::strin
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IconCache::BindIconTexture(UIContext *context, const std::string &key) {
|
||||
Draw::Texture *IconCache::BindIconTexture(UIContext *context, const std::string &key) {
|
||||
std::unique_lock<std::mutex> lock(lock_);
|
||||
auto iter = cache_.find(key);
|
||||
if (iter == cache_.end()) {
|
||||
// Don't have this entry.
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (iter->second.texture) {
|
||||
context->GetDrawContext()->BindTexture(0, iter->second.texture);
|
||||
iter->second.usedTimeStamp = time_now_d();
|
||||
return true;
|
||||
return iter->second.texture;
|
||||
}
|
||||
|
||||
if (iter->second.badData) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// OK, don't have a texture. Upload it!
|
||||
@ -174,13 +197,13 @@ bool IconCache::BindIconTexture(UIContext *context, const std::string &key) {
|
||||
if (result != 1) {
|
||||
ERROR_LOG(G3D, "IconCache: Failed to load png (%d bytes) for key %s", (int)iter->second.data.size(), key.c_str());
|
||||
iter->second.badData = true;
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
dataFormat = Draw::DataFormat::R8G8B8A8_UNORM;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Draw::TextureDesc iconDesc{};
|
||||
@ -192,11 +215,13 @@ bool IconCache::BindIconTexture(UIContext *context, const std::string &key) {
|
||||
iconDesc.swizzle = Draw::TextureSwizzle::DEFAULT;
|
||||
iconDesc.generateMips = false;
|
||||
iconDesc.tag = key.c_str();
|
||||
iconDesc.format = dataFormat;
|
||||
iconDesc.type = Draw::TextureType::LINEAR2D;
|
||||
|
||||
Draw::Texture *texture = context->GetDrawContext()->CreateTexture(iconDesc);
|
||||
iter->second.texture = texture;
|
||||
|
||||
free(buffer);
|
||||
|
||||
return true;
|
||||
return texture;
|
||||
}
|
||||
|
@ -14,14 +14,20 @@ enum class IconFormat : uint32_t {
|
||||
PNG,
|
||||
};
|
||||
|
||||
namespace Draw {
|
||||
class Texture;
|
||||
}
|
||||
|
||||
// TODO: Possibly make this smarter and use instead of ManagedTexture?
|
||||
|
||||
class IconCache {
|
||||
public:
|
||||
bool BindIconTexture(UIContext *context, const std::string &key);
|
||||
Draw::Texture *BindIconTexture(UIContext *context, const std::string &key);
|
||||
|
||||
// It's okay to call this from any thread.
|
||||
bool InsertIcon(const std::string &key, IconFormat format, std::string &&pngData);
|
||||
bool GetDimensions(const std::string &key, int *width, int *height);
|
||||
bool Contains(const std::string &key);
|
||||
|
||||
void SaveToFile(FILE *file);
|
||||
bool LoadFromFile(FILE *file);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "Common/UI/UI.h"
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Common/UI/IconCache.h"
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "Common/TimeUtil.h"
|
||||
@ -130,6 +131,7 @@ void ScreenManager::axis(const AxisInput &axis) {
|
||||
void ScreenManager::deviceLost() {
|
||||
for (auto &iter : stack_)
|
||||
iter.screen->deviceLost();
|
||||
g_iconCache.ClearTextures();
|
||||
}
|
||||
|
||||
void ScreenManager::deviceRestored() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user