Index: cc/frame_rate_counter.cc |
diff --git a/cc/frame_rate_counter.cc b/cc/frame_rate_counter.cc |
index c37956f78c8d06f0e2c1a68a611c9bce17ecf215..6d0e77a92a1b55d1e7836ede339f1814ee0ebd03 100644 |
--- a/cc/frame_rate_counter.cc |
+++ b/cc/frame_rate_counter.cc |
@@ -4,7 +4,7 @@ |
#include "cc/frame_rate_counter.h" |
-#include <cmath> |
+#include <limits> |
#include "base/metrics/histogram.h" |
#include "cc/proxy.h" |
@@ -15,58 +15,37 @@ const double FrameRateCounter::kFrameTooFast = 1.0 / 70.0; // measured in second |
const double FrameRateCounter::kFrameTooSlow = 1.0 / 4.0; |
const double FrameRateCounter::kDroppedFrameTime = 1.0 / 50.0; |
-// safeMod works on -1, returning m-1 in that case. |
-static inline int safeMod(int number, int modulus) |
-{ |
- return (number + modulus) % modulus; |
-} |
- |
// static |
scoped_ptr<FrameRateCounter> FrameRateCounter::create(bool hasImplThread) { |
return make_scoped_ptr(new FrameRateCounter(hasImplThread)); |
} |
-inline base::TimeDelta FrameRateCounter::frameInterval(int frameNumber) const |
-{ |
- return m_timeStampHistory[frameIndex(frameNumber)] - |
- m_timeStampHistory[frameIndex(frameNumber - 1)]; |
-} |
- |
-inline int FrameRateCounter::frameIndex(int frameNumber) const |
+inline base::TimeDelta FrameRateCounter::recentFrameInterval(int n) const |
{ |
- return safeMod(frameNumber, kTimeStampHistorySize); |
+ DCHECK(n > 0); |
+ return m_ringBuffer.ReadBuffer(n) - m_ringBuffer.ReadBuffer(n - 1); |
} |
FrameRateCounter::FrameRateCounter(bool hasImplThread) |
: m_hasImplThread(hasImplThread) |
- , m_currentFrameNumber(1) |
, m_droppedFrameCount(0) |
{ |
- m_timeStampHistory[0] = base::TimeTicks::Now(); |
- m_timeStampHistory[1] = m_timeStampHistory[0]; |
- for (int i = 2; i < kTimeStampHistorySize; i++) |
- m_timeStampHistory[i] = base::TimeTicks(); |
+ m_ringBuffer.SaveToBuffer(base::TimeTicks()); |
} |
-void FrameRateCounter::markBeginningOfFrame(base::TimeTicks timestamp) |
+void FrameRateCounter::saveTimeStamp(base::TimeTicks timestamp) |
{ |
- m_timeStampHistory[frameIndex(m_currentFrameNumber)] = timestamp; |
- base::TimeDelta frameIntervalSeconds = frameInterval(m_currentFrameNumber); |
+ m_ringBuffer.SaveToBuffer(timestamp); |
+ base::TimeDelta frameIntervalSeconds = recentFrameInterval(m_ringBuffer.BufferSize() - 1); |
- if (m_hasImplThread && m_currentFrameNumber > 0) { |
+ if (m_hasImplThread && m_ringBuffer.CurrentIndex() > 0) |
HISTOGRAM_CUSTOM_COUNTS("Renderer4.CompositorThreadImplDrawDelay", frameIntervalSeconds.InMilliseconds(), 1, 120, 60); |
- } |
if (!isBadFrameInterval(frameIntervalSeconds) && |
frameIntervalSeconds.InSecondsF() > kDroppedFrameTime) |
++m_droppedFrameCount; |
} |
-void FrameRateCounter::markEndOfFrame() |
-{ |
- m_currentFrameNumber += 1; |
-} |
- |
bool FrameRateCounter::isBadFrameInterval(base::TimeDelta intervalBetweenConsecutiveFrames) const |
{ |
double delta = intervalBetweenConsecutiveFrames.InSecondsF(); |
@@ -76,14 +55,30 @@ bool FrameRateCounter::isBadFrameInterval(base::TimeDelta intervalBetweenConsecu |
return intervalTooFast || intervalTooSlow; |
} |
-bool FrameRateCounter::isBadFrame(int frameNumber) const |
+void FrameRateCounter::getMinAndMaxFPS(double& minFPS, double& maxFPS) const |
{ |
- return isBadFrameInterval(frameInterval(frameNumber)); |
+ minFPS = std::numeric_limits<double>::max(); |
+ maxFPS = 0; |
+ |
+ for (int i = m_ringBuffer.BufferSize() - 1; i > 0 && m_ringBuffer.IsFilledIndex(i - 1); --i) { |
+ base::TimeDelta delta = recentFrameInterval(i); |
+ |
+ if (isBadFrameInterval(delta)) |
+ continue; |
+ |
+ DCHECK(delta.InSecondsF() > 0); |
egraether
2013/01/10 23:38:29
checking divide by 0
|
+ double fps = 1.0 / delta.InSecondsF(); |
+ |
+ minFPS = std::min(fps, minFPS); |
+ maxFPS = std::max(fps, maxFPS); |
+ } |
+ |
+ if (minFPS > maxFPS) |
+ minFPS = maxFPS; |
} |
double FrameRateCounter::getAverageFPS() const |
{ |
- int frameNumber = m_currentFrameNumber - 1; |
int frameCount = 0; |
double frameTimesTotal = 0; |
double averageFPS = 0; |
@@ -99,20 +94,20 @@ double FrameRateCounter::getAverageFPS() const |
// |
// isBadFrameInterval encapsulates the frame too slow/frame too fast logic. |
- while (frameIndex(frameNumber) != frameIndex(m_currentFrameNumber) && frameNumber >= 0 && frameTimesTotal < 1.0) { |
- base::TimeDelta delta = frameInterval(frameNumber); |
+ for (int i = m_ringBuffer.BufferSize() - 1; i > 0 && m_ringBuffer.IsFilledIndex(i - 1) && frameTimesTotal < 1.0; --i) { |
+ base::TimeDelta delta = recentFrameInterval(i); |
if (!isBadFrameInterval(delta)) { |
frameCount++; |
frameTimesTotal += delta.InSecondsF(); |
} else if (frameCount) |
break; |
- |
- frameNumber--; |
} |
- if (frameCount) |
+ if (frameCount) { |
+ DCHECK(frameTimesTotal > 0); |
egraether
2013/01/10 23:38:29
checking divide by 0
|
averageFPS = frameCount / frameTimesTotal; |
+ } |
return averageFPS; |
} |
@@ -120,9 +115,12 @@ double FrameRateCounter::getAverageFPS() const |
base::TimeTicks FrameRateCounter::timeStampOfRecentFrame(int n) const |
{ |
DCHECK(n >= 0); |
- DCHECK(n < kTimeStampHistorySize); |
- int desiredIndex = (frameIndex(m_currentFrameNumber) + n) % kTimeStampHistorySize; |
- return m_timeStampHistory[desiredIndex]; |
+ DCHECK(n < m_ringBuffer.BufferSize()); |
+ |
+ if (m_ringBuffer.IsFilledIndex(n)) |
+ return m_ringBuffer.ReadBuffer(n); |
+ |
+ return base::TimeTicks(); |
egraether
2013/01/10 23:38:29
Returns base::TimeTicks() for an invalid index. No
|
} |
} // namespace cc |