update Texture & GifImage cache management

This commit is contained in:
Nomango 2020-08-03 21:55:27 +08:00
parent 4dce6fb506
commit ada7c2b336
27 changed files with 379 additions and 240 deletions

View File

@ -94,7 +94,7 @@
<ClInclude Include="..\..\src\kiwano\render\Renderer.h" />
<ClInclude Include="..\..\src\kiwano\render\StrokeStyle.h" />
<ClInclude Include="..\..\src\kiwano\render\TextLayout.h" />
<ClInclude Include="..\..\src\kiwano\render\TextStyle.hpp" />
<ClInclude Include="..\..\src\kiwano\render\TextStyle.h" />
<ClInclude Include="..\..\src\kiwano\render\Texture.h" />
<ClInclude Include="..\..\src\kiwano\render\TextureCache.h" />
<ClInclude Include="..\..\src\kiwano\utils\ConfigIni.h" />
@ -174,6 +174,7 @@
<ClCompile Include="..\..\src\kiwano\render\Renderer.cpp" />
<ClCompile Include="..\..\src\kiwano\render\StrokeStyle.cpp" />
<ClCompile Include="..\..\src\kiwano\render\TextLayout.cpp" />
<ClCompile Include="..\..\src\kiwano\render\TextStyle.cpp" />
<ClCompile Include="..\..\src\kiwano\render\Texture.cpp" />
<ClCompile Include="..\..\src\kiwano\render\TextureCache.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\ConfigIni.cpp" />

View File

@ -156,9 +156,6 @@
<ClInclude Include="..\..\src\kiwano\render\TextLayout.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\TextStyle.hpp">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\Texture.h">
<Filter>render</Filter>
</ClInclude>
@ -357,6 +354,9 @@
<ClInclude Include="..\..\src\kiwano\utils\ResourceLoader.h">
<Filter>utils</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\TextStyle.h">
<Filter>render</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">
@ -584,6 +584,9 @@
<ClCompile Include="..\..\src\kiwano\utils\ResourceLoader.cpp">
<Filter>utils</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\TextStyle.cpp">
<Filter>render</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="suppress_warning.ruleset" />

View File

@ -60,7 +60,7 @@ DebugActor::DebugActor()
BrushPtr fill_brush = MakePtr<Brush>();
fill_brush->SetColor(Color::White);
debug_text_style_.font_family = "Arial";
debug_text_style_.font = new Font("Arial");
debug_text_style_.font_size = 16.f;
debug_text_style_.font_weight = FontWeight::Normal;
debug_text_style_.line_spacing = 20.f;

View File

@ -19,8 +19,7 @@
// THE SOFTWARE.
#include <kiwano/2d/GifSprite.h>
#include <kiwano/render/Renderer.h>
#include <kiwano/render/TextureCache.h>
#include <kiwano/render/RenderContext.h>
namespace kiwano
{
@ -53,13 +52,13 @@ GifSprite::GifSprite(GifImagePtr gif)
bool GifSprite::Load(const String& file_path)
{
GifImagePtr image = TextureCache::GetInstance().AddOrGetGifImage(file_path);
GifImagePtr image = GifImage::Preload(file_path);
return Load(image);
}
bool GifSprite::Load(const Resource& res)
{
GifImagePtr image = TextureCache::GetInstance().AddOrGetGifImage(res);
GifImagePtr image = GifImage::Preload(res);
return Load(image);
}

View File

@ -19,7 +19,7 @@
// THE SOFTWARE.
#include <kiwano/2d/Sprite.h>
#include <kiwano/render/Renderer.h>
#include <kiwano/render/RenderContext.h>
namespace kiwano
{

View File

@ -88,16 +88,6 @@ void TextActor::SetFont(FontPtr font)
}
}
void TextActor::SetFontFamily(const String& family)
{
if (style_.font_family != family)
{
style_.font_family = family;
if (layout_)
layout_->SetFontFamily(family, { 0, layout_->GetContentLength() });
}
}
void TextActor::SetFontSize(float size)
{
if (style_.font_size != size)

View File

@ -98,10 +98,6 @@ public:
/// @brief 设置字体
void SetFont(FontPtr font);
/// \~chinese
/// @brief ÉèÖÃ×ÖÌå×å
void SetFontFamily(const String& family);
/// \~chinese
/// @brief 设置字号(默认值为 18
void SetFontSize(float size);

View File

@ -22,7 +22,6 @@
#include <kiwano/core/Defer.h>
#include <kiwano/base/Director.h>
#include <kiwano/render/Renderer.h>
#include <kiwano/render/TextureCache.h>
#include <kiwano/utils/Logger.h>
namespace kiwano
@ -129,7 +128,6 @@ void Application::Destroy()
modules_.clear();
// Clear device resources
TextureCache::GetInstance().Clear();
Renderer::GetInstance().Destroy();
}

View File

@ -75,6 +75,9 @@ public:
HRESULT CreateFontCollectionFromResources(_Out_ ComPtr<IDWriteFontCollection>& font_collection,
const Vector<Resource>& resources) override;
HRESULT GetFontFamilyNames(_Out_ Vector<String>& family_names,
_In_ ComPtr<IDWriteFontCollection> font_collection) override;
HRESULT SetDpi(float dpi) override;
HRESULT SetLogicalSize(float width, float height) override;
@ -549,6 +552,50 @@ HRESULT D2DDeviceResources::CreateFontCollectionFromResources(ComPtr<IDWriteFont
return hr;
}
HRESULT D2DDeviceResources::GetFontFamilyNames(Vector<String>& family_names,
ComPtr<IDWriteFontCollection> font_collection)
{
HRESULT hr = S_OK;
if (!font_collection)
hr = E_FAIL;
if (SUCCEEDED(hr))
{
UINT32 count = font_collection->GetFontFamilyCount();
for (UINT32 i = 0; i < count; i++)
{
ComPtr<IDWriteFontFamily> family;
hr = font_collection->GetFontFamily(i, &family);
if (SUCCEEDED(hr))
{
ComPtr<IDWriteLocalizedStrings> str;
hr = family->GetFamilyNames(&str);
if (SUCCEEDED(hr))
{
UINT32 length;
hr = str->GetStringLength(0, &length);
if (SUCCEEDED(hr))
{
WideString name;
name.resize(length + 1);
str->GetString(0, &name[0], UINT32(name.size()));
if (SUCCEEDED(hr))
{
family_names.emplace_back(strings::WideToNarrow(name));
}
}
}
}
}
}
return hr;
}
} // namespace directx
} // namespace graphics
} // namespace kiwano

View File

@ -60,7 +60,10 @@ public:
const Vector<String>& file_paths) = 0;
virtual HRESULT CreateFontCollectionFromResources(_Out_ ComPtr<IDWriteFontCollection> & font_collection,
const Vector<Resource>& resources) = 0;
const Vector<Resource>& resources) = 0;
virtual HRESULT GetFontFamilyNames(_Out_ Vector<String> & family_names,
_In_ ComPtr<IDWriteFontCollection> font_collection) = 0;
virtual HRESULT SetDpi(float dpi) = 0;

View File

@ -114,6 +114,8 @@ void RendererImpl::Destroy()
{
KGE_DEBUG_LOGF("Destroying device resources");
Renderer::Destroy();
if (d2d_res_)
{
render_ctx_.Reset();
@ -502,36 +504,14 @@ void RendererImpl::CreateFontCollection(Font& font, const String& file_path)
ComPtr<IDWriteFontCollection> font_collection;
hr = d2d_res_->CreateFontCollectionFromFiles(font_collection, { full_path });
Vector<String> family_names;
if (SUCCEEDED(hr))
{
UINT32 count = font_collection->GetFontFamilyCount();
for (UINT32 i = 0; i < count; i++)
{
ComPtr<IDWriteFontFamily> family;
if (SUCCEEDED(font_collection->GetFontFamily(i, &family)))
{
ComPtr<IDWriteLocalizedStrings> str;
if (SUCCEEDED(family->GetFamilyNames(&str)))
{
UINT32 length = 0;
if (SUCCEEDED(str->GetStringLength(0, &length)))
{
WideString name;
name.resize(length + 1);
if (SUCCEEDED(str->GetString(0, &name[0], UINT32(name.size()))))
{
family_names.emplace_back(strings::WideToNarrow(name));
}
}
}
}
}
}
Vector<String> family_names;
d2d_res_->GetFontFamilyNames(family_names, font_collection); // ignore the result
if (!family_names.empty())
font.SetFamilyName(family_names[0]);
if (SUCCEEDED(hr))
{
font.SetFamilyNames(family_names);
NativePtr::Set(font, font_collection);
}
}
@ -552,36 +532,14 @@ void RendererImpl::CreateFontCollection(Font& font, const Resource& res)
ComPtr<IDWriteFontCollection> font_collection;
hr = d2d_res_->CreateFontCollectionFromResources(font_collection, Vector<Resource>{ res });
Vector<String> family_names;
if (SUCCEEDED(hr))
{
UINT32 count = font_collection->GetFontFamilyCount();
for (UINT32 i = 0; i < count; i++)
{
ComPtr<IDWriteFontFamily> family;
if (SUCCEEDED(font_collection->GetFontFamily(i, &family)))
{
ComPtr<IDWriteLocalizedStrings> str;
if (SUCCEEDED(family->GetFamilyNames(&str)))
{
UINT32 length = 0;
if (SUCCEEDED(str->GetStringLength(0, &length)))
{
WideString name;
name.resize(length + 1);
if (SUCCEEDED(str->GetString(0, &name[0], UINT32(name.size()))))
{
family_names.emplace_back(strings::WideToNarrow(name));
}
}
}
}
}
}
Vector<String> family_names;
d2d_res_->GetFontFamilyNames(family_names, font_collection); // ignore the result
if (!family_names.empty())
font.SetFamilyName(family_names[0]);
if (SUCCEEDED(hr))
{
font.SetFamilyNames(family_names);
NativePtr::Set(font, font_collection);
}
}
@ -606,11 +564,20 @@ void RendererImpl::CreateTextLayout(TextLayout& layout, const String& content, c
if (SUCCEEDED(hr))
{
WideString font_family = style.font_family.empty() ? L"" : strings::NarrowToWide(style.font_family);
DWRITE_FONT_WEIGHT font_weight = DWRITE_FONT_WEIGHT(style.font_weight);
DWRITE_FONT_STYLE font_style = style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
auto collection = NativePtr::Get<IDWriteFontCollection>(style.font);
WideString font_family;
if (style.font)
{
String name = style.font->GetFamilyName();
if (!name.empty())
{
font_family = strings::NarrowToWide(name);
}
}
ComPtr<IDWriteTextFormat> format;
hr = d2d_res_->CreateTextFormat(format, font_family.c_str(), collection, font_weight, font_style,
DWRITE_FONT_STRETCH_NORMAL, style.font_size);

View File

@ -88,8 +88,8 @@ private:
using ID2DDeviceResources = kiwano::graphics::directx::ID2DDeviceResources;
using ID3DDeviceResources = kiwano::graphics::directx::ID3DDeviceResources;
ComPtr<ID2DDeviceResources> d2d_res_;
ComPtr<ID3DDeviceResources> d3d_res_;
ComPtr<ID2DDeviceResources> d2d_res_;
ComPtr<ID3DDeviceResources> d3d_res_;
};

View File

@ -24,42 +24,39 @@
namespace kiwano
{
Font::Font(const String& file)
FontPtr Font::Preload(const String& file)
{
Load(file);
FontPtr ptr = MakePtr<Font>();
try
{
Renderer::GetInstance().CreateFontCollection(*ptr, file);
}
catch (Exception&)
{
return nullptr;
}
return ptr;
}
Font::Font(const Resource& resource)
FontPtr Font::Preload(const Resource& resource)
{
Load(resource);
FontPtr ptr = MakePtr<Font>();
try
{
Renderer::GetInstance().CreateFontCollection(*ptr, resource);
}
catch (Exception&)
{
return nullptr;
}
return ptr;
}
Font::Font() {}
bool Font::Load(const String& file)
Font::Font(const String& family_name)
: family_name_(family_name)
{
try
{
Renderer::GetInstance().CreateFontCollection(*this, file);
}
catch (RuntimeError&)
{
return false;
}
return true;
}
bool Font::Load(const Resource& resource)
{
try
{
Renderer::GetInstance().CreateFontCollection(*this, resource);
}
catch (RuntimeError&)
{
return false;
}
return true;
}
} // namespace kiwano

View File

@ -39,49 +39,46 @@ class Renderer;
*/
class Font : public NativeObject
{
friend class Renderer;
public:
/// \~chinese
/// @brief ´´˝¨×ÖĚĺ
Font(const String& file);
/// @param file 字体文件
static FontPtr Preload(const String& file);
/// \~chinese
/// @brief ´´˝¨×ÖĚĺ
Font(const Resource& resource);
/// @param resource 字体资源
static FontPtr Preload(const Resource& resource);
Font();
/// \~chinese
/// @brief 加载字体文件
bool Load(const String& file);
/// @brief 创建字体
/// @param family_name 字体族
Font(const String& family_name);
/// \~chinese
/// @brief 加载字体资源
bool Load(const Resource& resource);
/// @brief 获取字体族
String GetFamilyName() const;
/// \~chinese
/// @brief 获取字体族名称
Vector<String> GetFamilyNames() const;
/// \~chinese
/// @brief 设置字体族名称
void SetFamilyNames(const Vector<String>& names);
/// @brief 获取字体族
void SetFamilyName(const String& name);
protected:
Vector<String> family_names_;
String family_name_;
};
/** @} */
inline Vector<String> Font::GetFamilyNames() const
inline String Font::GetFamilyName() const
{
return family_names_;
return family_name_;
}
inline void Font::SetFamilyNames(const Vector<String>& names)
inline void Font::SetFamilyName(const String& name)
{
family_names_ = names;
family_name_ = name;
}
} // namespace kiwano

View File

@ -19,7 +19,6 @@
// THE SOFTWARE.
#include <kiwano/render/Frame.h>
#include <kiwano/render/TextureCache.h>
namespace kiwano
{
@ -43,7 +42,7 @@ Frame::Frame() {}
bool Frame::Load(const String& file_path)
{
TexturePtr texture = TextureCache::GetInstance().AddOrGetTexture(file_path);
TexturePtr texture = Texture::Preload(file_path);
if (texture->IsValid())
{
SetTexture(texture);
@ -54,7 +53,7 @@ bool Frame::Load(const String& file_path)
bool Frame::Load(const Resource& res)
{
TexturePtr texture = TextureCache::GetInstance().AddOrGetTexture(res);
TexturePtr texture = Texture::Preload(res);
if (texture->IsValid())
{
SetTexture(texture);

View File

@ -25,6 +25,18 @@
namespace kiwano
{
GifImagePtr GifImage::Preload(const String& file_path)
{
GifImagePtr image = Renderer::GetInstance().CreateGifImage(file_path);
return image;
}
GifImagePtr GifImage::Preload(const Resource& res)
{
GifImagePtr image = Renderer::GetInstance().CreateGifImage(res);
return image;
}
GifImage::GifImage(const String& file_path)
: GifImage()
{

View File

@ -38,6 +38,14 @@ KGE_DECLARE_SMART_PTR(GifImage);
class KGE_API GifImage : public NativeObject
{
public:
/// \~chinese
/// @brief 预加载本地GIF图片
static GifImagePtr Preload(const String& file_path);
/// \~chinese
/// @brief 预加载GIF图片资源
static GifImagePtr Preload(const Resource& res);
/// \~chinese
/// @brief ´´½¨GIFͼƬ
GifImage(const String& file_path);

View File

@ -18,6 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <functional> // std::hash
#include <kiwano/render/Renderer.h>
#include <kiwano/event/WindowEvent.h>
@ -46,6 +47,71 @@ void Renderer::ResetResolutionWhenWindowResized(bool enabled)
auto_reset_resolution_ = enabled;
}
TexturePtr Renderer::CreateTexture(const String& file_path)
{
size_t hash_code = std::hash<String>{}(file_path);
if (TexturePtr ptr = texture_cache_.GetTexture(hash_code))
{
return ptr;
}
TexturePtr ptr = MakePtr<Texture>();
if (ptr && ptr->Load(file_path))
{
texture_cache_.AddTexture(hash_code, ptr);
}
return ptr;
}
TexturePtr Renderer::CreateTexture(const Resource& resource)
{
size_t hash_code = resource.GetId();
if (TexturePtr ptr = texture_cache_.GetTexture(hash_code))
{
return ptr;
}
TexturePtr ptr = MakePtr<Texture>();
if (ptr && ptr->Load(resource))
{
texture_cache_.AddTexture(hash_code, ptr);
}
return ptr;
}
GifImagePtr Renderer::CreateGifImage(const String& file_path)
{
size_t hash_code = std::hash<String>{}(file_path);
if (GifImagePtr ptr = texture_cache_.GetGifImage(hash_code))
{
return ptr;
}
GifImagePtr ptr = MakePtr<GifImage>();
if (ptr && ptr->Load(file_path))
{
texture_cache_.AddGifImage(hash_code, ptr);
}
return ptr;
}
GifImagePtr Renderer::CreateGifImage(const Resource& resource)
{
size_t hash_code = resource.GetId();
if (GifImagePtr ptr = texture_cache_.GetGifImage(hash_code))
{
return ptr;
}
GifImagePtr ptr = MakePtr<GifImage>();
if (ptr && ptr->Load(resource))
{
texture_cache_.AddGifImage(hash_code, ptr);
}
return ptr;
}
void Renderer::Destroy()
{
texture_cache_.Clear();
}
void Renderer::HandleEvent(EventModuleContext& ctx)
{
if (auto_reset_resolution_)
@ -58,4 +124,9 @@ void Renderer::HandleEvent(EventModuleContext& ctx)
}
}
TextureCache& Renderer::GetTextureCache()
{
return texture_cache_;
}
} // namespace kiwano

View File

@ -22,8 +22,9 @@
#include <kiwano/base/Module.h>
#include <kiwano/render/Font.h>
#include <kiwano/render/GifImage.h>
#include <kiwano/render/TextStyle.hpp>
#include <kiwano/render/TextStyle.h>
#include <kiwano/render/RenderContext.h>
#include <kiwano/render/TextureCache.h>
#include <kiwano/platform/Window.h>
namespace kiwano
@ -79,6 +80,26 @@ public:
/// @brief 窗口大小变化时自动调整分辨率
void ResetResolutionWhenWindowResized(bool enabled);
/// \~chinese
/// @brief 创建纹理
/// @param[in] file_path 图片路径
TexturePtr CreateTexture(const String& file_path);
/// \~chinese
/// @brief 创建纹理
/// @param[in] resource 图片资源
TexturePtr CreateTexture(const Resource& resource);
/// \~chinese
/// @brief 创建GIF图像
/// @param[in] file_path 图片路径
GifImagePtr CreateGifImage(const String& file_path);
/// \~chinese
/// @brief 创建GIF图像
/// @param[in] resource 图片资源
GifImagePtr CreateGifImage(const Resource& resource);
/// \~chinese
/// @brief 创建纹理内部资源
/// @param[out] texture 纹理
@ -221,6 +242,10 @@ public:
/// @throw kiwano::SystemError 创建失败时抛出
virtual RenderContextPtr CreateTextureRenderContext(Texture& texture, const Size* desired_size = nullptr) = 0;
/// \~chinese
/// @brief 创建纹理渲染上下文
TextureCache& GetTextureCache();
public:
/// \~chinese
/// @brief 清除绘制内容
@ -237,7 +262,7 @@ public:
/// \~chinese
/// @brief 销毁渲染器资源
virtual void Destroy() = 0;
virtual void Destroy();
void HandleEvent(EventModuleContext& ctx) override;
@ -250,6 +275,8 @@ protected:
Color clear_color_;
Size output_size_;
RenderContextPtr render_ctx_;
TextureCache texture_cache_;
};
/** @} */

View File

@ -21,7 +21,7 @@
#pragma once
#include <kiwano/math/Math.h>
#include <kiwano/render/NativeObject.h>
#include <kiwano/render/TextStyle.hpp>
#include <kiwano/render/TextStyle.h>
namespace kiwano
{

View File

@ -0,0 +1,57 @@
// Copyright (c) 2016-2018 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <kiwano/render/TextStyle.h>
namespace kiwano
{
TextStyle::TextStyle()
: TextStyle(String(), 18, FontWeight::Normal)
{
}
TextStyle::TextStyle(const String& font_family, float font_size, uint32_t font_weight)
: font_size(font_size)
, font_weight(font_weight)
, italic(false)
, alignment(TextAlign::Left)
, wrap_width(0)
, line_spacing(0)
, show_underline(false)
, show_strikethrough(false)
{
font = MakePtr<Font>(font_family);
}
TextStyle::TextStyle(FontPtr font, float font_size, uint32_t font_weight)
: font(font)
, font_size(font_size)
, font_weight(font_weight)
, italic(false)
, alignment(TextAlign::Left)
, wrap_width(0)
, line_spacing(0)
, show_underline(false)
, show_strikethrough(false)
{
}
} // namespace kiwano

View File

@ -71,7 +71,6 @@ class KGE_API TextStyle
{
public:
FontPtr font; ///< 字体
String font_family; ///< ×ÖÌå×å
float font_size; ///< 字号
uint32_t font_weight; ///< 粗细值
bool italic; ///< 是否斜体
@ -99,27 +98,17 @@ public:
* @param font_weight
*/
TextStyle(const String& font_family, float font_size, uint32_t font_weight = FontWeight::Normal);
/**
* \~chinese
* @brief
* @param font
* @param font_size
* @param font_weight
*/
TextStyle(FontPtr font, float font_size, uint32_t font_weight = FontWeight::Normal);
};
/** @} */
inline TextStyle::TextStyle()
: TextStyle(String(), 18, FontWeight::Normal)
{
}
inline TextStyle::TextStyle(const String& font_family, float font_size, uint32_t font_weight)
: font(nullptr)
, font_family(font_family)
, font_size(font_size)
, font_weight(font_weight)
, italic(false)
, alignment(TextAlign::Left)
, wrap_width(0)
, line_spacing(0)
, show_underline(false)
, show_strikethrough(false)
{
}
} // namespace kiwano

View File

@ -30,6 +30,18 @@ namespace kiwano
InterpolationMode Texture::default_interpolation_mode_ = InterpolationMode::Linear;
TexturePtr Texture::Preload(const String& file_path)
{
TexturePtr image = Renderer::GetInstance().CreateTexture(file_path);
return image;
}
TexturePtr Texture::Preload(const Resource& res)
{
TexturePtr image = Renderer::GetInstance().CreateTexture(res);
return image;
}
Texture::Texture(const String& file_path)
: Texture()
{

View File

@ -54,6 +54,16 @@ typedef math::Vec2T<uint32_t> PixelSize;
class KGE_API Texture : public NativeObject
{
public:
/// \~chinese
/// @brief 预加载本地图片
static TexturePtr Preload(const String& file_path);
/// \~chinese
/// @brief 预加载图片资源
static TexturePtr Preload(const Resource& res);
Texture();
/// \~chinese
/// @brief 从本地文件创建纹理
Texture(const String& file_path);
@ -62,8 +72,6 @@ public:
/// @brief 从资源创建纹理
Texture(const Resource& res);
Texture();
virtual ~Texture();
/// \~chinese

View File

@ -18,85 +18,54 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <kiwano/utils/Logger.h>
#include <kiwano/render/Renderer.h>
#include <kiwano/render/TextureCache.h>
namespace kiwano
{
template <typename _Ty, typename _PathTy, typename _CacheTy>
RefPtr<_Ty> CreateOrGetCache(_CacheTy& cache, const _PathTy& path, size_t hash)
{
auto iter = cache.find(hash);
if (iter != cache.end())
{
return iter->second;
}
RefPtr<_Ty> texture = MakePtr<_Ty>();
if (texture->Load(path))
{
cache.insert(std::make_pair(hash, texture));
}
return texture;
}
template <typename _CacheTy>
void RemoveCache(_CacheTy& cache, size_t hash)
{
auto iter = cache.find(hash);
if (iter != cache.end())
{
cache.erase(iter);
}
}
TextureCache::TextureCache() {}
TextureCache::~TextureCache() {}
TexturePtr TextureCache::AddOrGetTexture(const String& file_path)
TextureCache::~TextureCache()
{
size_t hash = std::hash<String>()(file_path);
return CreateOrGetCache<Texture>(texture_cache_, file_path, hash);
Clear();
}
TexturePtr TextureCache::AddOrGetTexture(const Resource& res)
void TextureCache::AddTexture(size_t key, TexturePtr texture)
{
return CreateOrGetCache<Texture>(texture_cache_, res, res.GetId());
texture_cache_.insert(std::make_pair(key, texture));
}
GifImagePtr TextureCache::AddOrGetGifImage(const String& file_path)
void TextureCache::AddGifImage(size_t key, GifImagePtr gif)
{
size_t hash = std::hash<String>()(file_path);
return CreateOrGetCache<GifImage>(gif_texture_cache_, file_path, hash);
gif_texture_cache_.insert(std::make_pair(key, gif));
}
GifImagePtr TextureCache::AddOrGetGifImage(const Resource& res)
TexturePtr TextureCache::GetTexture(size_t key) const
{
return CreateOrGetCache<GifImage>(gif_texture_cache_, res, res.GetId());
if (texture_cache_.count(key))
{
return texture_cache_.at(key);
}
return TexturePtr();
}
void TextureCache::RemoveTexture(const String& file_path)
GifImagePtr TextureCache::GetGifImage(size_t key) const
{
size_t hash = std::hash<String>()(file_path);
RemoveCache(texture_cache_, hash);
if (gif_texture_cache_.count(key))
{
return gif_texture_cache_.at(key);
}
return GifImagePtr();
}
void TextureCache::RemoveTexture(const Resource& res)
void TextureCache::RemoveTexture(size_t key)
{
RemoveCache(texture_cache_, res.GetId());
texture_cache_.erase(key);
}
void TextureCache::RemoveGifImage(const String& file_path)
void TextureCache::RemoveGifImage(size_t key)
{
size_t hash = std::hash<String>()(file_path);
RemoveCache(gif_texture_cache_, hash);
}
void TextureCache::RemoveGifImage(const Resource& res)
{
RemoveCache(gif_texture_cache_, res.GetId());
gif_texture_cache_.erase(key);
}
void TextureCache::Clear()

View File

@ -33,52 +33,41 @@ namespace kiwano
* \~chinese
* @brief
*/
class KGE_API TextureCache final : public Singleton<TextureCache>
class KGE_API TextureCache final : Noncopyable
{
friend Singleton<TextureCache>;
public:
/// \~chinese
/// @brief 添加或获取纹理
TexturePtr AddOrGetTexture(const String& file_path);
TextureCache();
~TextureCache();
/// \~chinese
/// @brief 添加或获取纹理
TexturePtr AddOrGetTexture(const Resource& res);
void AddTexture(size_t key, TexturePtr texture);
/// \~chinese
/// @brief 添加或获取GIF图像
GifImagePtr AddOrGetGifImage(const String& file_path);
void AddGifImage(size_t key, GifImagePtr gif);
/// \~chinese
/// @brief 添加或获取GIF图像
GifImagePtr AddOrGetGifImage(const Resource& res);
/// @brief 获取纹理缓存
TexturePtr GetTexture(size_t key) const;
/// \~chinese
/// @brief 获取GIF图像缓存
GifImagePtr GetGifImage(size_t key) const;
/// \~chinese
/// @brief 移除纹理缓存
void RemoveTexture(const String& file_path);
/// \~chinese
/// @brief 移除纹理缓存
void RemoveTexture(const Resource& res);
void RemoveTexture(size_t key);
/// \~chinese
/// @brief 移除GIF图像缓存
void RemoveGifImage(const String& file_path);
/// \~chinese
/// @brief 移除GIF图像缓存
void RemoveGifImage(const Resource& res);
void RemoveGifImage(size_t key);
/// \~chinese
/// @brief 清空缓存
void Clear();
virtual ~TextureCache();
private:
TextureCache();
private:
using TextureMap = UnorderedMap<size_t, TexturePtr>;
TextureMap texture_cache_;

View File

@ -185,8 +185,8 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String&
if (type == "gif")
{
// GIF image
GifImagePtr gif = MakePtr<GifImage>();
if (gif && gif->Load(gdata->path + file))
GifImagePtr gif = GifImage::Preload(gdata->path + file);
if (gif)
{
cache->AddObject(id, gif);
return;
@ -273,8 +273,8 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String&
void LoadFontsFromData(ResourceCache* cache, GlobalData* gdata, const String& id, const String& file)
{
FontPtr font = MakePtr<Font>();
if (font && font->Load(gdata->path + file))
FontPtr font = Font::Preload(gdata->path + file);
if (font)
{
cache->AddObject(id, font);
return;