[whatwg] High-density canvases

Stephen White senorblanco at chromium.org
Tue Sep 10 07:14:40 PDT 2013

For posterity, here were our objections to the original high-DPI canvas

   - The API feels like a short-term hack to automagically do something
   that the developer may or may not want done (e.g., if the game/app was
   tuned for particular resolution, or for pixel-exact rendering) that we'll
   be stuck with in the web platform long after its short-term usefulness has
   - It doesn't scale well to non-integer devicePixelRatios
   - It is easy for developers to implement the above behaviour in JS if

I think the new proposal addresses the first point, since it's opt-in. I
don't think the second point is a problem, since [get|put]ImageData() will
be back to manipulating exact backing store pixels, so no non-integer
resizing will be required. The third point becomes moot.

One question: now that some browsers are including browser zoom (page zoom)
in window.devicePixelRatio, will/should the new proposal automatically
cause a resize callback on page zoom, in order to preserve 1:1 device
pixels? (Note that I think this is a problem with current JS-based
implementations of canvas auto-scale as well, although perhaps there's a
DOM event for this that you can listen to; I might just be showing my
ignorance here.)


On Mon, Sep 9, 2013 at 8:00 PM, Ian Hickson <ian at hixie.ch> wrote:

> On Wed, 17 Jul 2013, Rik Cabanier wrote:
> > Ian wrote:
> > >
> > > The density aspect of this might be pointless, given the failure of
> > > getImageDataHD(); if we're dropping that one, I'll drop this one at
> > > the same time.
> >
> > Yes, please drop it since the HD methods are going away from the one
> > implementation.
> On Tue, 9 Jul 2013, Stephen White wrote:
> >
> > Conversely, if it helps to bring the spec closer to the implementations,
> > one thing we do not intend to implement in Chrome is the automatic
> > high-DPI canvas scaling (ie., auto-doubling of backing stores,
> > getImageDataHD(), putImageDataHD(), etc).
> >
> > I believe Apple has also announced that they are dropping support for
> > this in Safari 7.
> So my understanding is that the reason this feature failed is that there's
> existing content that assumes a 1:1 ratio, and having an automatic
> high-density mode was making some pages end up with canvases with four
> canvas pixels per CSS pixel (linearly) -- two from the browser making a
> native canvas, times two from the page scaling the canvas for high DPI
> displays. This is a factor of sixteen over a 1:1 canvas, a factor of four
> more than it should be for high DPI, and a big waste of resources.
> As much as sites do this manually, though, it's a huge pain in the neck to
> have to worry about pixel density when you're creating your canvas and
> drawing on it, especially if you're not drawing sprites on it.
> While we're talking about annoying things, there's also the annoyance that
> canvases tend to not take zoom into account (either density-affecting zoom
> like page zoom on desktop, or "transparent" zoom like pinch-zoom on mobile
> for non-mobile-optimised sites, which the site isn't supposed to know
> about): you have to remember to listen for onresize, and then manually
> blow away your canvas and recreate it at the right density and then
> squeeze it into place so that the coordinate space matches what your code
> is expecting while the <canvas> is actually sized for the display.
> There's also the issue of full-bleed canvases where every time the
> container changes, you have to remember to re-update the canvas coordinate
> space and repaint because otherwise your pretty page gets all warped.
> It would be nice to fix these all at once, and I think we can, by
> introducing a configuration option on getContext(), in the style of WebGL:
>    getContext('2d', { density: 'autosize' });
> This would trigger the following behaviour: When the context is created,
> and subsequently when the <canvas> changes size (e.g. due to being sized
> with CSS relative units and the element they're relative to changing), or
> when the display density changes size (e.g. due to page zoom), then:
>    - the width and height of the canvas bitmaps get updated to match the
>      new native size of the <canvas>, at native density.
>    - the coordinate space of the canvas (context.width/context.height)
>      gets updated to match the size of the <canvas> in CSS pixel units.
>    - a 'resize' event gets fired at the <canvas>.
> We would dump the *HD versions of the methods, and make the regular ones
> go back to returning the actual raw pixels, since that would now work fine
> and still provide HD-quality content everywhere it's available.
> What do people think?
> --
> Ian Hickson               U+1047E                )\._.,--....,'``.    fL
> http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
> Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

More information about the whatwg mailing list