Extra2D/Easy2D/include/easy2d/graphics/texture_pool.h

195 lines
5.8 KiB
C
Raw Normal View History

#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