Having thought about this before, I wonder why we don’t use a producer/consumer model rather than a transfer of canvas ownership model?
A completely orthogonal idea (just my rough 2c after reading Gregg’s proposal), is to have an internal frame buffer accessible via a WorkerCanvas API which supports some set of canvas 2d/3d APIs as appropriate, and can “push” a completed frame onto a stack in the internal frame buffer. Thus the worker can produce frames as fast as desired.
On the document side, canvas gets a 3rd kind of context—a WorkerRemoteContext, which just offers the “pop” API to pop a frame from the internal frame buffer into the canvas.
Then you just add some basic signaling events on both ends of the frame buffer and you’re good (as far as synchronizing the worker with the document). The producer (in the worker) is free to produce multiple frames in advance (if desired), while the consumer is able to pop frames when available. You could even have the framebuffer depth configurable.
From: Gregg Tavares [mailto:gman@google.com]
Sent: Thursday, February 7, 2013 2:25 PM
To: Ian Hickson
Cc: Charles Pritchard; Web Applications Working Group WG
Subject: Re: exposing CANVAS or something like it to Web Workers
I put up a new proposal for canvas in workers
http://wiki.whatwg.org/wiki/CanvasInWorkers
Please take a look.
This proposal comes from offline discussions with representatives from the various browsers as well as input from the Google Maps team. I can post a summary here if you'd like but it might be easier to read the wiki
Looking forward to feedback.
On Tue, Jan 8, 2013 at 10:50 AM, Ian Hickson <ian@hixie.ch<mailto:ian@hixie.ch>> wrote:
On Wed, 2 Jan 2013, Gregg Tavares (社ç~T¨) wrote:
>
> Another issue as come up and that is one of being able
> to synchronize updates of a canvas in
> worker with changes in the main page.
For 2D, the intended solution is to just ship the ImageBitamp from the
worker canvas to the main thread via a MessagePort and then render it on
the canvas at the appropriate time.
I don't know how you would do it for WebGL.
> Similarly, let's say you have 2 canvases and are rendering to both in a
> worker. Does
>
> context1.commit();
> context2.commit();
>
> guarantee you'll see both commits together?
No, unfortunately not. There's no synchronisation between workers and the
main thread (by design, to prevent any possibility of deadlocks), and
there's not currently a batching API.
However, if this becomes a common problem (which we can determine by
seeing if we get bugs complaining about different parts of apps/games
seeming to slide around or generally be slightly out of sync, or if we see
a lot of authors shunting multiple ImageBitmap objects across MessagePort
channels) we can always add an explicit batching API to make this kind of
thing easy.
Note that in theory, for 2D at least, shunting ImageBitmaps across threads
can be as efficient as commit().
--
Ian Hickson U+1047E )\._.,--....,'``. fL
http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,.
Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'