Re: Using ArrayBuffer as payload for binary data to/from Web Workers

On Mon, Mar 7, 2011 at 9:07 PM, Boris Zbarsky <bzbarsky@mit.edu> wrote:

> On 3/7/11 8:55 PM, Glenn Maynard wrote:
>
>> I'd expect CanvasPixelArray to allow optimizations that ArrayBuffer
>> doesn't, since the implementation can use the native surface format,
>> translating to RGBA for the script transparently.  This can matter for
>> streaming textures to OpenGL/D3D, too; creating BGRA textures on nVidia
>> hardware is typically much faster than RGBA ones.
>>
>
> But modifying the ImageData is not supposed to modify what the graphics
> card sees, right?  So you have to make a copy here on putImageData (or on
> the next write to the image data), right?


Right, either way you need to make a copy when you send the data back to the
canvas.  But, if the surface format of the memory buffer matches a native
format of the graphics card, the copy is very fast--probably a DMA, for
hardware-accelerated surfaces.  (The exact mechanics of this are hidden
behind the drivers, of course, but that's what it looks like in my
experience.)  For example, nVidia cards typically are BGRA natively, and if
you give them RGBA with OpenGL it needs to be converted before (or as) it's
copied, which is much slower.

(Of course, CanvasPixelData itself always has to *appear* RGBA, but that
doesn't mean the backing store needs to actually be RGBA.)

 I don't recall if this has been brought up: are there cases where
>> explicit zero-copy messaging is better than transparent copy-on-write?
>>
>
> Transparent copy on write requires that each write do a "should I copy?"
> check, right?
>

Yeah.  The question is probably whether that check can be moved out of inner
loops.  It couldn't be if function calls are made that might have
side-effects to cause a private object to become a COW object (eg. non-pure
functions).

For page-aligned buffers, an implementation could optimize these checks away
entirely by marking the buffer read-only, so if a write is made it'll raise
an exception that the engine can catch.

> Yes. Copy on write does not efficiently handle the case where large
> amounts of data are continually produced by workers and posted to the
> main thread for display. Each time the worker posts a block of data to
> the main thread, the next time it attempts to update its version of
> the block for the next iteration, a copy will need to be made so the
> main thread's version appears immutable.

But how is this any different than just throwing away the ArrayBuffer and
creating a fresh one after each postMessage?

I guess one issue is that double-buffering would run into GC problems.  With
explicit zero-copy semantics, you can maintain two buffers: one for the
worker as it creates the next frame, and one for the main thread as it
updates the canvas.  On each frame, the worker posts its new frame to the
main thread, and the main thread posts the old buffer back to the worker.
(This avoids reallocating large buffers every frame.)  That doesn't work
with COW, since there's no way to deterministically throw away the old
buffer so it knows that it doesn't need to make a copy on the other side.

That could be dealt with by adding methods like ArrayBuffer.discard(),
though...

-- 
Glenn Maynard

Received on Tuesday, 8 March 2011 03:12:51 UTC