Re: [whatwg] Counterproposal for canvas in workers

On Thu, Oct 17, 2013 at 5:14 PM, Rik Cabanier <cabanier@gmail.com> wrote:

> Compositors are often already threaded, so synchronizing a buffer flip
>> with the compositor doesn't seem too far out there.)
>>
>
> This proposal implies an extra buffer for the 2d context. My proposal
> doesn't require that so it's more memory efficient + you can draw in
> parallel.
>

You always need at least two buffers: a back-buffer for drawing and a
front-buffer for display (compositing).  Otherwise, as soon as you start
drawing the next frame, the old frame is gone, so you won't be able to
recomposite (on reflow, CSS filter changes, etc).  Double-buffering at a
minimum is pretty standard, even for native applications (with none of this
Web complexity in the way).

I think WorkerCanvas (as well as CanvasProxy that's in the spec today--this
isn't new to WorkerCanvas) allows full parallelism in drawing, both between
the script and the GPU and between the worker and the main UI thread.


> I don't remember "multiple workers accessing the same canvas" and I'm not
>> quite sure what it means.  I do remember "a single (WebGL) context
>> rendering to multiple canvases".  Is that what you're thinking of?
>>
>
> I went back over the history and that was indeed his use case.
>

That's a good use case, I've wanted to do that myself.  We haven't tried
very hard to fit it into the WorkerCanvas approach yet, and it may also be
that the best way to do that is orthogonal to the whole "canvas in workers"
use case.

The obvious approach is to add a new method on the context,
"attachToCanvas(Canvas or WorkerCanvas)", which would just take the context
and cause its output to be directed to a new Canvas (or WorkerCanvas),
probably clearing the contents of the new canvas as a side-effect.  (This
could be added to both CanvasRenderingContext2D and WebGLRenderingContext,
though I suspect this is only really useful for WebGL.  There's no
expensive resource loading with 2d canvas.)

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

I think that's by far the most straightforward approach for users.  Maybe
there are implementation issues that make this hard, but if so I think they
would apply to every approach to this use case (they're really all
different interfaces to the same functionality)...

-- 
Glenn Maynard

Received on Thursday, 17 October 2013 23:32:36 UTC