Mailbox support for texture layers.
[chromium-blink-merge.git] / cc / frame_rate_counter.cc
blobc37956f78c8d06f0e2c1a68a611c9bce17ecf215
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
3 // found in the LICENSE file.
5 #include "cc/frame_rate_counter.h"
7 #include <cmath>
9 #include "base/metrics/histogram.h"
10 #include "cc/proxy.h"
12 namespace cc {
14 const double FrameRateCounter::kFrameTooFast = 1.0 / 70.0; // measured in seconds
15 const double FrameRateCounter::kFrameTooSlow = 1.0 / 4.0;
16 const double FrameRateCounter::kDroppedFrameTime = 1.0 / 50.0;
18 // safeMod works on -1, returning m-1 in that case.
19 static inline int safeMod(int number, int modulus)
21 return (number + modulus) % modulus;
24 // static
25 scoped_ptr<FrameRateCounter> FrameRateCounter::create(bool hasImplThread) {
26 return make_scoped_ptr(new FrameRateCounter(hasImplThread));
29 inline base::TimeDelta FrameRateCounter::frameInterval(int frameNumber) const
31 return m_timeStampHistory[frameIndex(frameNumber)] -
32 m_timeStampHistory[frameIndex(frameNumber - 1)];
35 inline int FrameRateCounter::frameIndex(int frameNumber) const
37 return safeMod(frameNumber, kTimeStampHistorySize);
40 FrameRateCounter::FrameRateCounter(bool hasImplThread)
41 : m_hasImplThread(hasImplThread)
42 , m_currentFrameNumber(1)
43 , m_droppedFrameCount(0)
45 m_timeStampHistory[0] = base::TimeTicks::Now();
46 m_timeStampHistory[1] = m_timeStampHistory[0];
47 for (int i = 2; i < kTimeStampHistorySize; i++)
48 m_timeStampHistory[i] = base::TimeTicks();
51 void FrameRateCounter::markBeginningOfFrame(base::TimeTicks timestamp)
53 m_timeStampHistory[frameIndex(m_currentFrameNumber)] = timestamp;
54 base::TimeDelta frameIntervalSeconds = frameInterval(m_currentFrameNumber);
56 if (m_hasImplThread && m_currentFrameNumber > 0) {
57 HISTOGRAM_CUSTOM_COUNTS("Renderer4.CompositorThreadImplDrawDelay", frameIntervalSeconds.InMilliseconds(), 1, 120, 60);
60 if (!isBadFrameInterval(frameIntervalSeconds) &&
61 frameIntervalSeconds.InSecondsF() > kDroppedFrameTime)
62 ++m_droppedFrameCount;
65 void FrameRateCounter::markEndOfFrame()
67 m_currentFrameNumber += 1;
70 bool FrameRateCounter::isBadFrameInterval(base::TimeDelta intervalBetweenConsecutiveFrames) const
72 double delta = intervalBetweenConsecutiveFrames.InSecondsF();
73 bool schedulerAllowsDoubleFrames = !m_hasImplThread;
74 bool intervalTooFast = schedulerAllowsDoubleFrames ? delta < kFrameTooFast : delta <= 0.0;
75 bool intervalTooSlow = delta > kFrameTooSlow;
76 return intervalTooFast || intervalTooSlow;
79 bool FrameRateCounter::isBadFrame(int frameNumber) const
81 return isBadFrameInterval(frameInterval(frameNumber));
84 double FrameRateCounter::getAverageFPS() const
86 int frameNumber = m_currentFrameNumber - 1;
87 int frameCount = 0;
88 double frameTimesTotal = 0;
89 double averageFPS = 0;
91 // Walk backwards through the samples looking for a run of good frame
92 // timings from which to compute the mean.
94 // 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
96 // 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
98 // too much for short lived animations.
100 // isBadFrameInterval encapsulates the frame too slow/frame too fast logic.
102 while (frameIndex(frameNumber) != frameIndex(m_currentFrameNumber) && frameNumber >= 0 && frameTimesTotal < 1.0) {
103 base::TimeDelta delta = frameInterval(frameNumber);
105 if (!isBadFrameInterval(delta)) {
106 frameCount++;
107 frameTimesTotal += delta.InSecondsF();
108 } else if (frameCount)
109 break;
111 frameNumber--;
114 if (frameCount)
115 averageFPS = frameCount / frameTimesTotal;
117 return averageFPS;
120 base::TimeTicks FrameRateCounter::timeStampOfRecentFrame(int n) const
122 DCHECK(n >= 0);
123 DCHECK(n < kTimeStampHistorySize);
124 int desiredIndex = (frameIndex(m_currentFrameNumber) + n) % kTimeStampHistorySize;
125 return m_timeStampHistory[desiredIndex];
128 } // namespace cc