Changeset View
Changeset View
Standalone View
Standalone View
extern/bullet2/src/LinearMath/btQuickprof.h
| /*************************************************************************************************** | /*************************************************************************************************** | ||||
| ** | ** | ||||
| ** Real-Time Hierarchical Profiling for Game Programming Gems 3 | ** Real-Time Hierarchical Profiling for Game Programming Gems 3 | ||||
| ** | ** | ||||
| ** by Greg Hjelstrom & Byon Garrabrant | ** by Greg Hjelstrom & Byon Garrabrant | ||||
| ** | ** | ||||
| ***************************************************************************************************/ | ***************************************************************************************************/ | ||||
| // Credits: The Clock class was inspired by the Timer classes in | // Credits: The Clock class was inspired by the Timer classes in | ||||
| // Ogre (www.ogre3d.org). | // Ogre (www.ogre3d.org). | ||||
| #ifndef BT_QUICK_PROF_H | #ifndef BT_QUICK_PROF_H | ||||
| #define BT_QUICK_PROF_H | #define BT_QUICK_PROF_H | ||||
| //To disable built-in profiling, please comment out next line | |||||
| //#define BT_NO_PROFILE 1 | |||||
| #ifndef BT_NO_PROFILE | |||||
| #include <stdio.h>//@todo remove this, backwards compatibility | |||||
| #include "btScalar.h" | #include "btScalar.h" | ||||
| #include "btAlignedAllocator.h" | |||||
| #include <new> | |||||
| #define USE_BT_CLOCK 1 | #define USE_BT_CLOCK 1 | ||||
| #ifdef USE_BT_CLOCK | #ifdef USE_BT_CLOCK | ||||
| ///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling. | ///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling. | ||||
| class btClock | class btClock | ||||
| { | { | ||||
| public: | public: | ||||
| btClock(); | btClock(); | ||||
| btClock(const btClock& other); | btClock(const btClock& other); | ||||
| btClock& operator=(const btClock& other); | btClock& operator=(const btClock& other); | ||||
| ~btClock(); | ~btClock(); | ||||
| /// Resets the initial reference time. | /// Resets the initial reference time. | ||||
| void reset(); | void reset(); | ||||
| /// Returns the time in ms since the last call to reset or since | /// Returns the time in ms since the last call to reset or since | ||||
| /// the btClock was created. | /// the btClock was created. | ||||
| unsigned long int getTimeMilliseconds(); | unsigned long long int getTimeMilliseconds(); | ||||
| /// Returns the time in us since the last call to reset or since | /// Returns the time in us since the last call to reset or since | ||||
| /// the Clock was created. | /// the Clock was created. | ||||
| unsigned long int getTimeMicroseconds(); | unsigned long long int getTimeMicroseconds(); | ||||
| unsigned long long int getTimeNanoseconds(); | |||||
| /// Returns the time in s since the last call to reset or since | /// Returns the time in s since the last call to reset or since | ||||
| /// the Clock was created. | /// the Clock was created. | ||||
| btScalar getTimeSeconds(); | btScalar getTimeSeconds(); | ||||
| private: | private: | ||||
| struct btClockData* m_data; | struct btClockData* m_data; | ||||
| }; | }; | ||||
| #endif //USE_BT_CLOCK | #endif //USE_BT_CLOCK | ||||
| typedef void(btEnterProfileZoneFunc)(const char* msg); | |||||
| typedef void(btLeaveProfileZoneFunc)(); | |||||
| btEnterProfileZoneFunc* btGetCurrentEnterProfileZoneFunc(); | |||||
| btLeaveProfileZoneFunc* btGetCurrentLeaveProfileZoneFunc(); | |||||
| void btSetCustomEnterProfileZoneFunc(btEnterProfileZoneFunc* enterFunc); | |||||
| void btSetCustomLeaveProfileZoneFunc(btLeaveProfileZoneFunc* leaveFunc); | |||||
| ///A node in the Profile Hierarchy Tree | #ifndef BT_ENABLE_PROFILE | ||||
| class CProfileNode { | #define BT_NO_PROFILE 1 | ||||
| #endif //BT_NO_PROFILE | |||||
| const unsigned int BT_QUICKPROF_MAX_THREAD_COUNT = 64; | |||||
| //btQuickprofGetCurrentThreadIndex will return -1 if thread index cannot be determined, | |||||
| //otherwise returns thread index in range [0..maxThreads] | |||||
| unsigned int btQuickprofGetCurrentThreadIndex2(); | |||||
| #ifndef BT_NO_PROFILE | |||||
| #include <stdio.h> //@todo remove this, backwards compatibility | |||||
| #include "btAlignedAllocator.h" | |||||
| #include <new> | |||||
| ///A node in the Profile Hierarchy Tree | |||||
| class CProfileNode | |||||
| { | |||||
| public: | public: | ||||
| CProfileNode( const char * name, CProfileNode * parent ); | CProfileNode(const char* name, CProfileNode* parent); | ||||
| ~CProfileNode( void ); | ~CProfileNode(void); | ||||
| CProfileNode * Get_Sub_Node( const char * name ); | CProfileNode* Get_Sub_Node(const char* name); | ||||
| CProfileNode * Get_Parent( void ) { return Parent; } | CProfileNode* Get_Parent(void) { return Parent; } | ||||
| CProfileNode * Get_Sibling( void ) { return Sibling; } | CProfileNode* Get_Sibling(void) { return Sibling; } | ||||
| CProfileNode * Get_Child( void ) { return Child; } | CProfileNode* Get_Child(void) { return Child; } | ||||
| void CleanupMemory(); | void CleanupMemory(); | ||||
| void Reset( void ); | void Reset(void); | ||||
| void Call( void ); | void Call(void); | ||||
| bool Return( void ); | bool Return(void); | ||||
| const char * Get_Name( void ) { return Name; } | const char* Get_Name(void) { return Name; } | ||||
| int Get_Total_Calls( void ) { return TotalCalls; } | int Get_Total_Calls(void) { return TotalCalls; } | ||||
| float Get_Total_Time( void ) { return TotalTime; } | float Get_Total_Time(void) { return TotalTime; } | ||||
| void* GetUserPointer() const {return m_userPtr;} | void* GetUserPointer() const { return m_userPtr; } | ||||
| void SetUserPointer(void* ptr) { m_userPtr = ptr;} | void SetUserPointer(void* ptr) { m_userPtr = ptr; } | ||||
| protected: | |||||
| protected: | |||||
| const char * Name; | const char* Name; | ||||
| int TotalCalls; | int TotalCalls; | ||||
| float TotalTime; | float TotalTime; | ||||
| unsigned long int StartTime; | unsigned long int StartTime; | ||||
| int RecursionCounter; | int RecursionCounter; | ||||
| CProfileNode * Parent; | CProfileNode* Parent; | ||||
| CProfileNode * Child; | CProfileNode* Child; | ||||
| CProfileNode * Sibling; | CProfileNode* Sibling; | ||||
| void* m_userPtr; | void* m_userPtr; | ||||
| }; | }; | ||||
| ///An iterator to navigate through the tree | ///An iterator to navigate through the tree | ||||
| class CProfileIterator | class CProfileIterator | ||||
| { | { | ||||
| public: | public: | ||||
| // Access all the children of the current parent | // Access all the children of the current parent | ||||
| void First(void); | void First(void); | ||||
| void Next(void); | void Next(void); | ||||
| bool Is_Done(void); | bool Is_Done(void); | ||||
| bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); } | bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); } | ||||
| void Enter_Child( int index ); // Make the given child the new parent | void Enter_Child(int index); // Make the given child the new parent | ||||
| void Enter_Largest_Child( void ); // Make the largest child the new parent | void Enter_Largest_Child(void); // Make the largest child the new parent | ||||
| void Enter_Parent( void ); // Make the current parent's parent the new parent | void Enter_Parent(void); // Make the current parent's parent the new parent | ||||
| // Access the current child | // Access the current child | ||||
| const char * Get_Current_Name( void ) { return CurrentChild->Get_Name(); } | const char* Get_Current_Name(void) { return CurrentChild->Get_Name(); } | ||||
| int Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); } | int Get_Current_Total_Calls(void) { return CurrentChild->Get_Total_Calls(); } | ||||
| float Get_Current_Total_Time( void ) { return CurrentChild->Get_Total_Time(); } | float Get_Current_Total_Time(void) { return CurrentChild->Get_Total_Time(); } | ||||
| void* Get_Current_UserPointer( void ) { return CurrentChild->GetUserPointer(); } | void* Get_Current_UserPointer(void) { return CurrentChild->GetUserPointer(); } | ||||
| void Set_Current_UserPointer(void* ptr) {CurrentChild->SetUserPointer(ptr);} | void Set_Current_UserPointer(void* ptr) { CurrentChild->SetUserPointer(ptr); } | ||||
| // Access the current parent | // Access the current parent | ||||
| const char * Get_Current_Parent_Name( void ) { return CurrentParent->Get_Name(); } | const char* Get_Current_Parent_Name(void) { return CurrentParent->Get_Name(); } | ||||
| int Get_Current_Parent_Total_Calls( void ) { return CurrentParent->Get_Total_Calls(); } | int Get_Current_Parent_Total_Calls(void) { return CurrentParent->Get_Total_Calls(); } | ||||
| float Get_Current_Parent_Total_Time( void ) { return CurrentParent->Get_Total_Time(); } | float Get_Current_Parent_Total_Time(void) { return CurrentParent->Get_Total_Time(); } | ||||
| protected: | protected: | ||||
| CProfileNode * CurrentParent; | CProfileNode* CurrentParent; | ||||
| CProfileNode * CurrentChild; | CProfileNode* CurrentChild; | ||||
| CProfileIterator( CProfileNode * start ); | CProfileIterator(CProfileNode* start); | ||||
| friend class CProfileManager; | friend class CProfileManager; | ||||
| }; | }; | ||||
| ///The Manager for the Profile system | ///The Manager for the Profile system | ||||
| class CProfileManager { | class CProfileManager | ||||
| { | |||||
| public: | public: | ||||
| static void Start_Profile( const char * name ); | static void Start_Profile(const char* name); | ||||
| static void Stop_Profile( void ); | static void Stop_Profile(void); | ||||
| static void CleanupMemory(void) | static void CleanupMemory(void); | ||||
| { | // { | ||||
| Root.CleanupMemory(); | // Root.CleanupMemory(); | ||||
| } | // } | ||||
| static void Reset( void ); | static void Reset(void); | ||||
| static void Increment_Frame_Counter( void ); | static void Increment_Frame_Counter(void); | ||||
| static int Get_Frame_Count_Since_Reset( void ) { return FrameCounter; } | static int Get_Frame_Count_Since_Reset(void) { return FrameCounter; } | ||||
| static float Get_Time_Since_Reset( void ); | static float Get_Time_Since_Reset(void); | ||||
| static CProfileIterator * Get_Iterator( void ) | static CProfileIterator* Get_Iterator(void); | ||||
| { | // { | ||||
| // | |||||
| return new CProfileIterator( &Root ); | // return new CProfileIterator( &Root ); | ||||
| } | // } | ||||
| static void Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); } | static void Release_Iterator(CProfileIterator* iterator) { delete (iterator); } | ||||
| static void dumpRecursive(CProfileIterator* profileIterator, int spacing); | static void dumpRecursive(CProfileIterator* profileIterator, int spacing); | ||||
| static void dumpAll(); | static void dumpAll(); | ||||
| private: | private: | ||||
| static CProfileNode Root; | |||||
| static CProfileNode * CurrentNode; | |||||
| static int FrameCounter; | static int FrameCounter; | ||||
| static unsigned long int ResetTime; | static unsigned long int ResetTime; | ||||
| }; | }; | ||||
| #endif //#ifndef BT_NO_PROFILE | |||||
| ///ProfileSampleClass is a simple way to profile a function's scope | ///ProfileSampleClass is a simple way to profile a function's scope | ||||
| ///Use the BT_PROFILE macro at the start of scope to time | ///Use the BT_PROFILE macro at the start of scope to time | ||||
| class CProfileSample { | class CProfileSample | ||||
| public: | |||||
| CProfileSample( const char * name ) | |||||
| { | { | ||||
| CProfileManager::Start_Profile( name ); | public: | ||||
| } | CProfileSample(const char* name); | ||||
| ~CProfileSample( void ) | ~CProfileSample(void); | ||||
| { | |||||
| CProfileManager::Stop_Profile(); | |||||
| } | |||||
| }; | }; | ||||
| #define BT_PROFILE( name ) CProfileSample __profile( name ) | #define BT_PROFILE(name) CProfileSample __profile(name) | ||||
| #else | |||||
| #define BT_PROFILE( name ) | |||||
| #endif //#ifndef BT_NO_PROFILE | |||||
| #endif //BT_QUICK_PROF_H | #endif //BT_QUICK_PROF_H | ||||