i use requestAnimationFrame
in a js webgl project where i change the pixel color from black to white on each frame by accessing a texture that contains the content of the last frame ) but the framerate exceeds the Hz of my monitor and the flickering is inconsistent.
also i calculate the fps with the help of window.performance.now()
and the framerate value looks like
n_fps: 200
n_fps: 333.3333333333333
n_fps: 250
i thought the requestAnimationFrame
should sync the function call with the framerate of my monitor which is set to 239.96hz, but the flickering is inconsistent and the framerate sometimes exceeds 240fps, i cant figure out why but i suspect it has to do with v-sync.
Here some specs
OS
Distributor ID: Ubuntu
Description: Pop!_OS 22.04 LTS
GPU
lshw -c video
WARNING: you should run this program as super-user.
*-display
description: VGA compatible controller
product: Ellesmere [Radeon RX 470/480/570/570X/580/580X/590]
Monitor settings
xrandr –verbose
DisplayPort-0 connected primary 1920×1080+0+1200
…
TearFree: on
supported: off, on, auto
…
the important part of my js code looks like this
//...
const gl = canvas.getContext(
'webgl2',
{
desynchronized: false, //trying to force vsync?
}
);
///...
function render() {
nid = requestAnimationFrame(render);
let n_ts_ms_now = window.performance.now();
let n_ms_delta = n_ts_ms_now - n_ts_ms;
// console.log(n_ms_delta)
console.log(`n_fps: ${1000/n_ms_delta})`);
n_ts_ms = n_ts_ms_now;
n += 1;
// if(n_ms_delta > n_ms_max){
const nextTextureIndex = 1 - currentTextureIndex;
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffers[nextTextureIndex]);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.useProgram(program);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, textures[currentTextureIndex]);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
// Swap textures
currentTextureIndex = nextTextureIndex;
// Render to the canvas
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.bindTexture(gl.TEXTURE_2D, textures[currentTextureIndex]);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
console.log(n)
// }
}
```
what i tried:
- manually forcing/setting vsync with this command `xrandr --output DisplayPort-0 --set TearFree on`
- running chrome and firefox with vblank_mode=1 `vblank_mode=1 google-chrome` and then
when i manually throttle the fps (commented out code) the flickering looks consistent.