junov / OffscreenCanvasAnimation

Proposal for driving animations in a Worker for OffscreenCanvas
Other
6 stars 5 forks source link

Understanding the multiple canvas solution #6

Open greggman opened 6 years ago

greggman commented 6 years ago

I'm hoping OffscreenCanvas allows one WebGL context to be used to efficiently update multiple canvases and it's not clear to me how that is solved in the current proposal.

Unrelated to the proposal two solutions come to mind.

  1. A callback for each canvas

    In this case when you get the callback the WebGLContext is setup to render to current canvas

  2. A way to manually bind a WebGLContext to any canvas.

Note that currently MDN lists code like this as the way to draw to multiple canvases

var one = document.getElementById("one").getContext("bitmaprenderer"); 
var two = document.getElementById("two").getContext("bitmaprenderer");

var offscreen = new OffscreenCanvas(256, 256);
var gl = offscreen.getContext('webgl');

// ... some drawing for the first canvas using the gl context ...

// Commit rendering to the first canvas
var bitmapOne = offscreen.transferToImageBitmap();
one.transferImageBitmap(bitmapOne);

// ... some more drawing for the second canvas using the gl context ...

// Commit rendering to the second canvas 
var bitmapTwo = offscreen.transferToImageBitmap();
two.transferImageBitmap(bitmapTwo);

But that seems likely to be super inefficient unless I'm missing something. In order to be able to draw to multiple canvases following the MDN style API you end up needed to set the size your rendering to. In other world you'd have to do this

offscreen.width = widthOfOne;       // EXPENSIVE
offscreen.height = heightOfOne;    // EXPENSIVE
renderSceneForOne();
var bitmapOne = offscreen.transferToImageBitmap();
one.transferImageBitmap(bitmapOne);

offscreen.width = widthOfTwo;       // EXPENSIVE
offscreen.height = heightOfTwo;    // EXPENSIVE
renderSceneForTwo();
var bitmapTwo = offscreen.transferToImageBitmap();
two.transferImageBitmap(bitmapTwo);

Where as if you can either bind to the canvas OR get callback then WebGL knows what canvas it's being asked to render to and if every canvas is double buffered there are no expensive operations.

Maybe there are other solutions? Or maybe the current proposal does this already?