Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zero-copy API for reading or writing pixels directly on the canvas surface? #910

Open
pcordes opened this issue Apr 26, 2017 · 1 comment

Comments

@pcordes
Copy link

pcordes commented Apr 26, 2017

Instead of creating an RGBA ImageData object and calling putImageData, it would be faster to store pixels directly onto the canvas. Copying is pretty fast + cheap, but not free by any means.


Or for another use-case, I want to draw some text + xy axes on a canvas with some existing pure-JS code, then copy those pixels to an indexed image format (uint8_t pixels + a palette), using native code with AVX2 SIMD, mapping alpha=0 to 0 and alpha=255 to 1. (Then I use another part of that array as uint8_t histogram bins, generate an appropriate palette, and feed it to a PNG encoder. If we were writing this from scratch now, we might use a different graphics library with good support for indexed images, but this is the path of least resistance).

canvas.ToBuffer("raw") makes a copy, instead of returning an ArrayBuffer reference to the actual underlying canvas->surface() or something. The interesting pixels are in a small known area of the canvas, so that's a huge amount of wasted work (and cache footprint).

Ideally there'd be an API with even more room for shooting yourself in the foot that lets you read/write the canvas surface directly. Or maybe just read but not write, if JS can enforce that for a zero-copy reference. (I barely know JS; in C++ you'd do this by returning a const uint32_t* which lets the caller break things by casting away the const, but only if they do it on purpose).


If zero-copy isn't feasible or desirable, maybe we can have an API for efficiently copying just some selected parts of the canvas so I can copy just the left and bottom edges (into two separate rectangles)?

getImageData can copy, but it has to format-convert and undo the premultiplied alpha. The current implementation is also much slower than necessary (#909), but it still can't be as fast as just copying. Especially for the special case of dst width = the full canvas width, so a single memcpy can get all the requested rows.


For my use-case, I'd be happy with a C++-only API. I mostly want to get at the raw pixels with native code anyway.

@zbjornson
Copy link
Collaborator

zbjornson commented May 3, 2017

This seems to be addressed by #678 (JS), but that PR needs some more design work. Sounds like it already works for C++ (#369).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants