• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Get_Parent(void)78 	CProfileNode * Get_Parent( void )		{ return Parent; }
Get_Sibling(void)79 	CProfileNode * Get_Sibling( void )		{ return Sibling; }
Get_Child(void)80 	CProfileNode * Get_Child( void )			{ return Child; }
81 
82 	void				CleanupMemory();
83 	void				Reset( void );
84 	void				Call( void );
85 	bool				Return( void );
86 
Get_Name(void)87 	const char *	Get_Name( void )				{ return Name; }
Get_Total_Calls(void)88 	int				Get_Total_Calls( void )		{ return TotalCalls; }
Get_Total_Time(void)89 	float				Get_Total_Time( void )		{ return TotalTime; }
GetUserPointer()90 	void*			GetUserPointer() const {return m_userPtr;}
SetUserPointer(void * ptr)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);
Is_Root(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
Get_Current_Name(void)121 	const char *	Get_Current_Name( void )			{ return CurrentChild->Get_Name(); }
Get_Current_Total_Calls(void)122 	int				Get_Current_Total_Calls( void )	{ return CurrentChild->Get_Total_Calls(); }
Get_Current_Total_Time(void)123 	float				Get_Current_Total_Time( void )	{ return CurrentChild->Get_Total_Time(); }
124 
Get_Current_UserPointer(void)125 	void*	Get_Current_UserPointer( void )			{ return CurrentChild->GetUserPointer(); }
Set_Current_UserPointer(void * ptr)126 	void	Set_Current_UserPointer(void* ptr) {CurrentChild->SetUserPointer(ptr);}
127 	// Access the current parent
Get_Current_Parent_Name(void)128 	const char *	Get_Current_Parent_Name( void )			{ return CurrentParent->Get_Name(); }
Get_Current_Parent_Total_Calls(void)129 	int				Get_Current_Parent_Total_Calls( void )	{ return CurrentParent->Get_Total_Calls(); }
Get_Current_Parent_Total_Time(void)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 
CleanupMemory(void)151 	static	void						CleanupMemory(void)
152 	{
153 		Root.CleanupMemory();
154 	}
155 
156 	static	void						Reset( void );
157 	static	void						Increment_Frame_Counter( void );
Get_Frame_Count_Since_Reset(void)158 	static	int						Get_Frame_Count_Since_Reset( void )		{ return FrameCounter; }
159 	static	float						Get_Time_Since_Reset( void );
160 
Get_Iterator(void)161 	static	CProfileIterator *	Get_Iterator( void )
162 	{
163 
164 		return new CProfileIterator( &Root );
165 	}
Release_Iterator(CProfileIterator * iterator)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:
CProfileSample(const char * name)184 	CProfileSample( const char * name )
185 	{
186 		CProfileManager::Start_Profile( name );
187 	}
188 
~CProfileSample(void)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