[whatwg] I believe source rectangles for HTML5 Canvas drawImage are specified incorrectly

Kevin Gadd kevin.gadd at gmail.com
Mon Dec 17 13:37:47 PST 2012

On Mon, Dec 17, 2012 at 1:23 PM, Rik Cabanier <cabanier at gmail.com> wrote:
> On Mon, Dec 17, 2012 at 11:49 AM, Justin Novosad <junov at chromium.org> wrote:
>>> Isn't this the same as what Ian suggested: copy it to a temporary canvas
>>> and use the temporary canvas scales.
>>> It seems that you can optimize that case too.
>> Hmm... It would one of those optimizations that only works if you perform
>> the secret handshake just right.
>> If I understand correctly, the hypothetical optimization would work
>> something like this: When a 2d canvas context is created, do not allocate a
>> backing store immediately. If the first draw operation into the canvas is a
>> drawImage from an image element and covers the entire canvas, then use a
>> shallow copy of the bitmap as the backing store. If anything else is drawn
>> into the canvas, then a proper backing store should be allocated and used.
>> I guess it could work... but I would fear that this behavior would be
>> perceived as idiosyncratic.
> I don't disagree. However, there probably are other occasions in canvas
> today where a common idiom gets optimized.
> In addition, developers have proven that they are quite comfortable with
> idiosyncrasies. For instance, many sites force their CSS animations to run
> in 3D because it tricks the browser into hardware acceleration.

I think I agree in general with your thinking here, but it seems
questionable whether it can be applied in this specific case - right
now if you were to replace existing uses of drawImage with a temporary
canvas, you'd see a dramatic performance hit in most (if not all)
canvas implementations. Without a reliable way to detect that an
implementation understands your 'secret handshake', you'd basically be
murdering the playability of your game (or responsiveness of your
application, if it's an app) in the hopes that it will run better in
the future.

I'd be totally happy with the temporary canvas as a long term solution
as long as there is a reasonable way to identify whether it's the
right thing from the JS side. I have enough performance issues in my
games resulting from bad canvas implementations that I'm not excited
about introducing another one. As I've mentioned in previous posts, I
have observed temporary canvases causing *significant* performance
hits in the wild in otherwise stellar canvas 2d implementations; I've
had to blacklist them as a result and that's super fragile.

Some thought also needs to go into what the 'right way' to use a
temporary canvas is: Should there be one temporary canvas of adequate
size, that gets updated before each drawing operation? A fixed-size
pool of temporary canvases that get reused? One temporary canvas for
each source region of the spritemap that's being used? I could see the
correct answer here depending on the implementation. If there's an
easy answer, maybe that guidance can go into an addendum to the canvas
spec or strongly evangelized page on some developer-visible wiki like

For a highly parallel canvas implementation (one backed by OpenGL or
Direct3D) I would expect you would want one temporary canvas per
source region, and prefer canvases that never change, so that it's at
least possible for the implementation to map them to textures. On the
other hand, if canvas is being implemented in software you would
probably get the best performance out of a single temporary canvas
(cache locality, etc). And for backends like Direct2D, Cairo etc I
have no idea what to expect - they tend to defy my expectations since
so much interesting stuff has to go on in order to achieve the
guarantees they make to end-users.


More information about the whatwg mailing list