[Webkit-unassigned] [Bug 67564] New: CanvasPixelArray should be implemented as a Uint8Array

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Sat Sep 3 09:23:45 PDT 2011


https://bugs.webkit.org/show_bug.cgi?id=67564

           Summary: CanvasPixelArray should be implemented as a Uint8Array
           Product: WebKit
           Version: 528+ (Nightly build)
          Platform: All
        OS/Version: All
            Status: UNCONFIRMED
          Severity: Enhancement
          Priority: P5
         Component: Canvas
        AssignedTo: webkit-unassigned at lists.webkit.org
        ReportedBy: jhuckaby at gmail.com
                CC: mdelaney at apple.com


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

-- 
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.



More information about the webkit-unassigned mailing list