Director users a low-pass filter to display the FPS

FPS is more stable. Uses a 5% low-pass filter
This commit is contained in:
Ricardo Quesada 2014-11-26 13:31:44 -08:00
parent 45f57aa63c
commit 1361f2c619
6 changed files with 39 additions and 21 deletions

View File

@ -117,7 +117,7 @@ bool Director::init(void)
_accumDt = 0.0f; _accumDt = 0.0f;
_frameRate = 0.0f; _frameRate = 0.0f;
_FPSLabel = _drawnBatchesLabel = _drawnVerticesLabel = nullptr; _FPSLabel = _drawnBatchesLabel = _drawnVerticesLabel = nullptr;
_totalFrames = _frames = 0; _totalFrames = 0;
_lastUpdate = new struct timeval; _lastUpdate = new struct timeval;
// paused ? // paused ?
@ -430,7 +430,13 @@ void Director::setNextDeltaTimeZero(bool nextDeltaTimeZero)
{ {
_nextDeltaTimeZero = nextDeltaTimeZero; _nextDeltaTimeZero = nextDeltaTimeZero;
} }
//
// FIXME TODO
// Matrix code MUST NOT be part of the Director
// MUST BE moved outide.
// Why the Director must have this code ?
//
void Director::initMatrixStack() void Director::initMatrixStack()
{ {
while (!_modelViewMatrixStack.empty()) while (!_modelViewMatrixStack.empty())
@ -1069,22 +1075,26 @@ void Director::showStats()
{ {
static unsigned long prevCalls = 0; static unsigned long prevCalls = 0;
static unsigned long prevVerts = 0; static unsigned long prevVerts = 0;
static float prevDeltaTime = 0.016; // 60FPS
static const float FPS_FILTER = 0.05;
++_frames;
_accumDt += _deltaTime; _accumDt += _deltaTime;
if (_displayStats && _FPSLabel && _drawnBatchesLabel && _drawnVerticesLabel) if (_displayStats && _FPSLabel && _drawnBatchesLabel && _drawnVerticesLabel)
{ {
char buffer[30]; char buffer[30];
float dt = _deltaTime * FPS_FILTER + (1-FPS_FILTER) * prevDeltaTime;
prevDeltaTime = dt;
// Probably we don't need this anymore since
// the framerate is using a low-pass filter
// to make the FPS stable
if (_accumDt > CC_DIRECTOR_STATS_INTERVAL) if (_accumDt > CC_DIRECTOR_STATS_INTERVAL)
{ {
_frameRate = _frames / _accumDt; sprintf(buffer, "%.1f / %.3f", 1/dt, _secondsPerFrame);
_frames = 0;
_accumDt = 0;
sprintf(buffer, "%.1f / %.3f", _frameRate, _secondsPerFrame);
_FPSLabel->setString(buffer); _FPSLabel->setString(buffer);
_accumDt = 0;
} }
auto currentCalls = (unsigned long)_renderer->getDrawnBatches(); auto currentCalls = (unsigned long)_renderer->getDrawnBatches();
@ -1101,8 +1111,8 @@ void Director::showStats()
prevVerts = currentVerts; prevVerts = currentVerts;
} }
Mat4 identity = Mat4::IDENTITY;
Mat4 identity = Mat4::IDENTITY;
_drawnVerticesLabel->visit(_renderer, identity, 0); _drawnVerticesLabel->visit(_renderer, identity, 0);
_drawnBatchesLabel->visit(_renderer, identity, 0); _drawnBatchesLabel->visit(_renderer, identity, 0);
_FPSLabel->visit(_renderer, identity, 0); _FPSLabel->visit(_renderer, identity, 0);
@ -1111,10 +1121,16 @@ void Director::showStats()
void Director::calculateMPF() void Director::calculateMPF()
{ {
static float prevSecondsPerFrame = 0;
static const float MPF_FILTER = 0.05;
struct timeval now; struct timeval now;
gettimeofday(&now, nullptr); gettimeofday(&now, nullptr);
_secondsPerFrame = (now.tv_sec - _lastUpdate->tv_sec) + (now.tv_usec - _lastUpdate->tv_usec) / 1000000.0f; _secondsPerFrame = (now.tv_sec - _lastUpdate->tv_sec) + (now.tv_usec - _lastUpdate->tv_usec) / 1000000.0f;
_secondsPerFrame = _secondsPerFrame * MPF_FILTER + (1-MPF_FILTER) * prevSecondsPerFrame;
prevSecondsPerFrame = _secondsPerFrame;
} }
// returns the FPS image data pointer and len // returns the FPS image data pointer and len

View File

@ -461,7 +461,6 @@ protected:
/* How many frames were called since the director started */ /* How many frames were called since the director started */
unsigned int _totalFrames; unsigned int _totalFrames;
unsigned int _frames;
float _secondsPerFrame; float _secondsPerFrame;
/* The running scene */ /* The running scene */

View File

@ -535,13 +535,13 @@ void TextWritePlist::onEnter()
auto loadDict = __Dictionary::createWithContentsOfFile(fullPath.c_str()); auto loadDict = __Dictionary::createWithContentsOfFile(fullPath.c_str());
auto loadDictInDict = (__Dictionary*)loadDict->objectForKey("dictInDict, Hello World"); auto loadDictInDict = (__Dictionary*)loadDict->objectForKey("dictInDict, Hello World");
auto boolValue = (__String*)loadDictInDict->objectForKey("bool"); auto boolValue = (__String*)loadDictInDict->objectForKey("bool");
CCLOG("%s",boolValue->getCString()); log("%s",boolValue->getCString());
auto floatValue = (__String*)loadDictInDict->objectForKey("float"); auto floatValue = (__String*)loadDictInDict->objectForKey("float");
CCLOG("%s",floatValue->getCString()); log("%s",floatValue->getCString());
auto intValue = (__String*)loadDictInDict->objectForKey("integer"); auto intValue = (__String*)loadDictInDict->objectForKey("integer");
CCLOG("%s",intValue->getCString()); log("%s",intValue->getCString());
auto doubleValue = (__String*)loadDictInDict->objectForKey("double"); auto doubleValue = (__String*)loadDictInDict->objectForKey("double");
CCLOG("%s",doubleValue->getCString()); log("%s",doubleValue->getCString());
} }

View File

@ -185,10 +185,9 @@ bool UIPageViewButtonTest::init()
return false; return false;
} }
void UIPageViewButtonTest::onButtonClicked(Ref* pSender, Widget::TouchEventType type) void UIPageViewButtonTest::onButtonClicked(Ref* sender, Widget::TouchEventType type)
{ {
Button *btn = (Button*)pSender; log("button %s clicked", static_cast<Button*>(sender)->getName().c_str());
CCLOG("button %s clicked", btn->getName().c_str());
} }

View File

@ -3,7 +3,8 @@
void RefPtrTest::onEnter() void RefPtrTest::onEnter()
{ {
UnitTestDemo::onEnter(); UnitTestDemo::onEnter();
#if DEBUG
// TEST(constructors) // TEST(constructors)
{ {
// Default constructor // Default constructor
@ -313,6 +314,9 @@ void RefPtrTest::onEnter()
CC_ASSERT(theString->getReferenceCount() == 2); CC_ASSERT(theString->getReferenceCount() == 2);
CC_ASSERT(theString->compare("Hello world!") == 0); CC_ASSERT(theString->compare("Hello world!") == 0);
} }
#else
log("RefPtr tests are not executed in release mode");
#endif
} }
std::string RefPtrTest::subtitle() const std::string RefPtrTest::subtitle() const

View File

@ -697,7 +697,8 @@ void ValueTest::constFunc(const Value& value) const
// UTFConversionTest // UTFConversionTest
static const int TEST_CODE_NUM = 11; // FIXME: made as define to prevent compile warnings in release mode. Better is to be a `const static int`
#define TEST_CODE_NUM 11
static const char16_t __utf16Code[] = static const char16_t __utf16Code[] =
{ {
@ -818,8 +819,7 @@ static void doUTFConversion()
CCASSERT(StringUtils::getCharacterCountInUTF8String(originalUTF8) == TEST_CODE_NUM, "StringUtils::getCharacterCountInUTF8String failed"); CCASSERT(StringUtils::getCharacterCountInUTF8String(originalUTF8) == TEST_CODE_NUM, "StringUtils::getCharacterCountInUTF8String failed");
//--------------------------- //---------------------------
int lastIndex = StringUtils::getIndexOfLastNotChar16(vec3, 0x2009); CCASSERT(StringUtils::getIndexOfLastNotChar16(vec3, 0x2009) == (vec1.size()-1), "StringUtils::getIndexOfLastNotChar16 failed");
CCASSERT(lastIndex == (vec1.size()-1), "StringUtils::getIndexOfLastNotChar16 failed");
//--------------------------- //---------------------------
CCASSERT(originalUTF16.length() == TEST_CODE_NUM, "The length of the original utf16 string isn't equal to TEST_CODE_NUM"); CCASSERT(originalUTF16.length() == TEST_CODE_NUM, "The length of the original utf16 string isn't equal to TEST_CODE_NUM");