高性能机器release版本会掉帧?

首先看看cocos的主循环,这里以application.mm作为实例,相信window平台应该差不多:

while (!glview->windowShouldClose())
{
lastTime = getCurrentMillSecond();

    director->mainLoop();
    glview->pollEvents();


    curTime = getCurrentMillSecond();
    if (curTime - lastTime < _animationInterval)
    {
        usleep(static_cast<useconds_t>((_animationInterval - curTime + lastTime)*1000));
    }
}

然后再看director->mainLoop();主要是调用了Director::drawScene();
高潮来了 我们看看Director::drawScene()这个方法:
// calculate “global” dt
calculateDeltaTime();

// skip one flame when _deltaTime equal to zero.
if(_deltaTime < FLT_EPSILON)
{
return;
}

if (_openGLView)
{
_openGLView->pollInputEvents();

}

前后都可以忽略了,关键是if(_deltaTime < FLT_EPSILON)这句判断要了老命,高端机上面的处理循环速度很快,结果反而造成了漏帧。

当然 最重要的还是 calculateDeltaTime();这个方法逻辑有问题:
void Director::calculateDeltaTime()
{
struct timeval now;

if (gettimeofday(&now, nullptr) != 0)
{

CCLOG(“error in gettimeofday”);
_deltaTime = 0;
return;
}

// new delta time. Re-fixed issue #1277
if (_nextDeltaTimeZero)
{
_deltaTime = 0;
_nextDeltaTimeZero = false;
}
else
{
_deltaTime = (now.tv_sec - _lastUpdate->tv_sec) + (now.tv_usec - _lastUpdate->tv_usec) / 1000000.0f;
_deltaTime = MAX(0, _deltaTime);
}

#if COCOS2D_DEBUG
// If we are debugging our code, prevent big delta time
if (_deltaTime > 0.2f)
{
_deltaTime = 1 / 60.0f;
}
#endif

*_lastUpdate = now;

}

可以看到在最后 *_lastUpdate = now;每次都把上次判断的时间更新了!!!!!!!
修改很简单,既然为了避免循环次数太多,造成手机发烫、耗电,那么再刷新时间的时候也需要判断一次:
*_lastUpdate = now;改为
if(_deltaTime >= FLT_EPSILON)
{
*_lastUpdate = now;
}

当然这样的改法还是会出现某些问题,但是至少不会因为高性能而掉帧。至于会出现的其他问题也可能只是我个人代码的问题,这里不表。