#pragma once #include #include #include #include #include #include #include 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 get(const std::string& filepath); /** * @brief 异步加载纹理 * @param filepath 纹理文件路径 * @param callback 加载完成回调 */ void getAsync(const std::string& filepath, std::function)> callback); /** * @brief 从内存数据创建纹理(自动缓存) * @param name 纹理名称(用于缓存键) * @param data 图像数据 * @param width 宽度 * @param height 高度 * @param format 像素格式 * @return 纹理对象 */ Ptr 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); /** * @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; size_t size; // 纹理大小(字节) float lastAccessTime; // 最后访问时间 uint32_t accessCount; // 访问次数 }; // LRU列表(最近使用的在前面) using LRUList = std::list; using LRUIterator = LRUList::iterator; mutable std::mutex mutex_; TexturePoolConfig config_; // 缓存存储 std::unordered_map cache_; std::unordered_map 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)> callback; }; std::vector asyncTasks_; // 内部方法 void touch(const std::string& key); void evict(); Ptr 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