CCFrameRateCounter.cpp [plain text]
#include "config.h"
#if USE(ACCELERATED_COMPOSITING)
#include "CCFrameRateCounter.h"
#include "CCProxy.h"
#include <wtf/CurrentTime.h>
namespace WebCore {
const double CCFrameRateCounter::kFrameTooFast = 1.0 / 70.0; const double CCFrameRateCounter::kFrameTooSlow = 1.0 / 12.0;
static inline int safeMod(int number, int modulus)
{
return (number + modulus) % modulus;
}
inline int CCFrameRateCounter::frameIndex(int frame) const
{
return safeMod(frame, kTimeStampHistorySize);
}
CCFrameRateCounter::CCFrameRateCounter()
: m_currentFrameNumber(1)
{
m_timeStampHistory[0] = currentTime();
m_timeStampHistory[1] = m_timeStampHistory[0];
for (int i = 2; i < kTimeStampHistorySize; i++)
m_timeStampHistory[i] = 0;
}
void CCFrameRateCounter::markBeginningOfFrame(double timestamp)
{
m_timeStampHistory[frameIndex(m_currentFrameNumber)] = timestamp;
}
void CCFrameRateCounter::markEndOfFrame()
{
m_currentFrameNumber += 1;
}
bool CCFrameRateCounter::isBadFrameInterval(double intervalBetweenConsecutiveFrames) const
{
bool schedulerAllowsDoubleFrames = !CCProxy::hasImplThread();
bool intervalTooFast = schedulerAllowsDoubleFrames && intervalBetweenConsecutiveFrames < kFrameTooFast;
bool intervalTooSlow = intervalBetweenConsecutiveFrames > kFrameTooSlow;
return intervalTooFast || intervalTooSlow;
}
bool CCFrameRateCounter::isBadFrame(int frameNumber) const
{
double delta = m_timeStampHistory[frameIndex(frameNumber)] -
m_timeStampHistory[frameIndex(frameNumber - 1)];
return isBadFrameInterval(delta);
}
void CCFrameRateCounter::getAverageFPSAndStandardDeviation(double& averageFPS, double& standardDeviation) const
{
int frame = m_currentFrameNumber - 1;
averageFPS = 0;
int averageFPSCount = 0;
double fpsVarianceNumerator = 0;
while (1) {
if (!isBadFrame(frame)) {
averageFPSCount++;
double secForLastFrame = m_timeStampHistory[frameIndex(frame)] -
m_timeStampHistory[frameIndex(frame - 1)];
double x = 1.0 / secForLastFrame;
double deltaFromAverage = x - averageFPS;
averageFPS = averageFPS + deltaFromAverage / averageFPSCount;
fpsVarianceNumerator = fpsVarianceNumerator + deltaFromAverage * (x - averageFPS);
}
if (averageFPSCount && isBadFrame(frame)) {
break;
}
--frame;
if (frameIndex(frame) == frameIndex(m_currentFrameNumber) || frame < 0) {
break;
}
}
standardDeviation = sqrt(fpsVarianceNumerator / averageFPSCount);
}
double CCFrameRateCounter::timeStampOfRecentFrame(int n)
{
ASSERT(n >= 0 && n < kTimeStampHistorySize);
int desiredIndex = (frameIndex(m_currentFrameNumber) + n) % kTimeStampHistorySize;
return m_timeStampHistory[desiredIndex];
}
}
#endif // USE(ACCELERATED_COMPOSITING)