| OLD | NEW |
| 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 "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "cc/frame_rate_counter.h" | 7 #include "cc/frame_rate_counter.h" |
| 8 | 8 |
| 9 #include <cmath> | 9 #include <cmath> |
| 10 | 10 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 ++m_droppedFrameCount; | 63 ++m_droppedFrameCount; |
| 64 } | 64 } |
| 65 | 65 |
| 66 void FrameRateCounter::markEndOfFrame() | 66 void FrameRateCounter::markEndOfFrame() |
| 67 { | 67 { |
| 68 m_currentFrameNumber += 1; | 68 m_currentFrameNumber += 1; |
| 69 } | 69 } |
| 70 | 70 |
| 71 bool FrameRateCounter::isBadFrameInterval(base::TimeDelta intervalBetweenConsecu
tiveFrames) const | 71 bool FrameRateCounter::isBadFrameInterval(base::TimeDelta intervalBetweenConsecu
tiveFrames) const |
| 72 { | 72 { |
| 73 double delta = intervalBetweenConsecutiveFrames.InSecondsF(); |
| 73 bool schedulerAllowsDoubleFrames = !Proxy::hasImplThread(); | 74 bool schedulerAllowsDoubleFrames = !Proxy::hasImplThread(); |
| 74 bool intervalTooFast = schedulerAllowsDoubleFrames && intervalBetweenConsecu
tiveFrames.InSecondsF() < kFrameTooFast; | 75 bool intervalTooFast = schedulerAllowsDoubleFrames ? delta < kFrameTooFast :
delta <= 0.0; |
| 75 bool intervalTooSlow = intervalBetweenConsecutiveFrames.InSecondsF() > kFram
eTooSlow; | 76 bool intervalTooSlow = delta > kFrameTooSlow; |
| 76 return intervalTooFast || intervalTooSlow; | 77 return intervalTooFast || intervalTooSlow; |
| 77 } | 78 } |
| 78 | 79 |
| 79 bool FrameRateCounter::isBadFrame(int frameNumber) const | 80 bool FrameRateCounter::isBadFrame(int frameNumber) const |
| 80 { | 81 { |
| 81 return isBadFrameInterval(frameInterval(frameNumber)); | 82 return isBadFrameInterval(frameInterval(frameNumber)); |
| 82 } | 83 } |
| 83 | 84 |
| 84 void FrameRateCounter::getAverageFPSAndStandardDeviation(double& averageFPS, dou
ble& standardDeviation) const | 85 void FrameRateCounter::getAverageFPSAndStandardDeviation(double& averageFPS, dou
ble& standardDeviation) const |
| 85 { | 86 { |
| 86 int frame = m_currentFrameNumber - 1; | 87 int frameNumber = m_currentFrameNumber - 1; |
| 88 int frameCount = 0; |
| 89 double fpsVarianceNumerator = 0; |
| 90 |
| 87 averageFPS = 0; | 91 averageFPS = 0; |
| 88 int averageFPSCount = 0; | 92 standardDeviation = 0; |
| 89 double fpsVarianceNumerator = 0; | |
| 90 | 93 |
| 91 // Walk backwards through the samples looking for a run of good frame | 94 // Walk backwards through the samples looking for a run of good frame |
| 92 // timings from which to compute the mean and standard deviation. | 95 // timings from which to compute the mean and standard deviation. |
| 93 // | 96 // |
| 94 // Slow frames occur just because the user is inactive, and should be | 97 // 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 | 98 // 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 | 99 // 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 | 100 // the first few swapbuffers happen instantly which skews the statistics |
| 98 // too much for short lived animations. | 101 // too much for short lived animations. |
| 99 // | 102 // |
| 100 // isBadFrame encapsulates the frame too slow/frame too fast logic. | 103 // isBadFrame encapsulates the frame too slow/frame too fast logic. |
| 101 while (1) { | 104 |
| 102 if (!isBadFrame(frame)) { | 105 // Go through all available historical data. |
| 103 averageFPSCount++; | 106 while (frameIndex(frameNumber) != frameIndex(m_currentFrameNumber) && frameN
umber >= 0) { |
| 104 base::TimeDelta secForLastFrame = m_timeStampHistory[frameIndex(fram
e)] - | 107 base::TimeDelta delta = frameInterval(frameNumber); |
| 105 m_timeStampHistory[frameIndex(fram
e - 1)]; | 108 |
| 106 double x = 1.0 / secForLastFrame.InSecondsF(); | 109 if (!isBadFrameInterval(delta)) { |
| 110 frameCount++; |
| 111 double x = 1.0 / delta.InSecondsF(); |
| 107 double deltaFromAverage = x - averageFPS; | 112 double deltaFromAverage = x - averageFPS; |
| 108 // Change with caution - numerics. http://en.wikipedia.org/wiki/Stan
dard_deviation | 113 // Change with caution - numerics. http://en.wikipedia.org/wiki/Stan
dard_deviation |
| 109 averageFPS = averageFPS + deltaFromAverage / averageFPSCount; | 114 averageFPS += deltaFromAverage / frameCount; |
| 110 fpsVarianceNumerator = fpsVarianceNumerator + deltaFromAverage * (x
- averageFPS); | 115 fpsVarianceNumerator += deltaFromAverage * (x - averageFPS); |
| 111 } | 116 } else if (frameCount) |
| 112 if (averageFPSCount && isBadFrame(frame)) { | |
| 113 // We've gathered a run of good samples, so stop. | 117 // We've gathered a run of good samples, so stop. |
| 114 break; | 118 break; |
| 115 } | 119 frameNumber--; |
| 116 --frame; | |
| 117 if (frameIndex(frame) == frameIndex(m_currentFrameNumber) || frame < 0)
{ | |
| 118 // We've gone through all available historical data, so stop. | |
| 119 break; | |
| 120 } | |
| 121 } | 120 } |
| 122 | 121 |
| 123 standardDeviation = sqrt(fpsVarianceNumerator / averageFPSCount); | 122 if (frameCount) |
| 123 standardDeviation = sqrt(fpsVarianceNumerator / frameCount); |
| 124 } | 124 } |
| 125 | 125 |
| 126 base::TimeTicks FrameRateCounter::timeStampOfRecentFrame(int n) | 126 base::TimeTicks FrameRateCounter::timeStampOfRecentFrame(int n) const |
| 127 { | 127 { |
| 128 DCHECK(n >= 0); | 128 DCHECK(n >= 0); |
| 129 DCHECK(n < kTimeStampHistorySize); | 129 DCHECK(n < kTimeStampHistorySize); |
| 130 int desiredIndex = (frameIndex(m_currentFrameNumber) + n) % kTimeStampHistor
ySize; | 130 int desiredIndex = (frameIndex(m_currentFrameNumber) + n) % kTimeStampHistor
ySize; |
| 131 return m_timeStampHistory[desiredIndex]; | 131 return m_timeStampHistory[desiredIndex]; |
| 132 } | 132 } |
| 133 | 133 |
| 134 } // namespace cc | 134 } // namespace cc |
| 135 | 135 |
| OLD | NEW |