1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-12-03 00:15:46 +00:00

Drop textures when no longer needed

Textures used to be unloaded as soon as they were unreferenced.
The TextureMgr cache keeps an active reference to prevent load-unload-load
cycles so it only unloads things when explicitly asked.
This does require some more peak VRAM during map/tileset transitions
especially, since old textures are unloaded only after the next map
has been loaded, but the shortened load times should be worth it.
This commit is contained in:
fgenesis 2023-05-31 01:36:50 +02:00
parent 6dc9dc7e8f
commit 9cd9601485
3 changed files with 29 additions and 0 deletions

View file

@ -3219,6 +3219,9 @@ void Game::applyState()
// cutscenes immediately. --achurch // cutscenes immediately. --achurch
dsq->subtitlePlayer.show(0.25); dsq->subtitlePlayer.show(0.25);
// First cleanup -- we're now done loading everything; anything leftover from the prev. map can go
dsq->texmgr.clearUnused();
if (verbose) debugLog("loading map init script"); if (verbose) debugLog("loading map init script");
if (dsq->mod.isActive()) if (dsq->mod.isActive())
dsq->runScript(dsq->mod.getPath() + "scripts/map_" + sceneName + ".lua", "init", true); dsq->runScript(dsq->mod.getPath() + "scripts/map_" + sceneName + ".lua", "init", true);
@ -3264,6 +3267,10 @@ void Game::applyState()
dsq->toggleCursor(true, 0.5); dsq->toggleCursor(true, 0.5);
} }
// Second cleanup -- after the short map init fadeout, some entities may have
// decided to remove themselves, in which case their gfx are no longer needed
dsq->texmgr.clearUnused();
debugLog("Game::applyState Done"); debugLog("Game::applyState Done");
} }

View file

@ -29,6 +29,10 @@ public:
if (!--_refcount) if (!--_refcount)
delete this; delete this;
} }
inline unsigned refcount() const
{
return _refcount;
}
private: private:
unsigned _refcount; unsigned _refcount;

View file

@ -166,6 +166,24 @@ Texture* TextureMgr::getOrLoad(const std::string& name)
return load(name, KEEP); return load(name, KEEP);
} }
void TextureMgr::clearUnused()
{
size_t done = 0;
for(TexCache::iterator it = cache.begin(); it != cache.end(); )
{
if(it->second->refcount() <= 1)
{
it = cache.erase(it);
++done;
}
else
++it;
}
std::ostringstream os;
os << "TextureMgr: Dropped " << done << " unused textures, now " << cache.size() << " left";
debugLog(os.str());
}
void TextureMgr::shutdown() void TextureMgr::shutdown()
{ {
for(TexCache::iterator it = cache.begin(); it != cache.end(); ++it) for(TexCache::iterator it = cache.begin(); it != cache.end(); ++it)