1cb007542SIngo Weinhold /*
2cb007542SIngo Weinhold * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3cb007542SIngo Weinhold * Distributed under the terms of the MIT License.
4cb007542SIngo Weinhold */
5cb007542SIngo Weinhold #include "TimeComputer.h"
6cb007542SIngo Weinhold
7*b5142f76SAugustin Cavalier #include <OS.h>
8*b5142f76SAugustin Cavalier
9cb007542SIngo Weinhold
TimeComputer()10cb007542SIngo Weinhold TimeComputer::TimeComputer()
11cb007542SIngo Weinhold :
12cb007542SIngo Weinhold fRealTime(0),
13cb007542SIngo Weinhold fPerformanceTime(0),
14cb007542SIngo Weinhold fDrift(1),
15cb007542SIngo Weinhold fFrameRate(1000000),
16cb007542SIngo Weinhold fUsecsPerFrame(1),
17cb007542SIngo Weinhold fPerformanceTimeBase(0),
18cb007542SIngo Weinhold fFrameBase(0),
19cb007542SIngo Weinhold fResetTimeBase(true),
20cb007542SIngo Weinhold fFirstEntry(0),
21cb007542SIngo Weinhold fLastEntry(0)
22cb007542SIngo Weinhold {
23cb007542SIngo Weinhold }
24cb007542SIngo Weinhold
25cb007542SIngo Weinhold
26cb007542SIngo Weinhold void
Init(float frameRate,bigtime_t realBaseTime)27cb007542SIngo Weinhold TimeComputer::Init(float frameRate, bigtime_t realBaseTime)
28cb007542SIngo Weinhold {
29cb007542SIngo Weinhold fRealTime = realBaseTime;
30cb007542SIngo Weinhold fPerformanceTime = 0;
31cb007542SIngo Weinhold fDrift = 1;
32cb007542SIngo Weinhold SetFrameRate(frameRate);
33cb007542SIngo Weinhold }
34cb007542SIngo Weinhold
35cb007542SIngo Weinhold
36cb007542SIngo Weinhold void
SetFrameRate(float frameRate)37cb007542SIngo Weinhold TimeComputer::SetFrameRate(float frameRate)
38cb007542SIngo Weinhold {
39cb007542SIngo Weinhold if (frameRate == fFrameRate)
40cb007542SIngo Weinhold return;
41cb007542SIngo Weinhold
42cb007542SIngo Weinhold fFrameRate = frameRate;
43cb007542SIngo Weinhold fUsecsPerFrame = (double)1000000 / fFrameRate;
44cb007542SIngo Weinhold fResetTimeBase = true;
45cb007542SIngo Weinhold fFirstEntry = 0;
46cb007542SIngo Weinhold fLastEntry = 0;
47cb007542SIngo Weinhold }
48cb007542SIngo Weinhold
49cb007542SIngo Weinhold
50cb007542SIngo Weinhold void
AddTimeStamp(bigtime_t realTime,uint64 frames)51cb007542SIngo Weinhold TimeComputer::AddTimeStamp(bigtime_t realTime, uint64 frames)
52cb007542SIngo Weinhold {
53cb007542SIngo Weinhold bigtime_t estimatedPerformanceTime = fPerformanceTime
54cb007542SIngo Weinhold + bigtime_t((realTime - fRealTime) * fDrift);
55cb007542SIngo Weinhold
56cb007542SIngo Weinhold fRealTime = realTime;
57cb007542SIngo Weinhold
58cb007542SIngo Weinhold if (fResetTimeBase) {
59cb007542SIngo Weinhold // use the extrapolated performance time at the given real time
60cb007542SIngo Weinhold fPerformanceTime = estimatedPerformanceTime;
61cb007542SIngo Weinhold fPerformanceTimeBase = estimatedPerformanceTime;
62cb007542SIngo Weinhold fFrameBase = frames;
63cb007542SIngo Weinhold fResetTimeBase = false;
64cb007542SIngo Weinhold _AddEntry(fRealTime, fPerformanceTime);
65cf238ffcSMichael Lotz fFirstEntry = fLastEntry;
66cb007542SIngo Weinhold return;
67cb007542SIngo Weinhold }
68cb007542SIngo Weinhold
69cb007542SIngo Weinhold // add entry
70cb007542SIngo Weinhold bigtime_t performanceTime = fPerformanceTimeBase
71cb007542SIngo Weinhold + bigtime_t((frames - fFrameBase) * fUsecsPerFrame);
72cb007542SIngo Weinhold _AddEntry(realTime, performanceTime);
73cb007542SIngo Weinhold
74cb007542SIngo Weinhold // Update performance time and drift. We don't use the given
75cb007542SIngo Weinhold // performance time directly, but average it with the estimated
76cb007542SIngo Weinhold // performance time.
77cb007542SIngo Weinhold fPerformanceTime = (performanceTime + estimatedPerformanceTime) / 2;
78cb007542SIngo Weinhold
79cb007542SIngo Weinhold Entry& entry = fEntries[fFirstEntry];
80cb007542SIngo Weinhold fDrift = double(fPerformanceTime - entry.performanceTime)
81cb007542SIngo Weinhold / double(fRealTime - entry.realTime);
82cb007542SIngo Weinhold }
83cb007542SIngo Weinhold
84cb007542SIngo Weinhold
85cb007542SIngo Weinhold void
_AddEntry(bigtime_t realTime,bigtime_t performanceTime)86cb007542SIngo Weinhold TimeComputer::_AddEntry(bigtime_t realTime, bigtime_t performanceTime)
87cb007542SIngo Weinhold {
88cb007542SIngo Weinhold fLastEntry = (fLastEntry + 1) % kEntryCount;
89cb007542SIngo Weinhold Entry& entry = fEntries[fLastEntry];
90cb007542SIngo Weinhold entry.realTime = realTime;
91cb007542SIngo Weinhold entry.performanceTime = performanceTime;
92cb007542SIngo Weinhold
93cb007542SIngo Weinhold if (fLastEntry == fFirstEntry)
94cb007542SIngo Weinhold fFirstEntry = (fFirstEntry + 1) % kEntryCount;
95cb007542SIngo Weinhold }
96