You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/CrySystem/CrySizerStats.h

208 lines
7.1 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : 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.
#ifndef CRYINCLUDE_CRYSYSTEM_CRYSIZERSTATS_H
#define CRYINCLUDE_CRYSYSTEM_CRYSIZERSTATS_H
#pragma once
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 getSizeKBytes() const {return sizeBytes / float(1 << 10); }
float getTotalSizeKBytes () const {return sizeBytesTotal / float(1 << 10); }
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); }
unsigned row() const {return m_nStartRow; }
void updateKeys();
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;
//current row offset inc/dec by cursor keys
unsigned m_nStartRow;
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:
// constructor
CrySizerStatsRenderer (ISystem* pSystem, CrySizerStats* pStats, unsigned nMaxDepth = 2, int nMinSubcomponentBytes = -1);
void render(bool bRefreshMark = false);
// dumps it to log. uses MB as default
void dump (bool bUseKB = false);
protected: // -------------------------------------------------
typedef CrySizerStats::Component Component;
IRenderer* m_pRenderer; //
ILog* m_pLog; //
CrySizerStats* m_pStats; //
ITextModeConsole* m_pTextModeConsole;
// 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 // CRYINCLUDE_CRYSYSTEM_CRYSIZERSTATS_H