Windows2003-3790/multimedia/opengl/toolkits/libmtk/timer.cxx
2020-09-30 16:53:55 +02:00

195 lines
4.9 KiB
C++

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
#include "mtk.h"
#include "timer.hxx"
/****** TIMER *******************************************************/
TIMER::TIMER()
{
Reset();
}
void
TIMER::Reset()
{
dwTotalMillis = 0;
bRunning = FALSE;
}
void
TIMER::Start()
{
dwStartMillis = GetTickCount();
bRunning = TRUE;
}
float
TIMER::Stop()
{
if( bRunning ) {
// Need to stop the timer
dwElapsedMillis = GetTickCount() - dwStartMillis;
dwTotalMillis += dwElapsedMillis;
bRunning = FALSE;
}
return MillisToSeconds( dwTotalMillis );
}
float
TIMER::Elapsed()
{
if( !bRunning )
return MillisToSeconds( dwTotalMillis );
dwElapsedMillis = GetTickCount() - dwStartMillis;
return MillisToSeconds( dwTotalMillis + dwElapsedMillis );
}
/****** UPDATE_TIMER *******************************************************/
// mf: need to address how dwTotalMillis used here, and in AVG
// Problem is that we effectively reset the timer on every update. This assumes
// that the number of items is >> # drawn in interval. But wait, that's the way
// it should be : We're measuring withing a time slice defined by the interval update, and don't want to include any previous slices. Of course, AVG_UPTDATE_TIMER *could* do this...
UPDATE_TIMER::UPDATE_TIMER( float fUpdateInterval )
: updateInterval( SecondsToMillis(fUpdateInterval) )
{
Reset();
}
void
UPDATE_TIMER::Reset()
{
TIMER::Reset();
nTotalItems = 0;
fUpdateRate = 0.0f;
}
BOOL
UPDATE_TIMER::Update( int numItems, float *fRate )
{
// Elapsed time will be total time plus current interval (if running)
dwElapsedMillis = dwTotalMillis;
if( bRunning ) {
dwElapsedMillis += GetTickCount()-dwStartMillis;
nTotalItems += numItems;
}
// If total elapsed time is greater than the update interval, send back
// timing information
if( bRunning && (dwElapsedMillis > updateInterval) )
{
int iNewResult;
fUpdateRate = (float) nTotalItems*1000.0f/dwElapsedMillis;
*fRate = fUpdateRate;
// At the end of each update period, we effectively reset and restart
// the timer, and set running totals back to 0
Reset();
Start();
return TRUE;
} else {
*fRate = fUpdateRate; // return last calculated value to caller
return FALSE; // no new information yet
}
}
/****** AVG_UPDATE_TIMER *****************************************************/
AVG_UPDATE_TIMER::AVG_UPDATE_TIMER( float fUpdateInterval, int numResults )
: UPDATE_TIMER( fUpdateInterval), nMaxResults( numResults )
{
Reset();
}
void
AVG_UPDATE_TIMER::Reset()
{
UPDATE_TIMER::Reset();
nResults = 0;
SS_CLAMP_TO_RANGE2( nMaxResults, 1, MAX_RESULTS );
fSummedResults = 0.0f;
iOldestResult = 0; // index of oldest result
}
BOOL
AVG_UPDATE_TIMER::Update( int numItems, float *fRate )
{
dwElapsedMillis = dwTotalMillis;
if( bRunning ) {
dwElapsedMillis += GetTickCount()-dwStartMillis;
nTotalItems += numItems;
}
// If total elapsed time is greater than the update interval, send back
// timing information
if( bRunning && (dwElapsedMillis > updateInterval) )
{
int iNewResult;
float fItemsPerSecond;
fItemsPerSecond = (float) nTotalItems*1000.0f/dwElapsedMillis;
// Average last n results (they are kept in a circular buffer)
if( nResults < nMaxResults ) {
// Haven't filled the buffer yet
iNewResult = nResults;
nResults++;
} else {
// Full buffer : replace oldest entry with new value
fSummedResults -= fResults[iOldestResult];
iNewResult = iOldestResult;
iOldestResult = (iOldestResult == (nMaxResults - 1)) ?
0 :
(iOldestResult + 1);
}
// Add new result, maintain sum to simplify calculations
fResults[iNewResult] = fItemsPerSecond;
fSummedResults += fItemsPerSecond;
// average the result
fUpdateRate = fSummedResults / (float) nResults;
*fRate = fUpdateRate;
// At the end of each update period, we effectively reset and restart
// the update timer, and set running totals back to 0
UPDATE_TIMER::Reset();
UPDATE_TIMER::Start();
return TRUE;
} else {
*fRate = fUpdateRate; // return last calculated value to caller
return FALSE; // no new information yet
}
}