Skip to content
Advertisement

Does canvas context2d.drawImage( webglCanvas, 0, 0 ) block until a webgl is finished rendering?

I assume the answer is “no” from my testing but I thought I’d make sure.

I’m trying to draw / copy the contents from a WebGL canvas to a 2d canvas every frame and I want to know if I should wait until the WebGL context is finished drawing (which I can use gl.fenceSync to check) before calling it or if I can call drawImage immediately without worrying about a performance hit. Here’s how I would plan to use it using three.js as a stand in renderer:

const renderer = new THREE.WebGLRendeer();
const canvas = document.createElement( 'canvas' );
const ctx = canvas.getContext( '2d' );

// ...

function renderLoop() {

    renderer.render( camera, scene1 );
    ctx.drawImage( renderer.domElement, 0, 0 );

    renderer.render( camera, scene2 );
    ctx.drawImage( renderer.domElement, 0, 0 );

}

Is there a pitfall here I’m missing?

Thank you!


Edit

Per gman’s request here’s an example demonstrating that the function seems to not block by performing a lot of GPU work (50000 instanced cubes with no depth write) before calling drawImage. The drawImage functions takes the same amount of time whether there is one cube or 50000 cubes and whether it’s called before or after render() which leads me to believe drawImage does not block. Tested on a 2017 Mac laptop with latest Chrome:

https://jsfiddle.net/sL9npto6/

Advertisement

Answer

Does canvas context2d.drawImage( webglCanvas, 0, 0 ) block until a webgl is finished rendering?

Yes, it effectively blocks

The last example on this page does exactly what your render loop shows.

If you have some example that you think shows otherwise make a minimal repo and post it a snippet

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement