Logo Search packages:      
Sourcecode: blender version File versions

btQuickprof.cpp

/*

/***************************************************************************************************
**
** profile.cpp
**
** Real-Time Hierarchical Profiling for Game Programming Gems 3
**
** by Greg Hjelstrom & Byon Garrabrant
**
***************************************************************************************************/

// Credits: The Clock class was inspired by the Timer classes in 
// Ogre (www.ogre3d.org).

#include "LinearMath/btQuickprof.h"


#ifdef USE_BT_CLOCK

static btClock gProfileClock;

inline void Profile_Get_Ticks(unsigned long int * ticks)
{
      *ticks = gProfileClock.getTimeMicroseconds();
}

inline float Profile_Get_Tick_Rate(void)
{
//    return 1000000.f;
      return 1000.f;

}



/***************************************************************************************************
**
** CProfileNode
**
***************************************************************************************************/

/***********************************************************************************************
 * INPUT:                                                                                      *
 * name - pointer to a static string which is the name of this profile node                    *
 * parent - parent pointer                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 * The name is assumed to be a static pointer, only the pointer is stored and compared for     *
 * efficiency reasons.                                                                         *
 *=============================================================================================*/
CProfileNode::CProfileNode( const char * name, CProfileNode * parent ) :
      Name( name ),
      TotalCalls( 0 ),
      TotalTime( 0 ),
      StartTime( 0 ),
      RecursionCounter( 0 ),
      Parent( parent ),
      Child( NULL ),
      Sibling( NULL )
{
      Reset();
}


void  CProfileNode::CleanupMemory()
{
      delete ( Child);
      Child = NULL;
      delete ( Sibling);
      Sibling = NULL;
}

CProfileNode::~CProfileNode( void )
{
      delete ( Child);
      delete ( Sibling);
}


/***********************************************************************************************
 * INPUT:                                                                                      *
 * name - static string pointer to the name of the node we are searching for                   *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 * All profile names are assumed to be static strings so this function uses pointer compares   *
 * to find the named node.                                                                     *
 *=============================================================================================*/
CProfileNode * CProfileNode::Get_Sub_Node( const char * name )
{
      // Try to find this sub node
      CProfileNode * child = Child;
      while ( child ) {
            if ( child->Name == name ) {
                  return child;
            }
            child = child->Sibling;
      }

      // We didn't find it, so add it
      
      CProfileNode * node = new CProfileNode( name, this );
      node->Sibling = Child;
      Child = node;
      return node;
}


void  CProfileNode::Reset( void )
{
      TotalCalls = 0;
      TotalTime = 0.0f;
      gProfileClock.reset();

      if ( Child ) {
            Child->Reset();
      }
      if ( Sibling ) {
            Sibling->Reset();
      }
}


void  CProfileNode::Call( void )
{
      TotalCalls++;
      if (RecursionCounter++ == 0) {
            Profile_Get_Ticks(&StartTime);
      }
}


bool  CProfileNode::Return( void )
{
      if ( --RecursionCounter == 0 && TotalCalls != 0 ) { 
            unsigned long int time;
            Profile_Get_Ticks(&time);
            time-=StartTime;
            TotalTime += (float)time / Profile_Get_Tick_Rate();
      }
      return ( RecursionCounter == 0 );
}


/***************************************************************************************************
**
** CProfileIterator
**
***************************************************************************************************/
CProfileIterator::CProfileIterator( CProfileNode * start )
{
      CurrentParent = start;
      CurrentChild = CurrentParent->Get_Child();
}


void  CProfileIterator::First(void)
{
      CurrentChild = CurrentParent->Get_Child();
}


void  CProfileIterator::Next(void)
{
      CurrentChild = CurrentChild->Get_Sibling();
}


bool  CProfileIterator::Is_Done(void)
{
      return CurrentChild == NULL;
}


void  CProfileIterator::Enter_Child( int index )
{
      CurrentChild = CurrentParent->Get_Child();
      while ( (CurrentChild != NULL) && (index != 0) ) {
            index--;
            CurrentChild = CurrentChild->Get_Sibling();
      }

      if ( CurrentChild != NULL ) {
            CurrentParent = CurrentChild;
            CurrentChild = CurrentParent->Get_Child();
      }
}


void  CProfileIterator::Enter_Parent( void )
{
      if ( CurrentParent->Get_Parent() != NULL ) {
            CurrentParent = CurrentParent->Get_Parent();
      }
      CurrentChild = CurrentParent->Get_Child();
}


/***************************************************************************************************
**
** CProfileManager
**
***************************************************************************************************/

CProfileNode      CProfileManager::Root( "Root", NULL );
CProfileNode *    CProfileManager::CurrentNode = &CProfileManager::Root;
int                     CProfileManager::FrameCounter = 0;
unsigned long int             CProfileManager::ResetTime = 0;


/***********************************************************************************************
 * CProfileManager::Start_Profile -- Begin a named profile                                    *
 *                                                                                             *
 * Steps one level deeper into the tree, if a child already exists with the specified name     *
 * then it accumulates the profiling; otherwise a new child node is added to the profile tree. *
 *                                                                                             *
 * INPUT:                                                                                      *
 * name - name of this profiling record                                                        *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 * The string used is assumed to be a static string; pointer compares are used throughout      *
 * the profiling code for efficiency.                                                          *
 *=============================================================================================*/
void  CProfileManager::Start_Profile( const char * name )
{
      if (name != CurrentNode->Get_Name()) {
            CurrentNode = CurrentNode->Get_Sub_Node( name );
      } 
      
      CurrentNode->Call();
}


/***********************************************************************************************
 * CProfileManager::Stop_Profile -- Stop timing and record the results.                       *
 *=============================================================================================*/
void  CProfileManager::Stop_Profile( void )
{
      // Return will indicate whether we should back up to our parent (we may
      // be profiling a recursive function)
      if (CurrentNode->Return()) {
            CurrentNode = CurrentNode->Get_Parent();
      }
}


/***********************************************************************************************
 * CProfileManager::Reset -- Reset the contents of the profiling system                       *
 *                                                                                             *
 *    This resets everything except for the tree structure.  All of the timing data is reset.  *
 *=============================================================================================*/
void  CProfileManager::Reset( void )
{ 
      Root.Reset();
    Root.Call();
      FrameCounter = 0;
      Profile_Get_Ticks(&ResetTime);
}


/***********************************************************************************************
 * CProfileManager::Increment_Frame_Counter -- Increment the frame counter                    *
 *=============================================================================================*/
void CProfileManager::Increment_Frame_Counter( void )
{
      FrameCounter++;
}


/***********************************************************************************************
 * CProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset         *
 *=============================================================================================*/
float CProfileManager::Get_Time_Since_Reset( void )
{
      unsigned long int time;
      Profile_Get_Ticks(&time);
      time -= ResetTime;
      return (float)time / Profile_Get_Tick_Rate();
}

#endif //USE_BT_CLOCK


Generated by  Doxygen 1.6.0   Back to index