1/* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "TimeComputer.h" 8 9 10TimeComputer::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 26void 27TimeComputer::Init(float frameRate, bigtime_t realBaseTime) 28{ 29 fRealTime = realBaseTime; 30 fPerformanceTime = 0; 31 fDrift = 1; 32 SetFrameRate(frameRate); 33} 34 35 36void 37TimeComputer::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 50void 51TimeComputer::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 85void 86TimeComputer::_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