[whatwg] createImageData

Oliver Hunt oliver at apple.com
Tue May 13 16:45:03 PDT 2008

On May 13, 2008, at 4:28 PM, Vladimir Vukicevic wrote:

> On May 13, 2008, at 4:10 PM, Oliver Hunt wrote:
>>>> My experience implementing this in WebKit showed a pure byte  
>>>> array backing store was significantly faster than using boxed  
>>>> values.
>>> Faster for which operation, though?  The put, or the actual  
>>> manipulation?  It's a tradeoff, really; if you're doing limited  
>>> pixel manipulation, but lots of putImageData, you can optimize  
>>> that directly by just calling putImageData once to an offscreen  
>>> canvas and then blitting that with drawImage.  If you're doing  
>>> lots of pixel manipulation but only one putImageData, I guess you  
>>> can use a JS array for your intermediate ops to avoid the checking  
>>> overhead, and set the image data pixels all at once (though again  
>>> paying the checking penalty per pixel), but having cheap  
>>> putImageData.
>>> Throwing the error at putImageData time lets the implementation  
>>> optimize in whatever way is most convenient/performant (either at  
>>> pixel operation time by setting an error bit in the ImageData  
>>> object which is checked by putImageData, or at putImageData time),  
>>> and is (IMO) more flexible.. given that errors are an exceptional  
>>> case, I don't think the spec should force the checking per pixel.
>> I found it faster in general across quite a few tests.  I would  
>> argue that if you are using ImageData in a way that leads to you  
>> writing to the same pixel multiple times you should improve your  
>> algorithms (this is just the generic over painting issue).
> I dunno, some kind of iterative algorithm that you want to visualize  
> at random timesteps.  You could keep the output in a separate array  
> and copy over when you want to render it.

I'm not sure what you mean.  By my interpretation that would require  
more work when you validate on blit, because while you would not have  
to validate when you copy the invalidated region of your buffer into  
the ImageData buffer it would not need to be validated, but when you  
then go to blit the ImageData, putImageData *must* revalidate the  
entirety of the ImageData buffer (hmmm, i suppose the UA could try  
tracking dirty regions in the ImageData buffer to minimise  
revalidation? i suspect this would not be significantly better than  
just validating on every pixel put)

If you actually meant you were using the ImageData buffer as your  
working buffer then you would possibly be doing excessive  
revalidation, but in my experience such a case would be atypical (and  
we're more interested in the performance of the normal case vs. edge  
cases) and the cost of clamping, etc is dwarfed by the dispatch cost  
just to do the assignment (at least in WebKit) so i'm not sure there  
would a significant loss in performance anyway.

>> A very reall issue to consider though is the case where I've been  
>> very careful to only update those pixels that need to be updated.   
>> If the ImageData is not clamped, etc on put then *every* blit must  
>> do a complete revalidation of the entire ImageData data buffer.
> Yep, that's true.
>> I think we need a list of use cases for ImageData, off the top of  
>> my head i can think of:
>> * filters -- in general a single write per pixel, potentially  
>> multiple reads
>> * Generated images -- still arguably single write per pixel
>> * I'm not sure what to call this -- but things like http://jsmsxdemo.googlepages.com/jsmsx.html
>> I honestly can't think of something that would (sanely) expect to  
>> be writing multiple times to the same pixel between blits, but i  
>> should note i haven't actively spent any significant time trying to  
>> come up with these.  That said in all of the above cases the cost  
>> of immediate clamping is technically the same as delaying the  
>> clamp, although it also has the benefit of allowing reduced memory  
>> usage.
> Yeah, those are all good use cases -- it just seems like requiring  
> immediate clamping is basically specifying for a specific  
> implementation, when the overall goal is "checking for invalid  
> data".  Specifying that the error should come from putImageData  
> would give implementations more flexibility, without limiting error  
> checking.  (You could argue that it's easier to get a precise error  
> location by checking on pixel assignment, but I don't think that the  
> potential cost and loss of flexibility is worth it.  Once authors  
> know that they have an error in their data, they can take other  
> action to track it down.)

There is no implementor freedom here -- you either clamp immediately,  
or you do not clamp immediately, if one UA does not clamp then it will  
have different behaviour from the other UAs leading to behavioural  
incompatibility (eg. one site may expect the values to be clamped  
immediately, and therefore not work in UAs that don't clamp, another  
may believe that the clamping happens later leading it to break in  
those UAs that clamp immediately).

This is not to say there's no room for implementation variation -- an  
implementation *could* maintain the data as an array of boxed values  
provided it performed the requisite toNumber and clamping and rounding  
operations, or it could store as an array of unboxed types -- there  
are potential advantages in doing it in either way.  The issue is when  
clamping occurs, which isn't an implementation detail, it's  
fundamental to how the data structure works.

>    - Vlad


More information about the whatwg mailing list