1 //============================================================================
2 //
3 //   SSSS    tt          lll  lll
4 //  SS  SS   tt           ll   ll
5 //  SS     tttttt  eeee   ll   ll   aaaa
6 //   SSSS    tt   ee  ee  ll   ll      aa
7 //      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
8 //  SS  SS   tt   ee      ll   ll  aa  aa
9 //   SSSS     ttt  eeeee llll llll  aaaaa
10 //
11 // Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
12 // and the Stella Team
13 //
14 // See the file "License.txt" for information on usage and redistribution of
15 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
16 //============================================================================
17 
18 #include "FpsMeter.hxx"
19 
20 using namespace std::chrono;
21 
22 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FpsMeter(uInt32 queueSize)23 FpsMeter::FpsMeter(uInt32 queueSize)
24   : myQueue{queueSize}
25 {
26   reset();
27 }
28 
29 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
reset(uInt32 garbageFrameLimit)30 void FpsMeter::reset(uInt32 garbageFrameLimit)
31 {
32   myQueue.clear();
33   myQueueOffset = 0;
34   myFrameCount = 0;
35   myFps = 0;
36   myGarbageFrameCounter = 0;
37   myGarbageFrameLimit = garbageFrameLimit;
38 }
39 
40 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
render(uInt32 frameCount)41 void FpsMeter::render(uInt32 frameCount)
42 {
43   if (myGarbageFrameCounter < myGarbageFrameLimit) {
44     myGarbageFrameCounter += frameCount;
45     return;
46   }
47 
48   size_t queueSize = myQueue.capacity();
49   entry first, last;
50 
51   last.frames = frameCount;
52   last.timestamp = high_resolution_clock::now();
53 
54   if (myQueue.size() < queueSize) {
55     myQueue.push_back(last);
56     myFrameCount += frameCount;
57 
58     first = myQueue.at(myQueueOffset);
59   } else {
60     myFrameCount = myFrameCount - myQueue.at(myQueueOffset).frames + frameCount;
61     myQueue.at(myQueueOffset) = last;
62 
63     myQueueOffset = (myQueueOffset + 1) % queueSize;
64     first = myQueue.at(myQueueOffset);
65   }
66 
67   float myTimeInterval =
68     duration_cast<duration<float>>(last.timestamp - first.timestamp).count();
69 
70   if (myTimeInterval > 0) myFps = (myFrameCount - first.frames) / myTimeInterval;
71 }
72 
73 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
fps() const74 float FpsMeter::fps() const
75 {
76   return myFps;
77 }
78