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