Bug 67564
Summary: | CanvasPixelArray should be implemented as a Uint8Array | ||
---|---|---|---|
Product: | WebKit | Reporter: | Joseph Huckaby <jhuckaby> |
Component: | Canvas | Assignee: | Nobody <webkit-unassigned> |
Status: | RESOLVED DUPLICATE | ||
Severity: | Enhancement | CC: | guanqun.lu, ian, mdelaney7 |
Priority: | P5 | ||
Version: | 528+ (Nightly build) | ||
Hardware: | All | ||
OS: | All |
Joseph Huckaby
Currently, when using a Canvas and createImageData() or getImageData() are called, an "ImageData" object is returned containing the requested pixels as an array in the "data" property. But the pixel array is implemented as a "CanvasPixelArray" object. This should instead be implemented as a Uint8Array, backed by an ArrayBuffer.
CanvasPixelData is theoretically already an "accelerated" array, and was introduced before typed array classes. But returning an actual Uint8Array has a number of important advantages. For one, it standardizes accelerated arrays to always use the typed array system, instead of having a strange one-off "CanvasPixelData" class. But most importantly, it would allow developers to cast the array as something else, like a Uint32Array (i.e. create another "view" of the ArrayBuffer).
Right now, setting a single canvas pixel involves 4 separate operations, because the "red", "green", "blue" and "alpha" channels are each separate elements in the array. But if the pixel array could be cast to a Uint32Array, then each pixel would take up only one element, and setting pixels could effectively be four times faster (depending on what the developer is doing). For example, you could pre-calculate 32-bit pixel values using bit-shift operations, then plop them into the Uint32Array 4 times faster than using an 8-bit array.
Example:
imageData = context.getImageData( 0, 0, 640, 480 );
var buffer = imageData.data.buffer; // get ArrayBuffer out of Uint8Array
var pixels = new Uint32Array( buffer ); // create Uint32Array view of same buffer
// precalculate a "white" opaque pixel as a 32-bit uint
var alpha = 255, blue = 255, green = 255, red = 255;
var pixel = (alpha) + (blue << 8) + (green << 16) + (red << 24);
// pixels.length is only 1/4 of the size it normally would be, so this should be very fast
for (var idx = 0, len = pixels.length; idx < len; idx++) {
pixels[idx] = pixel;
}
context.putImageData( imageData, 0, 0 );
This change should theoretically not have any adverse affects, and all existing JavaScript canvas code should continue to work, because right now "CanvasPixelArray" is effectively just an accelerated array of 8-bit unsigned integers. I am merely suggesting changing the underlying implementation to a real Uint8Array, so the data can be type cast if desired. If the developer doesn't cast, it will continue to work exactly the same as it does now.
This would be extremely useful for Canvas based games.
Thanks for your time!
- Joe
Attachments | ||
---|---|---|
Add attachment proposed patch, testcase, etc. |
Joseph Huckaby
FYI, this has now shown up on the WHATWG:
http://html5.org/tools/web-apps-tracker?from=6558&to=6559
And Firefox 6 has implemented it.
Ian 'Hixie' Hickson
*** This bug has been marked as a duplicate of bug 82802 ***