Home | History | Annotate | Download | only in LinearMath
      1 
      2 /***************************************************************************************************
      3 **
      4 ** Real-Time Hierarchical Profiling for Game Programming Gems 3
      5 **
      6 ** by Greg Hjelstrom & Byon Garrabrant
      7 **
      8 ***************************************************************************************************/
      9 
     10 // Credits: The Clock class was inspired by the Timer classes in
     11 // Ogre (www.ogre3d.org).
     12 
     13 
     14 
     15 #ifndef BT_QUICK_PROF_H
     16 #define BT_QUICK_PROF_H
     17 
     18 //To disable built-in profiling, please comment out next line
     19 //#define BT_NO_PROFILE 1
     20 #ifndef BT_NO_PROFILE
     21 #include <stdio.h>//@todo remove this, backwards compatibility
     22 #include "btScalar.h"
     23 #include "btAlignedAllocator.h"
     24 #include <new>
     25 
     26 
     27 
     28 
     29 
     30 #define USE_BT_CLOCK 1
     31 
     32 #ifdef USE_BT_CLOCK
     33 
     34 ///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling.
     35 class btClock
     36 {
     37 public:
     38 	btClock();
     39 
     40 	btClock(const btClock& other);
     41 	btClock& operator=(const btClock& other);
     42 
     43 	~btClock();
     44 
     45 	/// Resets the initial reference time.
     46 	void reset();
     47 
     48 	/// Returns the time in ms since the last call to reset or since
     49 	/// the btClock was created.
     50 	unsigned long int getTimeMilliseconds();
     51 
     52 	/// Returns the time in us since the last call to reset or since
     53 	/// the Clock was created.
     54 	unsigned long int getTimeMicroseconds();
     55 
     56 	/// Returns the time in s since the last call to reset or since
     57 	/// the Clock was created.
     58 	btScalar getTimeSeconds();
     59 
     60 private:
     61 	struct btClockData* m_data;
     62 };
     63 
     64 #endif //USE_BT_CLOCK
     65 
     66 
     67 
     68 
     69 ///A node in the Profile Hierarchy Tree
     70 class	CProfileNode {
     71 
     72 public:
     73 	CProfileNode( const char * name, CProfileNode * parent );
     74 	~CProfileNode( void );
     75 
     76 	CProfileNode * Get_Sub_Node( const char * name );
     77 
     78 	CProfileNode * Get_Parent( void )		{ return Parent; }
     79 	CProfileNode * Get_Sibling( void )		{ return Sibling; }
     80 	CProfileNode * Get_Child( void )			{ return Child; }
     81 
     82 	void				CleanupMemory();
     83 	void				Reset( void );
     84 	void				Call( void );
     85 	bool				Return( void );
     86 
     87 	const char *	Get_Name( void )				{ return Name; }
     88 	int				Get_Total_Calls( void )		{ return TotalCalls; }
     89 	float				Get_Total_Time( void )		{ return TotalTime; }
     90 	void*			GetUserPointer() const {return m_userPtr;}
     91 	void			SetUserPointer(void* ptr) { m_userPtr = ptr;}
     92 protected:
     93 
     94 	const char *	Name;
     95 	int				TotalCalls;
     96 	float				TotalTime;
     97 	unsigned long int			StartTime;
     98 	int				RecursionCounter;
     99 
    100 	CProfileNode *	Parent;
    101 	CProfileNode *	Child;
    102 	CProfileNode *	Sibling;
    103 	void*	m_userPtr;
    104 };
    105 
    106 ///An iterator to navigate through the tree
    107 class CProfileIterator
    108 {
    109 public:
    110 	// Access all the children of the current parent
    111 	void				First(void);
    112 	void				Next(void);
    113 	bool				Is_Done(void);
    114 	bool                Is_Root(void) { return (CurrentParent->Get_Parent() == 0); }
    115 
    116 	void				Enter_Child( int index );		// Make the given child the new parent
    117 	void				Enter_Largest_Child( void );	// Make the largest child the new parent
    118 	void				Enter_Parent( void );			// Make the current parent's parent the new parent
    119 
    120 	// Access the current child
    121 	const char *	Get_Current_Name( void )			{ return CurrentChild->Get_Name(); }
    122 	int				Get_Current_Total_Calls( void )	{ return CurrentChild->Get_Total_Calls(); }
    123 	float				Get_Current_Total_Time( void )	{ return CurrentChild->Get_Total_Time(); }
    124 
    125 	void*	Get_Current_UserPointer( void )			{ return CurrentChild->GetUserPointer(); }
    126 	void	Set_Current_UserPointer(void* ptr) {CurrentChild->SetUserPointer(ptr);}
    127 	// Access the current parent
    128 	const char *	Get_Current_Parent_Name( void )			{ return CurrentParent->Get_Name(); }
    129 	int				Get_Current_Parent_Total_Calls( void )	{ return CurrentParent->Get_Total_Calls(); }
    130 	float				Get_Current_Parent_Total_Time( void )	{ return CurrentParent->Get_Total_Time(); }
    131 
    132 
    133 
    134 protected:
    135 
    136 	CProfileNode *	CurrentParent;
    137 	CProfileNode *	CurrentChild;
    138 
    139 
    140 	CProfileIterator( CProfileNode * start );
    141 	friend	class		CProfileManager;
    142 };
    143 
    144 
    145 ///The Manager for the Profile system
    146 class	CProfileManager {
    147 public:
    148 	static	void						Start_Profile( const char * name );
    149 	static	void						Stop_Profile( void );
    150 
    151 	static	void						CleanupMemory(void)
    152 	{
    153 		Root.CleanupMemory();
    154 	}
    155 
    156 	static	void						Reset( void );
    157 	static	void						Increment_Frame_Counter( void );
    158 	static	int						Get_Frame_Count_Since_Reset( void )		{ return FrameCounter; }
    159 	static	float						Get_Time_Since_Reset( void );
    160 
    161 	static	CProfileIterator *	Get_Iterator( void )
    162 	{
    163 
    164 		return new CProfileIterator( &Root );
    165 	}
    166 	static	void						Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); }
    167 
    168 	static void	dumpRecursive(CProfileIterator* profileIterator, int spacing);
    169 
    170 	static void	dumpAll();
    171 
    172 private:
    173 	static	CProfileNode			Root;
    174 	static	CProfileNode *			CurrentNode;
    175 	static	int						FrameCounter;
    176 	static	unsigned long int					ResetTime;
    177 };
    178 
    179 
    180 ///ProfileSampleClass is a simple way to profile a function's scope
    181 ///Use the BT_PROFILE macro at the start of scope to time
    182 class	CProfileSample {
    183 public:
    184 	CProfileSample( const char * name )
    185 	{
    186 		CProfileManager::Start_Profile( name );
    187 	}
    188 
    189 	~CProfileSample( void )
    190 	{
    191 		CProfileManager::Stop_Profile();
    192 	}
    193 };
    194 
    195 
    196 #define	BT_PROFILE( name )			CProfileSample __profile( name )
    197 
    198 #else
    199 
    200 #define	BT_PROFILE( name )
    201 
    202 #endif //#ifndef BT_NO_PROFILE
    203 
    204 
    205 
    206 #endif //BT_QUICK_PROF_H
    207 
    208 
    209