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