File: FrameTimer.cpp

package info (click to toggle)
jazz2-native 3.5.0-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 16,912 kB
  • sloc: cpp: 172,557; xml: 113; python: 36; makefile: 5; sh: 2
file content (73 lines) | stat: -rw-r--r-- 2,484 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include "FrameTimer.h"
#include "../../Main.h"

#include <algorithm>

namespace nCine
{
	FrameTimer::FrameTimer(float logInterval, float avgInterval)
		: _averageInterval(avgInterval), _loggingInterval(logInterval), _frameDuration(0.0f), _lastAvgUpdate(TimeStamp::now()),
			_totNumFrames(0L), _avgNumFrames(0L), _logNumFrames(0L), _avgFps(0.0f), _timeMults{1.0f, 1.0f, 1.0f}
	{
	}

	void FrameTimer::AddFrame()
	{
		_frameDuration = _frameStart.secondsSince();

		// Start counting for the next frame interval
		_frameStart = TimeStamp::now();

		_totNumFrames++;
		_avgNumFrames++;
		_logNumFrames++;

		// Smooth out time multiplier using last 3 frames to prevent microstuttering
		const float timeMultLast = _timeMults[0];
		_timeMults[0] = (_timeMults[2] + _timeMults[1] + timeMultLast + (std::min(_frameDuration, SecondsPerFrame * 2) / SecondsPerFrame)) * 0.25f;
		_timeMults[2] = _timeMults[1];
		_timeMults[1] = timeMultLast;

		// Update the FPS average calculation every `avgInterval_` seconds
		if (_frameStart < _lastAvgUpdate || _frameStart < _lastLogUpdate) {
			LOGW("Detected time discontinuity, resetting counters");
			_lastAvgUpdate = _frameStart;
			_lastLogUpdate = _frameStart;
		}

		const float secsSinceLastAvgUpdate = (_frameStart - _lastAvgUpdate).seconds();
		if (_averageInterval > 0.0f && secsSinceLastAvgUpdate > _averageInterval) {
			_avgFps = static_cast<float>(_avgNumFrames) / secsSinceLastAvgUpdate;

			_avgNumFrames = 0L;
			_lastAvgUpdate = _frameStart;
		}

		const float secsSinceLastLogUpdate = (_frameStart - _lastLogUpdate).seconds();
		// Log number of frames and FPS every `logInterval_` seconds
		if (_loggingInterval > 0.0f && _avgNumFrames != 0 && secsSinceLastLogUpdate > _loggingInterval) {
			_avgFps = static_cast<float>(_logNumFrames) / _loggingInterval;
#if defined(DEATH_TRACE) && defined(DEATH_DEBUG)
			//const float msPerFrame = (_loggingInterval * 1000.0f) / static_cast<float>(_logNumFrames);
			//LOGD("{} frames in {:.0} seconds = {:.1} FPS ({:.2}ms per frame)", _logNumFrames, _loggingInterval, _avgFps, msPerFrame);
#endif
			_logNumFrames = 0L;
			_lastLogUpdate = _frameStart;
		}
	}

	void FrameTimer::Suspend()
	{
		_suspensionStart = TimeStamp::now();
	}

	TimeStamp FrameTimer::Resume()
	{
		const TimeStamp suspensionDuration = _suspensionStart.timeSince();
		_frameStart += suspensionDuration;
		_lastAvgUpdate += suspensionDuration;
		_lastLogUpdate += suspensionDuration;

		return suspensionDuration;
	}
}