Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: cc/frame_rate_counter.cc

Issue 11817011: cc: add RingBuffer class for timestamp storing in FrameRateCounter (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/frame_rate_counter.h" 5 #include "cc/frame_rate_counter.h"
6 6
7 #include <cmath> 7 #include <limits>
8 8
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "cc/proxy.h" 10 #include "cc/proxy.h"
11 11
12 namespace cc { 12 namespace cc {
13 13
14 const double FrameRateCounter::kFrameTooFast = 1.0 / 70.0; // measured in second s 14 const double FrameRateCounter::kFrameTooFast = 1.0 / 70.0; // measured in second s
15 const double FrameRateCounter::kFrameTooSlow = 1.0 / 4.0; 15 const double FrameRateCounter::kFrameTooSlow = 1.0 / 4.0;
16 const double FrameRateCounter::kDroppedFrameTime = 1.0 / 50.0; 16 const double FrameRateCounter::kDroppedFrameTime = 1.0 / 50.0;
17 17
18 // safeMod works on -1, returning m-1 in that case.
19 static inline int safeMod(int number, int modulus)
20 {
21 return (number + modulus) % modulus;
22 }
23
24 // static 18 // static
25 scoped_ptr<FrameRateCounter> FrameRateCounter::create(bool hasImplThread) { 19 scoped_ptr<FrameRateCounter> FrameRateCounter::create(bool hasImplThread) {
26 return make_scoped_ptr(new FrameRateCounter(hasImplThread)); 20 return make_scoped_ptr(new FrameRateCounter(hasImplThread));
27 } 21 }
28 22
29 inline base::TimeDelta FrameRateCounter::frameInterval(int frameNumber) const 23 inline base::TimeDelta FrameRateCounter::frameInterval(int frameNumber) const
30 { 24 {
31 return m_timeStampHistory[frameIndex(frameNumber)] - 25 return m_buffer[bufferIndex(frameNumber)] - m_buffer[bufferIndex(frameNumber - 1)];
32 m_timeStampHistory[frameIndex(frameNumber - 1)];
33 }
34
35 inline int FrameRateCounter::frameIndex(int frameNumber) const
36 {
37 return safeMod(frameNumber, kTimeStampHistorySize);
38 } 26 }
39 27
40 FrameRateCounter::FrameRateCounter(bool hasImplThread) 28 FrameRateCounter::FrameRateCounter(bool hasImplThread)
41 : m_hasImplThread(hasImplThread) 29 : m_hasImplThread(hasImplThread)
42 , m_currentFrameNumber(1)
43 , m_droppedFrameCount(0) 30 , m_droppedFrameCount(0)
44 { 31 {
45 m_timeStampHistory[0] = base::TimeTicks::Now(); 32 m_buffer[0] = m_buffer[1] = base::TimeTicks::Now();
46 m_timeStampHistory[1] = m_timeStampHistory[0]; 33 m_currentIndex = 1;
47 for (int i = 2; i < kTimeStampHistorySize; i++) 34 for (int i = 2; i < bufferSize(); i++)
48 m_timeStampHistory[i] = base::TimeTicks(); 35 m_buffer[i] = base::TimeTicks();
49 } 36 }
50 37
51 void FrameRateCounter::markBeginningOfFrame(base::TimeTicks timestamp) 38 void FrameRateCounter::saveTimeStamp(base::TimeTicks timestamp)
52 { 39 {
53 m_timeStampHistory[frameIndex(m_currentFrameNumber)] = timestamp; 40 saveToBuffer(timestamp);
54 base::TimeDelta frameIntervalSeconds = frameInterval(m_currentFrameNumber); 41 base::TimeDelta frameIntervalSeconds = frameInterval(m_currentIndex);
55 42
56 if (m_hasImplThread && m_currentFrameNumber > 0) { 43 if (m_hasImplThread && m_currentIndex > 0)
57 HISTOGRAM_CUSTOM_COUNTS("Renderer4.CompositorThreadImplDrawDelay", frame IntervalSeconds.InMilliseconds(), 1, 120, 60); 44 HISTOGRAM_CUSTOM_COUNTS("Renderer4.CompositorThreadImplDrawDelay", frame IntervalSeconds.InMilliseconds(), 1, 120, 60);
58 }
59 45
60 if (!isBadFrameInterval(frameIntervalSeconds) && 46 if (!isBadFrameInterval(frameIntervalSeconds) &&
61 frameIntervalSeconds.InSecondsF() > kDroppedFrameTime) 47 frameIntervalSeconds.InSecondsF() > kDroppedFrameTime)
62 ++m_droppedFrameCount; 48 ++m_droppedFrameCount;
63 } 49 }
64 50
65 void FrameRateCounter::markEndOfFrame()
66 {
67 m_currentFrameNumber += 1;
68 }
69
70 bool FrameRateCounter::isBadFrameInterval(base::TimeDelta intervalBetweenConsecu tiveFrames) const 51 bool FrameRateCounter::isBadFrameInterval(base::TimeDelta intervalBetweenConsecu tiveFrames) const
71 { 52 {
72 double delta = intervalBetweenConsecutiveFrames.InSecondsF(); 53 double delta = intervalBetweenConsecutiveFrames.InSecondsF();
73 bool schedulerAllowsDoubleFrames = !m_hasImplThread; 54 bool schedulerAllowsDoubleFrames = !m_hasImplThread;
74 bool intervalTooFast = schedulerAllowsDoubleFrames ? delta < kFrameTooFast : delta <= 0.0; 55 bool intervalTooFast = schedulerAllowsDoubleFrames ? delta < kFrameTooFast : delta <= 0.0;
75 bool intervalTooSlow = delta > kFrameTooSlow; 56 bool intervalTooSlow = delta > kFrameTooSlow;
76 return intervalTooFast || intervalTooSlow; 57 return intervalTooFast || intervalTooSlow;
77 } 58 }
78 59
79 bool FrameRateCounter::isBadFrame(int frameNumber) const 60 void FrameRateCounter::getMinAndMaxFPS(double& minFPS, double& maxFPS) const
80 { 61 {
81 return isBadFrameInterval(frameInterval(frameNumber)); 62 minFPS = std::numeric_limits<double>::max();
63 maxFPS = 0;
64
65 for (int i = m_currentIndex - 1; i > 0 && bufferIndex(i) != bufferIndex(m_cu rrentIndex); --i) {
66 base::TimeDelta delta = frameInterval(i);
67
68 if (isBadFrameInterval(delta))
69 continue;
70
71 double fps = 1.0 / delta.InSecondsF();
72
73 minFPS = std::min(fps, minFPS);
74 maxFPS = std::max(fps, maxFPS);
75 }
76
77 if (minFPS > maxFPS)
78 minFPS = maxFPS;
82 } 79 }
83 80
84 double FrameRateCounter::getAverageFPS() const 81 double FrameRateCounter::getAverageFPS() const
85 { 82 {
86 int frameNumber = m_currentFrameNumber - 1; 83 int frameNumber = m_currentIndex - 1;
87 int frameCount = 0; 84 int frameCount = 0;
88 double frameTimesTotal = 0; 85 double frameTimesTotal = 0;
89 double averageFPS = 0; 86 double averageFPS = 0;
90 87
91 // Walk backwards through the samples looking for a run of good frame 88 // Walk backwards through the samples looking for a run of good frame
92 // timings from which to compute the mean. 89 // timings from which to compute the mean.
93 // 90 //
94 // Slow frames occur just because the user is inactive, and should be 91 // Slow frames occur just because the user is inactive, and should be
95 // ignored. Fast frames are ignored if the scheduler is in single-thread 92 // ignored. Fast frames are ignored if the scheduler is in single-thread
96 // mode in order to represent the true frame rate in spite of the fact that 93 // mode in order to represent the true frame rate in spite of the fact that
97 // the first few swapbuffers happen instantly which skews the statistics 94 // the first few swapbuffers happen instantly which skews the statistics
98 // too much for short lived animations. 95 // too much for short lived animations.
99 // 96 //
100 // isBadFrameInterval encapsulates the frame too slow/frame too fast logic. 97 // isBadFrameInterval encapsulates the frame too slow/frame too fast logic.
101 98
102 while (frameIndex(frameNumber) != frameIndex(m_currentFrameNumber) && frameN umber >= 0 && frameTimesTotal < 1.0) { 99 while (bufferIndex(frameNumber) != bufferIndex(m_currentIndex) && frameNumbe r >= 0 && frameTimesTotal < 1.0) {
103 base::TimeDelta delta = frameInterval(frameNumber); 100 base::TimeDelta delta = frameInterval(frameNumber);
104 101
105 if (!isBadFrameInterval(delta)) { 102 if (!isBadFrameInterval(delta)) {
106 frameCount++; 103 frameCount++;
107 frameTimesTotal += delta.InSecondsF(); 104 frameTimesTotal += delta.InSecondsF();
108 } else if (frameCount) 105 } else if (frameCount)
109 break; 106 break;
110 107
111 frameNumber--; 108 frameNumber--;
112 } 109 }
113 110
114 if (frameCount) 111 if (frameCount)
115 averageFPS = frameCount / frameTimesTotal; 112 averageFPS = frameCount / frameTimesTotal;
116 113
117 return averageFPS; 114 return averageFPS;
118 } 115 }
119 116
120 base::TimeTicks FrameRateCounter::timeStampOfRecentFrame(int n) const
121 {
122 DCHECK(n >= 0);
123 DCHECK(n < kTimeStampHistorySize);
124 int desiredIndex = (frameIndex(m_currentFrameNumber) + n) % kTimeStampHistor ySize;
125 return m_timeStampHistory[desiredIndex];
126 }
127
128 } // namespace cc 117 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698