TextureFactory small refactor.

Fix in getTextureCacheName.
This commit is contained in:
Martín Lucas Golini
2026-07-05 19:21:23 -03:00
parent 4f3e5309a4
commit ab14972fd3
6 changed files with 120 additions and 76 deletions
+8 -10
View File
@@ -1,6 +1,7 @@
#ifndef EECTEXTUREFACTORY_H #ifndef EECTEXTUREFACTORY_H
#define EECTEXTUREFACTORY_H #define EECTEXTUREFACTORY_H
#include <eepp/core/containers.hpp>
#include <eepp/graphics/base.hpp> #include <eepp/graphics/base.hpp>
#include <eepp/graphics/texture.hpp> #include <eepp/graphics/texture.hpp>
#include <eepp/system/mutex.hpp> #include <eepp/system/mutex.hpp>
@@ -182,7 +183,7 @@ class EE_API TextureFactory : protected Mutex {
void setCurrentTexture( const int& TexId, const Uint32& TextureUnit ); void setCurrentTexture( const int& TexId, const Uint32& TextureUnit );
/** Returns the number of textures loaded */ /** Returns the number of textures loaded */
Uint32 getTextureCount() const { return (Uint32)mTextures.size(); } Uint32 getTextureCount();
/** @return All the active textures */ /** @return All the active textures */
std::vector<Texture*> getTextures(); std::vector<Texture*> getTextures();
@@ -211,11 +212,8 @@ class EE_API TextureFactory : protected Mutex {
/** Reload all the grabbed textures */ /** Reload all the grabbed textures */
void ungrabTextures(); void ungrabTextures();
/** Allocate space for Textures (only works if EE_ALLOC_TEXTURES_ON_VECTOR is defined) */
void allocate( const unsigned int& size );
/** @return The memory used by the textures (in bytes) */ /** @return The memory used by the textures (in bytes) */
unsigned int getTextureMemorySize() { return mMemSize; } unsigned int getTextureMemorySize();
/** It's possible to create textures outside the texture factory loader, but the library will /** It's possible to create textures outside the texture factory loader, but the library will
* need to know of this texture, so it's necessary to push the texture to the factory. * need to know of this texture, so it's necessary to push the texture to the factory.
@@ -263,23 +261,23 @@ class EE_API TextureFactory : protected Mutex {
std::vector<int> mCurrentTexture; std::vector<int> mCurrentTexture;
std::vector<Texture*> mTextures; UnorderedMap<Uint32, Texture*> mTextures;
unsigned int mMemSize; unsigned int mMemSize;
std::vector<Uint32> mVectorFreeSlots; Uint32 mTextureIdSeq;
Texture::CoordinateType mLastCoordinateType; Texture::CoordinateType mLastCoordinateType;
void unloadTextures(); void unloadTextures();
Uint32 findFreeSlot();
bool mErasing; bool mErasing;
const bool& isErasing() const; bool isErasing();
void removeReference( Texture* Tex ); void removeReference( Texture* Tex );
void updateMemorySize( Uint32 oldSize, Uint32 newSize );
}; };
}} // namespace EE::Graphics }} // namespace EE::Graphics
+4 -5
View File
@@ -481,8 +481,7 @@ void Texture::reload() {
mTexture = SOIL_create_OGL_texture( reinterpret_cast<Uint8*>( &mPixels[0] ), &width, mTexture = SOIL_create_OGL_texture( reinterpret_cast<Uint8*>( &mPixels[0] ), &width,
&height, mChannels, mTexture, flags ); &height, mChannels, mTexture, flags );
TextureFactory::instance()->mMemSize -= mSize; Uint32 oldSize = mSize;
mSize = mWidth * mHeight * mChannels; mSize = mWidth * mHeight * mChannels;
if ( getMipmap() ) { if ( getMipmap() ) {
@@ -496,7 +495,7 @@ void Texture::reload() {
} }
} }
TextureFactory::instance()->mMemSize += mSize; TextureFactory::instance()->updateMemorySize( oldSize, mSize );
} }
iTextureFilter( mFilter ); iTextureFilter( mFilter );
@@ -593,9 +592,9 @@ void Texture::replace( Image* image ) {
mHeight = mImgHeight = height; mHeight = mImgHeight = height;
mChannels = image->getChannels(); mChannels = image->getChannels();
TextureFactory::instance()->mMemSize -= mSize; Uint32 oldSize = mSize;
mSize = mWidth * mHeight * mChannels; mSize = mWidth * mHeight * mChannels;
TextureFactory::instance()->mMemSize += mSize; TextureFactory::instance()->updateMemorySize( oldSize, mSize );
if ( hasLocalCopy() ) { if ( hasLocalCopy() ) {
// Renew the local copy // Renew the local copy
+92 -57
View File
@@ -7,6 +7,7 @@
#include <eepp/graphics/texturefactory.hpp> #include <eepp/graphics/texturefactory.hpp>
#include <eepp/graphics/textureloader.hpp> #include <eepp/graphics/textureloader.hpp>
#include <eepp/system/filesystem.hpp> #include <eepp/system/filesystem.hpp>
#include <eepp/system/lock.hpp>
#include <eepp/system/log.hpp> #include <eepp/system/log.hpp>
#include <jpeg-compressor/jpge.h> #include <jpeg-compressor/jpge.h>
@@ -17,11 +18,9 @@ SINGLETON_DECLARE_IMPLEMENTATION( TextureFactory )
TextureFactory::TextureFactory() : TextureFactory::TextureFactory() :
mCurrentTexture( EE_MAX_TEXTURE_UNITS ), mCurrentTexture( EE_MAX_TEXTURE_UNITS ),
mMemSize( 0 ), mMemSize( 0 ),
mTextureIdSeq( 0 ),
mLastCoordinateType( Texture::CoordinateType::Normalized ), mLastCoordinateType( Texture::CoordinateType::Normalized ),
mErasing( false ) { mErasing( false ) {}
mTextures.clear();
mTextures.push_back( NULL );
}
const Texture::CoordinateType& TextureFactory::getLastCoordinateType() const { const Texture::CoordinateType& TextureFactory::getLastCoordinateType() const {
return mLastCoordinateType; return mLastCoordinateType;
@@ -104,7 +103,7 @@ Texture* TextureFactory::pushTexture( const std::string& Filepath, const Uint32&
const Texture::ClampMode& ClampMode, const Texture::ClampMode& ClampMode,
const bool& CompressTexture, const bool& LocalCopy, const bool& CompressTexture, const bool& LocalCopy,
const Uint32& MemSize ) { const Uint32& MemSize ) {
lock(); Lock l( *this );
Texture* Tex = NULL; Texture* Tex = NULL;
Uint32 Pos; Uint32 Pos;
@@ -113,7 +112,7 @@ Texture* TextureFactory::pushTexture( const std::string& Filepath, const Uint32&
FileSystem::filePathRemoveProcessPath( FPath ); FileSystem::filePathRemoveProcessPath( FPath );
Pos = findFreeSlot(); Pos = ++mTextureIdSeq;
Tex = mTextures[Pos] = eeNew( Texture, () ); Tex = mTextures[Pos] = eeNew( Texture, () );
Tex->create( TexId, Width, Height, ImgWidth, ImgHeight, Mipmap, Channels, FPath, ClampMode, Tex->create( TexId, Width, Height, ImgWidth, ImgHeight, Mipmap, Channels, FPath, ClampMode,
@@ -127,25 +126,9 @@ Texture* TextureFactory::pushTexture( const std::string& Filepath, const Uint32&
mMemSize += MemSize; mMemSize += MemSize;
unlock();
return Tex; return Tex;
} }
Uint32 TextureFactory::findFreeSlot() {
if ( !mVectorFreeSlots.empty() ) {
Uint32 Pos = mVectorFreeSlots.front();
mVectorFreeSlots.erase( mVectorFreeSlots.begin() );
return Pos;
}
mTextures.push_back( NULL );
return (Uint32)mTextures.size() - 1;
}
void TextureFactory::bind( const Texture* texture, Texture::CoordinateType coordinateType, void TextureFactory::bind( const Texture* texture, Texture::CoordinateType coordinateType,
const Uint32& TextureUnit, const bool& forceRebind ) { const Uint32& TextureUnit, const bool& forceRebind ) {
if ( NULL != texture ) { if ( NULL != texture ) {
@@ -195,23 +178,29 @@ void TextureFactory::bind( const Uint32& TexId, Texture::CoordinateType coordina
} }
void TextureFactory::unloadTextures() { void TextureFactory::unloadTextures() {
Lock l( *this );
mErasing = true; mErasing = true;
for ( Uint32 i = 1; i < mTextures.size(); i++ ) for ( auto& texture : mTextures )
eeSAFE_DELETE( mTextures[i] ); eeSAFE_DELETE( texture.second );
mErasing = false; mErasing = false;
mTextures.clear(); mTextures.clear();
mTextureIdSeq = 0;
Log::debug( "Textures Unloaded." ); Log::debug( "Textures Unloaded." );
} }
bool TextureFactory::remove( Uint32 TexId ) { bool TextureFactory::remove( Uint32 TexId ) {
Texture* Tex; Lock l( *this );
if ( TexId < mTextures.size() && NULL != ( Tex = mTextures[TexId] ) ) { Texture* Tex;
removeReference( mTextures[TexId] ); auto it = mTextures.find( TexId );
if ( it != mTextures.end() && NULL != ( Tex = it->second ) ) {
removeReference( Tex );
mErasing = true; mErasing = true;
eeDelete( Tex ); eeDelete( Tex );
@@ -224,29 +213,51 @@ bool TextureFactory::remove( Uint32 TexId ) {
} }
bool TextureFactory::remove( Texture* texture ) { bool TextureFactory::remove( Texture* texture ) {
if ( std::find( mTextures.begin(), mTextures.end(), texture ) != mTextures.end() ) { Lock l( *this );
auto it = std::find_if( mTextures.begin(), mTextures.end(),
[texture]( const auto& pair ) { return pair.second == texture; } );
if ( it != mTextures.end() ) {
removeReference( texture ); removeReference( texture );
mErasing = true;
eeDelete( texture );
mErasing = false;
return true; return true;
} }
return false; return false;
} }
void TextureFactory::removeReference( Texture* Tex ) { void TextureFactory::removeReference( Texture* Tex ) {
Lock l( *this );
auto it = mTextures.find( Tex->getTextureId() );
if ( it == mTextures.end() || it->second != Tex )
return;
mMemSize -= Tex->getMemSize(); mMemSize -= Tex->getMemSize();
int glTexId = Tex->getHandle(); int glTexId = Tex->getHandle();
mTextures[Tex->getTextureId()] = NULL; mTextures.erase( it );
for ( Uint32 i = 0; i < EE_MAX_TEXTURE_UNITS; i++ ) { for ( Uint32 i = 0; i < EE_MAX_TEXTURE_UNITS; i++ ) {
if ( mCurrentTexture[i] == (Int32)glTexId ) if ( mCurrentTexture[i] == (Int32)glTexId )
mCurrentTexture[i] = 0; mCurrentTexture[i] = 0;
} }
mVectorFreeSlots.push_back( Tex->getTextureId() );
} }
const bool& TextureFactory::isErasing() const { void TextureFactory::updateMemorySize( Uint32 oldSize, Uint32 newSize ) {
Lock l( *this );
mMemSize -= oldSize;
mMemSize += newSize;
}
bool TextureFactory::isErasing() {
Lock l( *this );
return mErasing; return mErasing;
} }
@@ -261,11 +272,13 @@ void TextureFactory::setCurrentTexture( const int& TexId, const Uint32& TextureU
} }
std::vector<Texture*> TextureFactory::getTextures() { std::vector<Texture*> TextureFactory::getTextures() {
Lock l( *this );
std::vector<Texture*> textures; std::vector<Texture*> textures;
textures.reserve( mTextures.size() ); textures.reserve( mTextures.size() );
for ( Uint32 i = 1; i < mTextures.size(); i++ ) { for ( const auto& texture : mTextures ) {
Texture* Tex = getTexture( i ); Texture* Tex = texture.second;
if ( Tex ) if ( Tex )
textures.push_back( Tex ); textures.push_back( Tex );
@@ -275,8 +288,10 @@ std::vector<Texture*> TextureFactory::getTextures() {
} }
void TextureFactory::reloadAllTextures() { void TextureFactory::reloadAllTextures() {
for ( Uint32 i = 1; i < mTextures.size(); i++ ) { Lock l( *this );
Texture* Tex = getTexture( i );
for ( const auto& texture : mTextures ) {
Texture* Tex = texture.second;
if ( Tex ) if ( Tex )
Tex->reload(); Tex->reload();
@@ -286,8 +301,10 @@ void TextureFactory::reloadAllTextures() {
} }
void TextureFactory::grabTextures() { void TextureFactory::grabTextures() {
for ( Uint32 i = 1; i < mTextures.size(); i++ ) { Lock l( *this );
Texture* Tex = getTexture( i );
for ( const auto& texture : mTextures ) {
Texture* Tex = texture.second;
if ( Tex && !Tex->hasLocalCopy() ) { if ( Tex && !Tex->hasLocalCopy() ) {
Tex->lock(); Tex->lock();
@@ -297,8 +314,10 @@ void TextureFactory::grabTextures() {
} }
void TextureFactory::ungrabTextures() { void TextureFactory::ungrabTextures() {
for ( Uint32 i = 1; i < mTextures.size(); i++ ) { Lock l( *this );
Texture* Tex = getTexture( i );
for ( const auto& texture : mTextures ) {
Texture* Tex = texture.second;
if ( NULL != Tex && Tex->isGrabbed() ) { if ( NULL != Tex && Tex->isGrabbed() ) {
Tex->reload(); Tex->reload();
@@ -320,41 +339,57 @@ unsigned int TextureFactory::getValidTextureSize( const unsigned int& Size ) {
} }
bool TextureFactory::existsId( const Uint32& TexId ) { bool TextureFactory::existsId( const Uint32& TexId ) {
return ( TexId < mTextures.size() && TexId > 0 && NULL != mTextures[TexId] ); Lock l( *this );
return mTextures.find( TexId ) != mTextures.end();
} }
bool TextureFactory::exists( const Texture* tex ) { bool TextureFactory::exists( const Texture* tex ) {
return std::find( mTextures.begin(), mTextures.end(), tex ) != mTextures.end(); Lock l( *this );
return std::find_if( mTextures.begin(), mTextures.end(), [tex]( const auto& pair ) {
return pair.second == tex;
} ) != mTextures.end();
} }
Texture* TextureFactory::getTexture( const Uint32& TexId ) { Texture* TextureFactory::getTexture( const Uint32& TexId ) {
return mTextures[TexId]; Lock l( *this );
}
void TextureFactory::allocate( const unsigned int& size ) { auto it = mTextures.find( TexId );
if ( size > mTextures.size() ) { return it != mTextures.end() ? it->second : NULL;
mTextures.resize( size + 1, NULL );
for ( unsigned int i = 1; i < mTextures.size(); i++ )
mVectorFreeSlots.push_back( i );
}
} }
Texture* TextureFactory::getByName( const std::string& Name ) { Texture* TextureFactory::getByName( const std::string& Name ) {
return getByHash( String::hash( Name ) ); return getByHash( String::hash( Name ) );
} }
Uint32 TextureFactory::getTextureCount() {
Lock l( *this );
return (Uint32)mTextures.size();
}
unsigned int TextureFactory::getTextureMemorySize() {
Lock l( *this );
return mMemSize;
}
Texture* TextureFactory::getByHash( const String::HashType& hash ) { Texture* TextureFactory::getByHash( const String::HashType& hash ) {
Texture* tTex = NULL; Lock l( *this );
for ( Uint32 i = (Uint32)mTextures.size() - 1; i > 0; i-- ) { Uint32 latestId = 0;
tTex = mTextures[i]; Texture* latestTexture = NULL;
for ( const auto& texture : mTextures ) {
Texture* tTex = texture.second;
if ( NULL != tTex && tTex->getHashName() == hash ) if ( NULL != tTex && texture.first > latestId && tTex->getHashName() == hash ) {
return mTextures[i]; latestId = texture.first;
latestTexture = tTex;
}
} }
return NULL; return latestTexture;
} }
}} // namespace EE::Graphics }} // namespace EE::Graphics
+13 -1
View File
@@ -21,7 +21,19 @@ namespace EE { namespace UI {
namespace { namespace {
std::string getTextureCacheName( const Network::URI& uri ) { std::string getTextureCacheName( const Network::URI& uri ) {
std::string filePath( uri.getFSPath() ); std::string filePath( uri.toString() );
if ( String::startsWith( filePath, "file://" ) )
filePath = filePath.substr( 7 );
else
filePath = uri.getFSPath();
#if EE_PLATFORM == EE_PLATFORM_WIN
if ( filePath.size() >= 3 && filePath[0] == '/' && String::isLetter( filePath[1] ) &&
filePath[2] == ':' ) {
filePath = filePath.substr( 1 );
}
#endif
FileSystem::filePathRemoveProcessPath( filePath ); FileSystem::filePathRemoveProcessPath( filePath );
return filePath; return filePath;
} }
-1
View File
@@ -141,7 +141,6 @@ void EETest::init() {
mWindow->pushResizeCallback( [this]( auto event ) { onWindowResize( event ); } ); mWindow->pushResizeCallback( [this]( auto event ) { onWindowResize( event ); } );
TF = TextureFactory::instance(); TF = TextureFactory::instance();
TF->allocate( 40 );
Log = Log::instance(); Log = Log::instance();
KM = mWindow->getInput(); KM = mWindow->getInput();
+3 -2
View File
@@ -1,6 +1,7 @@
#include "compareimages.hpp" #include "compareimages.hpp"
#include "utest.hpp" #include "utest.hpp"
#include <eepp/graphics/drawablesearcher.hpp>
#include <eepp/graphics/fontfamily.hpp> #include <eepp/graphics/fontfamily.hpp>
#include <eepp/graphics/fontmanager.hpp> #include <eepp/graphics/fontmanager.hpp>
#include <eepp/graphics/fonttruetype.hpp> #include <eepp/graphics/fonttruetype.hpp>
@@ -4298,11 +4299,11 @@ UTEST( UIHTML, DeferredFileImageReusesCachedTexture ) {
const std::string processPath = Sys::getProcessPath(); const std::string processPath = Sys::getProcessPath();
UISceneNode* sceneNode = init_test_inline_block(); UISceneNode* sceneNode = init_test_inline_block();
sceneNode->setThreadPool( ThreadPool::createShared( 1 ) );
sceneNode->setURI( URI( "file://" + processPath ) ); sceneNode->setURI( URI( "file://" + processPath ) );
URI imageURI = sceneNode->solveRelativePath( URI( "../assets/icon/ee.png" ) ); URI imageURI = sceneNode->solveRelativePath( URI( "../assets/icon/ee.png" ) );
ASSERT_TRUE( FileSystem::fileExists( imageURI.getFSPath() ) ); ASSERT_TRUE( FileSystem::fileExists( imageURI.getFSPath() ) );
Texture* cached = TextureFactory::instance()->loadFromFile( Drawable* cached = DrawableSearcher::searchByName( imageURI.toString() );
imageURI.getFSPath(), false, Texture::ClampMode::ClampToEdge, false, false );
ASSERT_TRUE( cached != nullptr ); ASSERT_TRUE( cached != nullptr );
sceneNode->loadLayoutFromString( HTMLFormatter::HTMLtoXML( R"html( sceneNode->loadLayoutFromString( HTMLFormatter::HTMLtoXML( R"html(