diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index ce454a9ee9..5cfc5711ed 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -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); diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index 2b39a83f22..2bf3884999 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -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; diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index b90e638117..5213726c94 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -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; diff --git a/Common/UI/IconCache.cpp b/Common/UI/IconCache.cpp index 1006a111e9..4326323ef2 100644 --- a/Common/UI/IconCache.cpp +++ b/Common/UI/IconCache.cpp @@ -119,6 +119,29 @@ void IconCache::Decimate() { } +bool IconCache::GetDimensions(const std::string &key, int *width, int *height) { + std::unique_lock 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 lock(lock_); + return cache_.find(key) != cache_.end(); +} + bool IconCache::InsertIcon(const std::string &key, IconFormat format, std::string &&data) { std::unique_lock 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 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; } diff --git a/Common/UI/IconCache.h b/Common/UI/IconCache.h index 6bda9a7c18..b16924f46d 100644 --- a/Common/UI/IconCache.h +++ b/Common/UI/IconCache.h @@ -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); diff --git a/Common/UI/Screen.cpp b/Common/UI/Screen.cpp index 0eeaa66214..6e888c63cd 100644 --- a/Common/UI/Screen.cpp +++ b/Common/UI/Screen.cpp @@ -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() {