W3C home > Mailing lists > Public > whatwg@whatwg.org > January 2013

Re: [whatwg] Canvas in Workers

From: Gregg Tavares <gman@google.com>
Date: Thu, 3 Jan 2013 17:06:49 -0800
Message-ID: <CAKZ+BNr2ihUeMr8Pw4eJOEzSWOoaBb5Cn3uzjzg1qkywTsPRZg@mail.gmail.com>
To: Ian Hickson <ian@hixie.ch>
Cc: Rick Waldron <waldron.rick@gmail.com>, Elliott Sprehn <esprehn@chromium.org>, WHAT Working Group <whatwg@whatwg.org>
So I've been thinking more about this and I'm wondering, for the time
being,
why have canvas.setContext and why expose the Canvas2DRenderingContext
constructor?

I'm assuming those ideas were influenced by the WebGL one context multiple
canvas
discussions but I have a feeling this issues are orthogonal to single
canvas single
context.

What if instead of "canvas.setContext" and "new Canvas2DRenderingContext()"
we
just have CanvasProxy and it has the same API as Canvas minus the
HTMLElement stuff?

Then you'd do this

   // main.html
   <canvas></canvas>
   <script>
    var canvas = document.getElementsByTagName('canvas')[0];
    var worker = new Worker('clock.js');
    var proxy = canvas.transferControlToProxy());
    worker.postMessage(proxy, [proxy]);
   </script>

   // clock.js worker
   onmessage = function (event) {
     var proxy = event.data;
     var ctx = proxy.getContext("2d");  // same API as Canvas
     setInterval(function () {
       context.clearRect(0, 0, context.width, context.height);
       context.fillText(0, 100, new Date());
       context.commit();
     }, 1000);
   };

That would mean for the simple case of single context in worker and single
canvas
nothing really changes. CanvasProxy is a proxy for the Canvas. The
CanvasProxy
can be passed anywhere the Canvas can currently be used (drawImage)

You can call proxy.toDataURL() etc...

That means we can solve the 1 context multiple canvases issue later making
this
a minimal api change?

Is there some reason that won't work?

There is some weirdness in that calling this in a worker

    someOtherCanvasProxy.drawImage(proxy)

Will give you different results than calling this in a main thread

    someOtherCanvas.drawImage(canvas);

Since the proxy is drawing to a different buffer than the canvas. commit()
still copies from the proxy to the canvas.

This direction though seems more forward compatible (or at least less
likely to conflict)
with whatever solutions comes up later for 1 context and multiple canvases.











On Thu, Jan 3, 2013 at 4:46 PM, Gregg Tavares <gman@google.com> wrote:

>
>
>
> On Tue, Dec 11, 2012 at 9:04 AM, Ian Hickson <ian@hixie.ch> wrote:
>
>> On Tue, 11 Dec 2012, Gregg Tavares (社ç~T¨) wrote:
>> >
>> > discussion seems to have died down here but I'd like to bring up another
>> > issue
>> >
>> > In WebGL land we have creation attributes on the drawingbuffer made for
>> a
>> > canvas. Example
>> >
>> >     gl = canvas.getContext("webgl", { preserveDrawingBuffer: false });
>> >
>> > We're working out the details on how to set those options for the case
>> > where we have 1 context and multiple canvases.
>> >
>> > The particular option above would apparently be a huge perf win for
>> > canvas 2d for mobile. Which suggests that whatever API is decided on it
>> > would be nice if it worked for both APIs the same.
>>
>> What does it do?
>>
>
> Effectively it makes the canvas double buffered.
>
> Right now by 2d canvases are effectively single buffered. At the
> appropriate time a copy
> of the canvas is made and passed to the compositor. This copy is slow,
> especially on
> mobile.
>
> Apple requested that for WebGL the default be for double buffering. When
> double buffered, when the canvas is composited (when the current
> JavaScript event exits)
> the canvas's buffer is given to the compositor and the canvas is given a
> new buffer (or
> an old one). That new buffer is cleared, meaning the contents is gone.
> It's up to the app to
> draw stuff into again. If nothing is drawn the compositor will continue to
> use the
> buffer it acquired earlier.
>
> In WebGL you can opt into the slower "copy" path. For Canvas 2D while the
> default
> has to remain the slow "copy" path it would be nice to be able to opt into
> the faster
> "swap" double buffered path.
>
>
>
>
>
>
>
>>
>> In the 2D canvas, whenever you bind to a new canvas, the context is reset
>> to its default state, the context's hit region list is reset, and the
>> context's bitmap is reset. The next time the context is flushed, the
>> canvas itself is always reset (since flushing the context causes the
>> bitmap and hit region list to be pushed to the canvas, replacing whatever
>> was there before).
>>
>> --
>> Ian Hickson               U+1047E                )\._.,--....,'``.    fL
>> http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
>> Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
>>
>
>
Received on Friday, 4 January 2013 01:07:14 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Wednesday, 30 January 2013 18:48:12 GMT