195 lines
5.8 KiB
C
195 lines
5.8 KiB
C
|
|
#pragma once
|
|||
|
|
|
|||
|
|
#include <easy2d/core/types.h>
|
|||
|
|
#include <easy2d/graphics/texture.h>
|
|||
|
|
#include <string>
|
|||
|
|
#include <unordered_map>
|
|||
|
|
#include <list>
|
|||
|
|
#include <functional>
|
|||
|
|
#include <mutex>
|
|||
|
|
|
|||
|
|
namespace easy2d {
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// 纹理池配置
|
|||
|
|
// ============================================================================
|
|||
|
|
struct TexturePoolConfig {
|
|||
|
|
size_t maxCacheSize = 64 * 1024 * 1024; // 最大缓存大小 (64MB)
|
|||
|
|
size_t maxTextureCount = 256; // 最大纹理数量
|
|||
|
|
float unloadInterval = 30.0f; // 自动清理间隔 (秒)
|
|||
|
|
bool enableAsyncLoad = true; // 启用异步加载
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// 纹理池 - 使用LRU缓存策略管理纹理复用
|
|||
|
|
// ============================================================================
|
|||
|
|
class TexturePool {
|
|||
|
|
public:
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
// 单例访问
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
static TexturePool& getInstance();
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
// 初始化和关闭
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
bool init(const TexturePoolConfig& config = TexturePoolConfig{});
|
|||
|
|
void shutdown();
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
// 纹理获取
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 从文件获取纹理(带缓存)
|
|||
|
|
* @param filepath 纹理文件路径
|
|||
|
|
* @return 纹理对象,失败返回nullptr
|
|||
|
|
*/
|
|||
|
|
Ptr<Texture> get(const std::string& filepath);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 异步加载纹理
|
|||
|
|
* @param filepath 纹理文件路径
|
|||
|
|
* @param callback 加载完成回调
|
|||
|
|
*/
|
|||
|
|
void getAsync(const std::string& filepath,
|
|||
|
|
std::function<void(Ptr<Texture>)> callback);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 从内存数据创建纹理(自动缓存)
|
|||
|
|
* @param name 纹理名称(用于缓存键)
|
|||
|
|
* @param data 图像数据
|
|||
|
|
* @param width 宽度
|
|||
|
|
* @param height 高度
|
|||
|
|
* @param format 像素格式
|
|||
|
|
* @return 纹理对象
|
|||
|
|
*/
|
|||
|
|
Ptr<Texture> createFromData(const std::string& name,
|
|||
|
|
const uint8_t* data,
|
|||
|
|
int width,
|
|||
|
|
int height,
|
|||
|
|
PixelFormat format = PixelFormat::RGBA8);
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
// 缓存管理
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 手动添加纹理到缓存
|
|||
|
|
*/
|
|||
|
|
void add(const std::string& key, Ptr<Texture> texture);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 从缓存移除纹理
|
|||
|
|
*/
|
|||
|
|
void remove(const std::string& key);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 检查纹理是否在缓存中
|
|||
|
|
*/
|
|||
|
|
bool has(const std::string& key) const;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 清空所有缓存
|
|||
|
|
*/
|
|||
|
|
void clear();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 清理未使用的纹理(LRU策略)
|
|||
|
|
* @param targetSize 目标缓存大小
|
|||
|
|
*/
|
|||
|
|
void trim(size_t targetSize);
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
// 统计信息
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 获取当前缓存的纹理数量
|
|||
|
|
*/
|
|||
|
|
size_t getTextureCount() const;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 获取当前缓存的总大小(字节)
|
|||
|
|
*/
|
|||
|
|
size_t getCacheSize() const;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 获取缓存命中率
|
|||
|
|
*/
|
|||
|
|
float getHitRate() const;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 打印统计信息
|
|||
|
|
*/
|
|||
|
|
void printStats() const;
|
|||
|
|
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
// 自动清理
|
|||
|
|
// ------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 更新(在主循环中调用,用于自动清理)
|
|||
|
|
*/
|
|||
|
|
void update(float dt);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 设置自动清理间隔
|
|||
|
|
*/
|
|||
|
|
void setAutoUnloadInterval(float interval);
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
TexturePool() = default;
|
|||
|
|
~TexturePool() = default;
|
|||
|
|
TexturePool(const TexturePool&) = delete;
|
|||
|
|
TexturePool& operator=(const TexturePool&) = delete;
|
|||
|
|
|
|||
|
|
// 缓存项
|
|||
|
|
struct CacheEntry {
|
|||
|
|
Ptr<Texture> texture;
|
|||
|
|
size_t size; // 纹理大小(字节)
|
|||
|
|
float lastAccessTime; // 最后访问时间
|
|||
|
|
uint32_t accessCount; // 访问次数
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// LRU列表(最近使用的在前面)
|
|||
|
|
using LRUList = std::list<std::string>;
|
|||
|
|
using LRUIterator = LRUList::iterator;
|
|||
|
|
|
|||
|
|
mutable std::mutex mutex_;
|
|||
|
|
TexturePoolConfig config_;
|
|||
|
|
|
|||
|
|
// 缓存存储
|
|||
|
|
std::unordered_map<std::string, CacheEntry> cache_;
|
|||
|
|
std::unordered_map<std::string, LRUIterator> lruMap_;
|
|||
|
|
LRUList lruList_;
|
|||
|
|
|
|||
|
|
// 统计
|
|||
|
|
size_t totalSize_ = 0;
|
|||
|
|
uint64_t hitCount_ = 0;
|
|||
|
|
uint64_t missCount_ = 0;
|
|||
|
|
float autoUnloadTimer_ = 0.0f;
|
|||
|
|
bool initialized_ = false;
|
|||
|
|
|
|||
|
|
// 异步加载队列
|
|||
|
|
struct AsyncLoadTask {
|
|||
|
|
std::string filepath;
|
|||
|
|
std::function<void(Ptr<Texture>)> callback;
|
|||
|
|
};
|
|||
|
|
std::vector<AsyncLoadTask> asyncTasks_;
|
|||
|
|
|
|||
|
|
// 内部方法
|
|||
|
|
void touch(const std::string& key);
|
|||
|
|
void evict();
|
|||
|
|
Ptr<Texture> loadTexture(const std::string& filepath);
|
|||
|
|
size_t calculateTextureSize(int width, int height, PixelFormat format);
|
|||
|
|
void processAsyncTasks();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// 便捷宏
|
|||
|
|
// ============================================================================
|
|||
|
|
#define E2D_TEXTURE_POOL() ::easy2d::TexturePool::getInstance()
|
|||
|
|
|
|||
|
|
} // namespace easy2d
|