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