Re: [whatwg] Canvas in workers

On Fri, Oct 18, 2013 at 2:06 PM, Kenneth Russell <kbr@google.com> wrote:

> Capturing Glenn Maynard's feedback from the other thread started by
> Rik Cabanier, Glenn made a good point that there needs to be a way to
> explicitly deallocate the ImageBitmap. Otherwise, the JavaScript
> objects will have to be garbage collected before the GPU resource
> (texture) it references can be freed, and that will not work -- GPU
> resources will quickly pile up.
>

I'd like to hear thoughts on the "context.attachToCanvas" approach.  I
think it has important advantages over ImageBitmap:

- ImageBitmap requires the user to call close().  If the user forgets, or
doesn't know, or misses it in some code paths, the problems caused aren't
obvious.  Worse, they may only appear in some implementations and not
others, depending on GC strategies.  attachToCanvas doesn't need cleanup in
the first place, which is a nicer solution--there's nothing for the user to
get wrong.
- If you're rendering in a worker and the eventual target is in the main
thread, the worker needs to be careful to not start rendering again until
the main thread has assigned the ImageBitmap to where it wants it, and
called .close().  You'd need to send a message back to the worker going
"okay, you can continue now".  Otherwise, you'd start rendering before a
buffer has been freed up for reuse, and end up creating more backbuffers
than you intended (which matters for large screens).  This seems easy to
get wrong, and attachToCanvas doesn't have this problem.
- With ImageBitmap, you need to create a helper canvas, then each time you
render to a new target, you need to resize the canvas to match where it'll
eventually go, so the resulting ImageBitmap is the size of its
destination.  (This may also need to be carefully optimized, so the
implementation doesn't actually resize the backing store every time its
size changes.)  With attachToCanvas, you just size both canvases normally
once, and switch between them with a single function call.
- attachToCanvas matches the way Canvas works today: you create a Canvas,
put it in the document (if it's for display), and render to it.  For two
canvases, you'd just add a second Canvas, and toggle as needed.  With
ImageBitmap, you have to restructure everything as soon as you want a
second canvas, since you'd want to have a single offscreen Canvas for
rendering, and to have <img> elements in the document instead of canvases.

Here's the example from the other thread to consolidate the discussion.  If
you're in a worker, canvas and canvas2 can both be WorkerCanvases posted
from the main thread or created directly:

var canvas = document.querySelector(".canvas1");
var gl = canvas.getContext("webgl");
loadExpensiveResources(gl);
drawStuff(gl);
var canvas2 = document.querySelector(".canvas2");
gl.attachToCanvas(canvas2);
drawStuff(gl); // don't need to loadExpensiveResources again

-- 
Glenn Maynard

Received on Friday, 18 October 2013 23:29:12 UTC