123
This commit is contained in:
183
CrySystem/CrySizerStats.h
Normal file
183
CrySystem/CrySizerStats.h
Normal file
@@ -0,0 +1,183 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CryEngine Source code
|
||||
//
|
||||
// File:CrySizerStats.h
|
||||
// Declaration of the CrySizerStats class, which is used to
|
||||
// calculate the memory usage by the subsystems and components, to help
|
||||
// the artists keep the memory budged low.
|
||||
//
|
||||
//
|
||||
// History:
|
||||
// December 03, 2002 : Created by Sergiy Migdalskiy <sergiy@crytek.de>
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _CRY_SYSTEM_CRY_SIZER_STATS_HDR_
|
||||
#define _CRY_SYSTEM_CRY_SIZER_STATS_HDR_
|
||||
|
||||
class CrySizerImpl;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// This class holds only the necessary statistics data, which can be carried
|
||||
// over a few frames without significant impact on memory usage
|
||||
// CrySizerImpl is an implementation of ICrySizer, which is used to collect
|
||||
// those data; it must be destructed immediately after constructing the Stats
|
||||
// object to avoid excessive memory usage.
|
||||
class CrySizerStats
|
||||
{
|
||||
public:
|
||||
// constructs the statistics based on the given cry sizer
|
||||
CrySizerStats (CrySizerImpl* pCrySizer);
|
||||
|
||||
CrySizerStats ();
|
||||
|
||||
// this structure describes one component of the memory size statistics
|
||||
struct Component
|
||||
{
|
||||
Component() {clear();}
|
||||
Component (const string& name, unsigned size = 0, unsigned num = 0):
|
||||
strName(name), sizeBytes(size), numObjects(num), nDepth(0) {}
|
||||
void clear()
|
||||
{
|
||||
strName = "";
|
||||
sizeBytes = 0;
|
||||
numObjects = 0;
|
||||
nDepth = 0;
|
||||
}
|
||||
|
||||
// the name of the component, as it appeared in the push() call
|
||||
string strName;
|
||||
// the total size, in bytes, of objects in the component
|
||||
size_t sizeBytes;
|
||||
// the total size including the subcomponents
|
||||
size_t sizeBytesTotal;
|
||||
// the number of objects allocated
|
||||
size_t numObjects;
|
||||
unsigned nDepth;
|
||||
|
||||
float getSizeMBytes() const {return sizeBytes / float(1<<20);}
|
||||
|
||||
float getTotalSizeMBytes () const {return sizeBytesTotal / float(1<<20);}
|
||||
|
||||
struct NameOrder
|
||||
{
|
||||
bool operator () (const Component& left, const Component& right)const {return left.strName < right.strName;}
|
||||
};
|
||||
|
||||
struct SizeOrder
|
||||
{
|
||||
bool operator () (const Component& left, const Component& right)const {return left.sizeBytes < right.sizeBytes;}
|
||||
};
|
||||
|
||||
struct GenericOrder
|
||||
{
|
||||
bool operator () (const Component& left, const Component& right)const;
|
||||
};
|
||||
};
|
||||
|
||||
// returns the number of different subsystems/components used
|
||||
unsigned numComponents()const {return (unsigned)m_arrComponents.size();}
|
||||
// returns the name of the i-th component
|
||||
const Component& getComponent(unsigned nComponent)const {return m_arrComponents[nComponent];}
|
||||
|
||||
unsigned size() const {return numComponents();}
|
||||
const Component& operator [] (unsigned i) const {return getComponent(i);}
|
||||
const Component& operator [] ( signed i) const {return getComponent(i);}
|
||||
|
||||
size_t getMaxNameLength()const {return m_nMaxNameLength;}
|
||||
enum {g_numTimers = 3};
|
||||
|
||||
void startTimer(unsigned nTimer, ITimer*pTimer);
|
||||
void stopTimer(unsigned nTimer, ITimer*pTimer);
|
||||
float getTime(unsigned nTimer)const {assert (nTimer < g_numTimers);return m_fTime[nTimer];}
|
||||
int getAgeFrames() const {return m_nAgeFrames;}
|
||||
void incAgeFrames() {++m_nAgeFrames;}
|
||||
protected:
|
||||
// refreshes the statistics built after the component array is built
|
||||
void refresh();
|
||||
protected:
|
||||
// the names of the components
|
||||
typedef std::vector<Component> ComponentArray;
|
||||
ComponentArray m_arrComponents;
|
||||
|
||||
// the maximum length of the component name, in characters
|
||||
size_t m_nMaxNameLength;
|
||||
|
||||
// the timer that counts the time spent on statistics gathering
|
||||
float m_fTime[g_numTimers];
|
||||
|
||||
// the age of the statistics, in frames
|
||||
int m_nAgeFrames;
|
||||
|
||||
friend class CrySizerStatsBuilder;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// this is the constructor for the CrySizerStats
|
||||
class CrySizerStatsBuilder
|
||||
{
|
||||
public:
|
||||
CrySizerStatsBuilder (CrySizerImpl* pSizer, int nMinSubcomponentBytes = 0);
|
||||
|
||||
void build (CrySizerStats* pStats);
|
||||
|
||||
protected:
|
||||
typedef CrySizerStats::Component Component;
|
||||
// if there is already such name in the map, then just returns the index
|
||||
// of the compoentn in the component array; otherwise adds an entry to themap
|
||||
// and to the component array nad returns its index
|
||||
Component& mapName (unsigned nName);
|
||||
|
||||
// creates the map of names from old to new, and initializes the components themselves
|
||||
void processNames();
|
||||
|
||||
// given the name in the old system, adds the subtree of names to the
|
||||
// name map and components. In case all the subtree is empty, returns 0 and
|
||||
// adds nothing. Otherwise, returns the total size of objects belonging to the
|
||||
// subtree
|
||||
size_t addNameSubtree (unsigned nDepth, size_t nName);
|
||||
|
||||
protected:
|
||||
CrySizerStats* m_pStats;
|
||||
CrySizerImpl* m_pSizer;
|
||||
|
||||
// this is the mapping from the old names into the new componentn indices
|
||||
typedef std::vector<size_t> IdToIdMap;
|
||||
// from old to new
|
||||
IdToIdMap m_mapNames;
|
||||
|
||||
// this is the threshold: if the total number of bytes in the subcomponent
|
||||
// is less than this, the subcomponent isn't shown
|
||||
unsigned m_nMinSubcomponentBytes;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Renders the given usage stats; gets created upon every rendering
|
||||
class CrySizerStatsRenderer
|
||||
{
|
||||
public:
|
||||
CrySizerStatsRenderer (ISystem* pSystem, CrySizerStats* pStats, unsigned nMaxDepth = 2, int nMinSubcomponentBytes = -1);
|
||||
void render(bool bRefreshMark = false);
|
||||
// dumps it to log
|
||||
void dump ();
|
||||
protected:
|
||||
typedef CrySizerStats::Component Component;
|
||||
|
||||
IRenderer* m_pRenderer;
|
||||
ILog* m_pLog;
|
||||
CrySizerStats* m_pStats;
|
||||
class CXFont* m_pFont;
|
||||
|
||||
// this is the threshold: if the total number of bytes in the subcomponent
|
||||
// is less than this, the subcomponent isn't shown
|
||||
unsigned m_nMinSubcomponentBytes;
|
||||
|
||||
// the max depth of the branch to output
|
||||
unsigned m_nMaxSubcomponentDepth;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user