OpenSceneGraph/include/osg/Timer
Robert Osfield 82008d5ecd Updates to the flush rendering objects function calls to allow for
managment of amount of time available to do gl delete's.  This control is
required for constant frame rate applications.
2003-07-15 21:19:03 +00:00

229 lines
5.7 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSG_TIMER
#define OSG_TIMER 1
#include <osg/Export>
#if defined(_MSC_VER)
namespace osg {
typedef __int64 Timer_t;
}
#elif defined(__linux) || defined(__FreeBSD__) || defined(__CYGWIN__)|| defined(__MINGW32__)
namespace osg {
typedef unsigned long long Timer_t;
}
#elif defined(__sgi)
namespace osg {
typedef unsigned long long Timer_t;
}
#elif defined(unix)
namespace osg {
typedef unsigned long long Timer_t;
}
#elif defined __APPLE__ || defined macintosh
namespace osg {
typedef double Timer_t;
}
#else
#include <ctime>
namespace osg {
typedef std::clock_t Timer_t;
}
#endif
namespace osg {
/** A high resolution, low latency time stamper.*/
class SG_EXPORT Timer {
public:
Timer();
~Timer() {}
static const Timer* instance();
#if defined __DARWIN_OSX__ || defined macintosh
// PJA MAC OSX - inline Tick() pollutes namespace so badly
// we cant compile, due to Carbon.h ...
Timer_t tick() const;
#else
inline Timer_t tick() const;
#endif
inline double delta_s( Timer_t t1, Timer_t t2 ) const { return (double)(t2 - t1)*_secsPerClick; }
inline double delta_m( Timer_t t1, Timer_t t2 ) const { return delta_s(t1,t2)*1e3; }
inline double delta_u( Timer_t t1, Timer_t t2 ) const { return delta_s(t1,t2)*1e6; }
inline double delta_n( Timer_t t1, Timer_t t2 ) const { return delta_s(t1,t2)*1e9; }
private :
double _secsPerClick;
bool _useStandardClock;
# ifdef __sgi
unsigned long* _clockAddress_32;
unsigned long long* _clockAddress_64;
int _cycleCntrSize;
// for SGI machines with 32 bit clocks.
mutable unsigned long _lastClockValue;
mutable unsigned long long _rollOver;
# endif
};
}
#if defined(_MSC_VER)
#include <time.h>
#pragma optimize("",off)
namespace osg{
inline Timer_t Timer::tick( void ) const
{
if (_useStandardClock) return clock();
volatile Timer_t ts;
volatile unsigned int HighPart;
volatile unsigned int LowPart;
_asm
{
xor eax, eax // Used when QueryPerformanceCounter()
xor edx, edx // not supported or minimal overhead
_emit 0x0f // desired
_emit 0x31 //
mov HighPart,edx
mov LowPart,eax
}
//ts = LowPart | HighPart >> 32;
*((unsigned int*)&ts) = LowPart;
*((unsigned int*)&ts+1) = HighPart;
return ts;
}
}
#pragma optimize("",on)
#elif defined(__MINGW32__)
#include <sys/time.h>
#define CLK(x) __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x))
namespace osg{
inline Timer_t Timer::tick() const
{
if (_useStandardClock)
return clock();
else
{
Timer_t x;CLK(x);return x;
}
}
}
#elif defined(__linux) || defined(__FreeBSD__) || defined(__CYGWIN__)
#include <sys/time.h>
#ifdef __ia64
#define CLK(x) ((x)=0)
#else
#define CLK(x) __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x))
#endif
namespace osg{
inline Timer_t Timer::tick() const
{
if (_useStandardClock)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return ((osg::Timer_t)tv.tv_sec)*1000000+(osg::Timer_t)tv.tv_usec;
}
else
{
Timer_t x;CLK(x);return x;
}
}
}
#elif defined(__sgi)
#include <sys/types.h>
#include <sys/time.h>
namespace osg{
inline Timer_t Timer::tick() const
{
if (_useStandardClock)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return ((osg::Timer_t)tv.tv_sec)*1000000+(osg::Timer_t)tv.tv_usec;
}
else
{
if ( _clockAddress_64 )
return *_clockAddress_64;
else
{
unsigned long clockValue = *_clockAddress_32;
if( _lastClockValue > clockValue )
{
_rollOver += 0x100000000L;
}
_lastClockValue = clockValue;
return _rollOver + clockValue;
}
}
}
}
#elif defined(unix)
#include <sys/time.h>
namespace osg{
inline Timer_t Timer::tick() const
{
struct timeval tv;
gettimeofday(&tv, NULL);
return ((osg::Timer_t)tv.tv_sec)*1000000+(osg::Timer_t)tv.tv_usec;
}
}
#elif !defined (__DARWIN_OSX__) && !defined (macintosh)
// no choice, always use std::clock()
namespace osg{
inline Timer_t Timer::tick( void ) const { return std::clock(); }
}
#endif
// note, MacOSX compiled in the Timer.cpp.
#endif