Add console command to dump sprite cache stats

pull/590/head
Jonathan G Rennison 10 months ago
parent 7e5a87dd46
commit 627fd3d4fa

@ -3126,6 +3126,20 @@ DEF_CONSOLE_CMD(ConDumpSignalStyles)
return true;
}
DEF_CONSOLE_CMD(ConSpriteCacheStats)
{
if (argc == 0) {
IConsoleHelp("Dump sprite cache stats.");
return true;
}
extern void DumpSpriteCacheStats(char *buffer, const char *last);
char buffer[8192];
DumpSpriteCacheStats(buffer, lastof(buffer));
PrintLineByLine(buffer);
return true;
}
DEF_CONSOLE_CMD(ConCheckCaches)
{
if (argc == 0) {
@ -3956,6 +3970,7 @@ void IConsoleStdLibRegister()
IConsole::CmdRegister("dump_tile", ConDumpTile, nullptr, true);
IConsole::CmdRegister("dump_grf_cargo_tables", ConDumpGrfCargoTables, nullptr, true);
IConsole::CmdRegister("dump_signal_styles", ConDumpSignalStyles, nullptr, true);
IConsole::CmdRegister("dump_sprite_cache_stats", ConSpriteCacheStats, nullptr, true);
IConsole::CmdRegister("check_caches", ConCheckCaches, nullptr, true);
IConsole::CmdRegister("show_town_window", ConShowTownWindow, nullptr, true);
IConsole::CmdRegister("show_station_window", ConShowStationWindow, nullptr, true);

@ -37,6 +37,9 @@ uint _sprite_cache_size = 4;
static size_t _spritecache_bytes_used = 0;
static uint32 _sprite_lru_counter;
static uint32 _spritecache_prune_events = 0;
static size_t _spritecache_prune_entries = 0;
static size_t _spritecache_prune_total = 0;
struct SpriteCache;
@ -81,12 +84,14 @@ public:
uint16 flags; ///< Control flags, see SpriteCacheCtrlFlags
void *GetPtr() { return this->ptr.get(); }
uint32 GetTotalSize() { return this->totalsize; }
const void *GetPtr() const { return this->ptr.get(); }
uint32 GetTotalSize() const { return this->totalsize; }
SpriteType GetType() const { return this->type; }
void SetType(SpriteType type) { this->type = type; }
bool GetWarned() const { return HasBit(this->flags, SCCF_WARNED); }
void SetWarned(bool warned) { SB(this->flags, SCCF_WARNED, 1, warned ? 1 : 0); }
bool GetHasPalette() const { return GB(this->flags, SCC_PAL_ZOOM_START, 6) != 0; }
bool GetHasNonPalette() const { return GB(this->flags, SCC_32BPP_ZOOM_START, 6) != 0; }
private:
@ -942,12 +947,21 @@ static void DeleteEntriesFromSpriteCache(size_t target)
DEBUG(sprite, 3, "DeleteEntriesFromSpriteCache, deleted: " PRINTF_SIZE " of " PRINTF_SIZE ", freed: " PRINTF_SIZE ", in use: " PRINTF_SIZE " --> " PRINTF_SIZE ", delta: " PRINTF_SIZE ", requested: " PRINTF_SIZE,
candidates.size(), total_candidates, candidate_bytes, initial_in_use, GetSpriteCacheUsage(), initial_in_use - GetSpriteCacheUsage(), target);
_spritecache_prune_events++;
_spritecache_prune_entries += candidates.size();
_spritecache_prune_total += (initial_in_use - GetSpriteCacheUsage());
}
void IncreaseSpriteLRU()
uint GetTargetSpriteSize()
{
int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
uint target_size = (bpp > 0 ? _sprite_cache_size * bpp / 8 : 1) * 1024 * 1024;
return (bpp > 0 ? _sprite_cache_size * bpp / 8 : 1) * 1024 * 1024;
}
void IncreaseSpriteLRU()
{
uint target_size = GetTargetSpriteSize();
if (_spritecache_bytes_used > target_size) {
DeleteEntriesFromSpriteCache(_spritecache_bytes_used - target_size + 512 * 1024);
}
@ -1184,6 +1198,9 @@ void GfxInitSpriteMem()
_spritecache.clear();
_sprite_files.clear();
assert(_spritecache_bytes_used == 0);
_spritecache_prune_events = 0;
_spritecache_prune_entries = 0;
_spritecache_prune_total = 0;
}
/**
@ -1214,4 +1231,49 @@ void GfxClearFontSpriteCache()
}
}
void DumpSpriteCacheStats(char *buffer, const char *last)
{
uint target_size = GetTargetSpriteSize();
buffer += seprintf(buffer, last, "Sprite cache: entries: %u, size: %u, target: %u, percent used: %.1f%%\n",
(uint)_spritecache.size(), (uint)_spritecache_bytes_used, target_size, (100.0f * _spritecache_bytes_used) / target_size);
uint types[(uint)SpriteType::Invalid] = {};
uint have_data = 0;
uint have_warned = 0;
uint have_8bpp = 0;
uint have_32bpp = 0;
uint depths[16] = {};
uint have_partial_zoom = 0;
for (const SpriteCache &entry : _spritecache) {
if ((uint)entry.GetType() >= (uint)SpriteType::Invalid) continue;
types[(uint)entry.GetType()]++;
if (entry.GetPtr() != nullptr) have_data++;
if (entry.GetHasPalette()) have_8bpp++;
if (entry.GetHasNonPalette()) have_32bpp++;
if (entry.GetType() == SpriteType::Normal) {
if (entry.total_missing_zoom_levels != 0) have_partial_zoom++;
uint depth = 0;
const Sprite *p = (const Sprite *)entry.GetPtr();
while (p != nullptr) {
depth++;
p = p->next;
}
if (depth < lengthof(depths)) depths[depth]++;
}
}
buffer += seprintf(buffer, last, " Normal: %u, MapGen: %u, Font: %u, Recolour: %u\n",
types[(uint)SpriteType::Normal], types[(uint)SpriteType::MapGen], types[(uint)SpriteType::Font], types[(uint)SpriteType::Recolour]);
buffer += seprintf(buffer, last, " Data loaded: %u, Warned: %u, 8bpp: %u, 32bpp: %u\n",
have_data, have_warned, have_8bpp, have_32bpp);
buffer += seprintf(buffer, last, " Cache prune events: %u, pruned entry total: " PRINTF_SIZE ", pruned data total: " PRINTF_SIZE "\n",
_spritecache_prune_events, _spritecache_prune_entries, _spritecache_prune_total);
buffer += seprintf(buffer, last, " Normal:\n");
buffer += seprintf(buffer, last, " Partial zoom: %u\n", have_partial_zoom);
for (uint i = 0; i < lengthof(depths); i++) {
if (depths[i] > 0) buffer += seprintf(buffer, last, " Data depth %u: %u\n", i, depths[i]);
}
}
/* static */ ReusableBuffer<SpriteLoader::CommonPixel> SpriteLoader::Sprite::buffer[ZOOM_LVL_SPR_COUNT];

Loading…
Cancel
Save