I recently wrote a little web thingie that output a picture on a <canvas> pixel-by-pixel by calling fillRect() on a canvas. My picture had the interesting property that adjacent pixels were the same color in many cases. It was initially very slow, with lots of time taken by fillRect() (and specifically by the cairo stuff in there). By coalescing adjacent identical-color pixels into single rects and filling them all at once, this time was almost eliminates. I wonder whether it's worth putting this optimization into canvas itself. That is, delaying applying the fill to the cairo surface until either we get queried or the next op happens, and if the next op is also a fill and no other state has changed coalescing the rect. Thoughts?
I would suggest getImageData() and putImageData() for that use case :) We could coalesce, I'm just not sure whether it's worth the complexity -- it'll help use cases like this, but that's what getImageData/putImageData were put in for.
Hmm. The problem with getImageData/putImageData is they require rgb color values, when what I have are HTML color names. Plus they require building up these huge arrays, which is actually pretty slow.
Oh, huh.. are you sure that the parsing of the HTML colors (that is, setting fillStyle) isn't a bigger chunk than the actual fillRect? I would expect that setting fillStyle and overall xpconnect overhead is the majority of the time spent, not the actual time rendering the squares.
It would have been, for sure, except but I build up lists of rectangles which all have the same color, then for each list set the fillStyle once, then fill all the rectangles. For what it's worth, when I make claims about where time is being spent I'm usually staring at a Shark profile nowadays. ;)