ludolover
ludolover

Reputation: 21

What's different with requestAnimationFrame's timestamp at various / higher refresh rates?

So I have a running loop:

var FRAME_TIME = 1000 / 60;
var lastTime = 0;
var fpsTime = 0;
var fps = 0;

function mainLoop(timestamp) {
    if (timestamp - lastTime >= FRAME_TIME) {
        fps++;
        lastTime = timestamp;
    }

    if (timestamp - fpsTime >= 1000) {
        console.log(fps);
        fps = 0;
        fpsTime = timestamp;
    }
    requestAnimationFrame(mainLoop);
}

Now, when running with monitor refresh at 60, I get "60" printed in console as expected. But, when running with resfresh at 144, I get "48" = 1/3 of the refresh.

Why? Time is time, right...?

Upvotes: 0

Views: 105

Answers (2)

Bergi
Bergi

Reputation: 664297

The if (timestamp - lastTime >= FRAME_TIME) fps++; is no good. That means it does not count every frame - it counts whenever FRAME_TIME has passed. At 144 fps, that means there are two frames (at 7 ms and 14 ms) before you count the next frame at 21 ms that is after the expected FRAME_TIME for 60 fps - 17 ms. That comes down to only every third frame being counted - exactly what you experience.

To fix it, do fps++ on every invocation:

var fpsTime = 0;
var fps = 0;

function mainLoop(timestamp) {
    fps++;
    if (timestamp - fpsTime >= 1000) {
        console.log(fps);
        fps = 0;
        fpsTime = timestamp;
    }
    requestAnimationFrame(mainLoop);
}
mainLoop(performance.now());

Upvotes: 1

Ben Abraham
Ben Abraham

Reputation: 482

So I believe the main issue comes down to these lines.

if (timestamp - lastTime >= FRAME_TIME) {
    fps++;
    lastTime = timestamp;
}

What that is saying is if our current frame time (timestamp - lastTime) is OVER (or equal) to that of an 'ideal' frame (1000ms / 60 [144]), then we count it, otherwise, it's not counted.

If this function is called (once and only once) every frame, then you don't need an if statement, you can simply do "fps++" every frame, because it will be reset by the 1 second counter.

Upvotes: 2

Related Questions