mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-16 14:05:07 +03:00
graphics: move texture ownership to catalogs and scopes
Add ResourceCatalog and ResourceScope to provide explicit strong ownership and deterministic semantic lookup independently from the live texture registry. Let Engine own the global catalog and default Graphics scope, and give each UISceneNode an isolated scope that can be explicitly shared with other scenes. Remove TextureFactory's strong texture retention and name/hash lookup. The factory now observes textures weakly for identity, diagnostics, and deferred destruction without controlling their semantic lifetime. Migrate drawable resolution, texture atlas loading, UI image caches, tile maps, ecode resources, and related tests to scoped lookup and publication. Allow final TexturePtr release from worker threads while keeping actual texture destruction deferred to the graphics thread. Fix mismatched pixel deallocation uncovered by asynchronous texture loading tests. Add ownership, scope isolation, scene sharing, worker release, and decoder allocation regression tests, and update the shared-resource architecture plan through Stage 3.
This commit is contained in:
@@ -47,6 +47,8 @@
|
||||
#include <eepp/graphics/renderer/rendererhelper.hpp>
|
||||
#include <eepp/graphics/rendermode.hpp>
|
||||
#include <eepp/graphics/richtext.hpp>
|
||||
#include <eepp/graphics/resourcecatalog.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/scopedtexture.hpp>
|
||||
#include <eepp/graphics/scrollparallax.hpp>
|
||||
#include <eepp/graphics/shader.hpp>
|
||||
|
||||
@@ -7,10 +7,13 @@
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
class ResourceScope;
|
||||
|
||||
class EE_API DrawableSearcher {
|
||||
public:
|
||||
static Drawable* searchByName( const std::string& name, bool firstSearchSprite = false,
|
||||
Network::URI referer = "" );
|
||||
Network::URI referer = "",
|
||||
ResourceScope* resourceScope = nullptr );
|
||||
|
||||
static Drawable* searchById( const Uint32& id );
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#define EE_GRAPHICS_RESOURCE_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <eepp/core.hpp>
|
||||
|
||||
@@ -25,6 +27,22 @@ class ResourceId {
|
||||
Uint64 mValue{ 0 };
|
||||
};
|
||||
|
||||
/** Immutable semantic lookup key. Catalog equality always compares the complete key value. */
|
||||
class ResourceKey {
|
||||
public:
|
||||
ResourceKey() = default;
|
||||
explicit ResourceKey( std::string value ) : mValue( std::move( value ) ) {}
|
||||
|
||||
const std::string& value() const { return mValue; }
|
||||
bool empty() const { return mValue.empty(); }
|
||||
|
||||
bool operator==( const ResourceKey& other ) const { return mValue == other.mValue; }
|
||||
bool operator!=( const ResourceKey& other ) const { return !( *this == other ); }
|
||||
|
||||
private:
|
||||
std::string mValue;
|
||||
};
|
||||
|
||||
template <typename T> using ResourcePtr = std::shared_ptr<T>;
|
||||
template <typename T> using ResourceWeakPtr = std::weak_ptr<T>;
|
||||
|
||||
|
||||
37
include/eepp/graphics/resourcecatalog.hpp
Normal file
37
include/eepp/graphics/resourcecatalog.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef EE_GRAPHICS_RESOURCECATALOG_HPP
|
||||
#define EE_GRAPHICS_RESOURCECATALOG_HPP
|
||||
|
||||
#include <eepp/core/containers.hpp>
|
||||
#include <eepp/graphics/resource.hpp>
|
||||
#include <eepp/graphics/texture.hpp>
|
||||
#include <eepp/system/mutex.hpp>
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
class ResourceCatalog;
|
||||
using ResourceCatalogPtr = ResourcePtr<ResourceCatalog>;
|
||||
|
||||
/** Strong, named ownership for Graphics resources. The live registry is never searched here. */
|
||||
class EE_API ResourceCatalog {
|
||||
public:
|
||||
static ResourceCatalogPtr New();
|
||||
|
||||
void publish( ResourceKey key, TexturePtr texture );
|
||||
void publish( std::string key, TexturePtr texture );
|
||||
|
||||
TexturePtr findTexture( const ResourceKey& key ) const;
|
||||
TexturePtr findTexture( const std::string& key ) const;
|
||||
|
||||
bool erase( const ResourceKey& key );
|
||||
bool erase( const std::string& key );
|
||||
void clear();
|
||||
std::size_t size() const;
|
||||
|
||||
private:
|
||||
mutable System::Mutex mMutex;
|
||||
UnorderedMap<std::string, TexturePtr> mTextures;
|
||||
};
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
#endif
|
||||
45
include/eepp/graphics/resourcescope.hpp
Normal file
45
include/eepp/graphics/resourcescope.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef EE_GRAPHICS_RESOURCESCOPE_HPP
|
||||
#define EE_GRAPHICS_RESOURCESCOPE_HPP
|
||||
|
||||
#include <eepp/graphics/resourcecatalog.hpp>
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
class ResourceScope;
|
||||
using ResourceScopePtr = ResourcePtr<ResourceScope>;
|
||||
|
||||
/** Graphics-only semantic lookup boundary with a local catalog and explicit catalog imports. */
|
||||
class EE_API ResourceScope {
|
||||
public:
|
||||
static ResourceScopePtr New();
|
||||
|
||||
ResourceScope();
|
||||
|
||||
TexturePtr findTexture( const ResourceKey& key ) const;
|
||||
TexturePtr findTexture( const std::string& key ) const;
|
||||
|
||||
void publishLocal( ResourceKey key, TexturePtr texture );
|
||||
void publishLocal( std::string key, TexturePtr texture );
|
||||
bool eraseLocal( const ResourceKey& key );
|
||||
bool eraseLocal( const std::string& key );
|
||||
void clearLocal();
|
||||
|
||||
void importCatalog( ResourceCatalogPtr catalog );
|
||||
bool removeCatalog( const ResourceCatalogPtr& catalog );
|
||||
void clearImports();
|
||||
|
||||
ResourceCatalogPtr getLocalCatalog() const;
|
||||
|
||||
private:
|
||||
ResourceCatalogPtr mLocalCatalog;
|
||||
std::vector<ResourceCatalogPtr> mImports;
|
||||
mutable System::Mutex mMutex;
|
||||
};
|
||||
|
||||
/** Engine-owned process defaults for pure Graphics and legacy application-wide resolution. */
|
||||
EE_API ResourceCatalog& globalResourceCatalog();
|
||||
EE_API ResourceScope& defaultResourceScope();
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
#endif
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <eepp/graphics/base.hpp>
|
||||
#include <eepp/graphics/packerhelper.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/texturefactory.hpp>
|
||||
#include <eepp/graphics/textureloader.hpp>
|
||||
#include <eepp/system/iostream.hpp>
|
||||
@@ -161,6 +162,11 @@ class EE_API TextureAtlasLoader {
|
||||
|
||||
void setTextureFilter( const Texture::Filter& textureFilter );
|
||||
|
||||
/** Sets the semantic texture lookup boundary used by subsequent loads. */
|
||||
void setResourceScope( ResourceScopePtr resourceScope );
|
||||
|
||||
const ResourceScopePtr& getResourceScope() const;
|
||||
|
||||
protected:
|
||||
std::string mTextureAtlasPath;
|
||||
bool mThreaded;
|
||||
@@ -170,6 +176,7 @@ class EE_API TextureAtlasLoader {
|
||||
std::atomic<bool> mIsLoading;
|
||||
TextureAtlas* mTextureAtlas;
|
||||
GLLoadCallback mLoadCallback;
|
||||
ResourceScopePtr mResourceScope;
|
||||
std::vector<TexturePtr> mTexturesLoaded;
|
||||
|
||||
struct sTempTexAtlas {
|
||||
|
||||
@@ -21,7 +21,7 @@ struct TextureRegistryRecord {
|
||||
|
||||
using TextureRegistrySnapshot = std::vector<TextureRegistryRecord>;
|
||||
|
||||
/** @brief The Texture Manager Class. Here we do all the textures stuff. (Singleton Class) */
|
||||
/** Creates textures and weakly observes every live texture for diagnostics. */
|
||||
class EE_API TextureFactory : protected Mutex {
|
||||
SINGLETON_DECLARE_HEADERS( TextureFactory )
|
||||
|
||||
@@ -172,7 +172,7 @@ class EE_API TextureFactory : protected Mutex {
|
||||
*/
|
||||
void setCurrentTexture( const int& textureHandle, const Uint32& TextureUnit );
|
||||
|
||||
/** Returns the number of textures loaded */
|
||||
/** Returns the number of currently live textures. */
|
||||
Uint32 getTextureCount();
|
||||
|
||||
/** @return A non-owning diagnostic snapshot of every currently live texture. */
|
||||
@@ -201,10 +201,10 @@ class EE_API TextureFactory : protected Mutex {
|
||||
*/
|
||||
unsigned int getValidTextureSize( const unsigned int& Size );
|
||||
|
||||
/** Determines whether the texture identity exists in the factory. */
|
||||
/** Determines whether the texture identity is currently live. */
|
||||
bool existsId( ResourceId textureId );
|
||||
|
||||
/** @return The texture matching @p textureId, or null if it is not factory-retained. */
|
||||
/** @return The live texture matching @p textureId, or null if it has expired. */
|
||||
TexturePtr getTexture( ResourceId textureId );
|
||||
|
||||
/** @return The memory used by the textures (in bytes) */
|
||||
@@ -233,32 +233,17 @@ class EE_API TextureFactory : protected Mutex {
|
||||
const Texture::ClampMode& ClampMode, const bool& CompressTexture,
|
||||
const bool& LocalCopy = false, const Uint32& MemSize = 0 );
|
||||
|
||||
/** Return a texture by it file path name
|
||||
* @param Name File path name
|
||||
* @return The texture, NULL if not exists.
|
||||
*/
|
||||
TexturePtr getByName( const std::string& Name );
|
||||
|
||||
/** Return a texture by it hash path name
|
||||
* @param Hash The file path hash
|
||||
* @return The texture, NULL if not exists
|
||||
*/
|
||||
TexturePtr getByHash( const String::HashType& hash );
|
||||
|
||||
~TextureFactory();
|
||||
|
||||
const Texture::CoordinateType& getLastCoordinateType() const;
|
||||
|
||||
protected:
|
||||
friend class Texture;
|
||||
friend class TextureLoader;
|
||||
|
||||
TextureFactory();
|
||||
|
||||
std::vector<int> mCurrentTexture;
|
||||
|
||||
using TextureMap = UnorderedMap<Uint64, TexturePtr>;
|
||||
|
||||
struct LiveTextureRecord {
|
||||
ResourceId id;
|
||||
TextureWeakPtr texture;
|
||||
@@ -268,19 +253,16 @@ class EE_API TextureFactory : protected Mutex {
|
||||
void operator()( Texture* texture ) const noexcept;
|
||||
};
|
||||
|
||||
TextureMap mTextures;
|
||||
UnorderedMap<Uint64, LiveTextureRecord> mLiveTextures;
|
||||
std::vector<Texture*> mReleasedTextures;
|
||||
std::atomic<Uint64> mLiveTextureGeneration{ 0 };
|
||||
|
||||
Texture::CoordinateType mLastCoordinateType;
|
||||
|
||||
void unloadTextures();
|
||||
|
||||
void resetTextureBinding( const Texture* texture );
|
||||
|
||||
bool releaseRetainedTexture( ResourceId textureId );
|
||||
|
||||
/** Thread-safe final-handle handoff. Actual Texture destruction remains graphics-thread-only.
|
||||
*/
|
||||
void queueReleasedTexture( Texture* texture );
|
||||
|
||||
void diagnoseLiveTexturesAtShutdown();
|
||||
|
||||
@@ -137,12 +137,14 @@ class EE_API TextureLoader {
|
||||
bool mLoaded{ false };
|
||||
bool mTexLoaded{ false };
|
||||
bool mDirectUpload{ false };
|
||||
bool mPixelsUseSystemFree{ false };
|
||||
Image::Format mImgType{ 0 };
|
||||
int mIsCompressed{ 0 };
|
||||
|
||||
Clock mTE;
|
||||
|
||||
void loadFile();
|
||||
void freePixels();
|
||||
void loadFromFile();
|
||||
void loadFromMemory();
|
||||
void loadFromPack();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef EE_UISCENENODE_HPP
|
||||
#define EE_UISCENENODE_HPP
|
||||
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/systemfontresolver.hpp>
|
||||
#include <eepp/network/cookiemanager.hpp>
|
||||
#include <eepp/network/uri.hpp>
|
||||
@@ -153,8 +154,8 @@ class EE_API UISceneNode : public SceneNode {
|
||||
*
|
||||
* Copies only shared platform/configuration services: dispatcher, DPI/window pointer,
|
||||
* thread pool, color/contrast preferences, and default font/theme pointers. Stylesheets,
|
||||
* URI, referer, cookies, navigation callbacks, actions, roots, and dirty queues remain owned
|
||||
* by this scene.
|
||||
* URI, referer, cookies, navigation callbacks, actions, roots, resource scope, and dirty queues
|
||||
* remain owned by this scene.
|
||||
*/
|
||||
void initializeEmbeddedFromHost( UISceneNode* hostScene );
|
||||
|
||||
@@ -770,6 +771,12 @@ class EE_API UISceneNode : public SceneNode {
|
||||
*/
|
||||
void setThreadPool( const std::shared_ptr<ThreadPool>& threadPool );
|
||||
|
||||
/** @return The Graphics resource lookup and ownership boundary of this scene. */
|
||||
const Graphics::ResourceScopePtr& getResourceScope() const;
|
||||
|
||||
/** Replaces this scene's resource boundary, allowing intentional sharing between scenes. */
|
||||
UISceneNode* setResourceScope( Graphics::ResourceScopePtr resourceScope );
|
||||
|
||||
/**
|
||||
* @brief Sets the theme for the entire UI scene.
|
||||
*
|
||||
@@ -902,6 +909,7 @@ class EE_API UISceneNode : public SceneNode {
|
||||
UnorderedMap<std::string, Font*> mFontFaceAliases;
|
||||
UnorderedMap<Font*, std::string> mFontFaceFamilies;
|
||||
std::shared_ptr<AsyncResourceLoadState> mAsyncResourceLoadState;
|
||||
Graphics::ResourceScopePtr mResourceScope;
|
||||
KeyBindings mKeyBindings;
|
||||
std::map<std::string, KeyBindingCommand> mKeyBindingCommands;
|
||||
UnorderedSet<UIWidget*> mDirtyStyle;
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
#include <eepp/window/platformhelper.hpp>
|
||||
#include <eepp/window/window.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
class ResourceCatalog;
|
||||
class ResourceScope;
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
namespace EE { namespace System {
|
||||
class IniFile;
|
||||
class Pack;
|
||||
@@ -140,6 +147,12 @@ class EE_API Engine {
|
||||
/** @return The display manager. Holds the physical displays information. */
|
||||
DisplayManager* getDisplayManager();
|
||||
|
||||
/** @return The catalog used for resources intentionally exported application-wide. */
|
||||
std::shared_ptr<Graphics::ResourceCatalog> getGlobalResourceCatalog() const;
|
||||
|
||||
/** @return The default Graphics scope. It explicitly imports the global resource catalog. */
|
||||
std::shared_ptr<Graphics::ResourceScope> getDefaultResourceScope() const;
|
||||
|
||||
/** Open a URL in a separate, system-provided application.
|
||||
* @return true if success
|
||||
*/
|
||||
@@ -156,6 +169,8 @@ class EE_API Engine {
|
||||
PlatformHelper* mPlatformHelper;
|
||||
Pack* mZip;
|
||||
DisplayManager* mDisplayManager;
|
||||
std::shared_ptr<Graphics::ResourceCatalog> mGlobalResourceCatalog;
|
||||
std::shared_ptr<Graphics::ResourceScope> mDefaultResourceScope;
|
||||
|
||||
Engine();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user