Intent to Implement: window.screen.canvasResolution

482 views
Skip to first unread message

Emil A Eklund

unread,
Jul 1, 2013, 8:37:45 PM7/1/13
to blink-dev
Primary eng/PM emails
e...@chromium.org

Spec
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-screen-canvasresolution

Summary
Provide a way for web content to query the pixel density (in device
pixels per coordinate space unit) so that an appropriate density may
be used for canvas image data. Can also be used to query the browser
zoom factor (by dividing the result by window.devicePixelRatio).

Motivation
In addition to being crucial for canvas image drawing being able to
query the zoom factor is an oft-requested feature and is quite hard to
do today. Entire libraries are provided for the sole purpose, e.g.
https://github.com/tombigel/detect-zoom

Compatibility Risk
Small to moderate. In latest HTML spec version but not implemented by
any other browser. IE provides device[XY]DPI/logical[XY]DPI.

Ongoing technical constraints
None

Will this feature be supported on all five Blink platforms (Windows,
Mac, Linux, Chrome OS and Android)?
Yes

OWP launch tracking bug?
None
Implementation bug: https://code.google.com/p/chromium/issues/detail?id=254990

Row on feature dashboard?
Yes

Requesting approval to ship?
No

Levi Weintraub

unread,
Jul 1, 2013, 8:40:41 PM7/1/13
to Emil A Eklund, blink-dev
LGTM. This is a highly requested feature and the libraries like the one mentioned are quite fragile.

Dimitri Glazkov

unread,
Jul 1, 2013, 10:29:35 PM7/1/13
to Levi Weintraub, Emil A Eklund, blink-dev
LGTM.

Brandon Jones

unread,
Jul 2, 2013, 12:10:19 AM7/2/13
to Dimitri Glazkov, Levi Weintraub, Emil A Eklund, blink-dev
To clarify: If I was to resize a WebGL canvas (which does not automatically scale the backing store) and I wanted it to always have a 1:1 pixel ratio with the screen, the formula would be ((css width or height) * window.screen.canvasResolution)?

If so, I'm fully behind this feature! (Though I have no ability to LG.) Detecting browser zoom levels is a pain point for many applications.


Kenneth Rohde Christiansen

unread,
Jul 2, 2013, 4:22:31 AM7/2/13
to e...@chromium.org, blink-dev
I like the feature, but I find the method name a bit confusing, but
LGTM for implementing!

Kenneth
--
Kenneth Rohde Christiansen
Senior Engineer, WebKit, Qt, EFL
Phone +45 4294 9458 / E-mail kenneth at webkit.org

﹆﹆﹆

John Mellor

unread,
Jul 2, 2013, 10:17:44 AM7/2/13
to Kenneth Rohde Christiansen, e...@chromium.org, blink-dev
I'm confused - how does this help to determine the browser zoom factor? Surely we're not proposing to change the pixel ratio of canvases whenever you pinch zoom? And if you're talking about the desktop full page zoom factor, then this is the wrong way to expose that - instead we should just roll that into devicePixelRatio, as proposed in crbug.com/177836.

Finally, could you clarify the relationship between screen.canvasResolution and Safari's context.webkitBackingStorePixelRatio?

Ben Vanik

unread,
Jul 2, 2013, 11:04:09 AM7/2/13
to John Mellor, Kenneth Rohde Christiansen, e...@chromium.org, blink-dev
In Maps changing pixel ratio on browswr zoom is exactly what we want, otherwise the canvas backing store will end up way too big for the device (zoom in a few times and you'll be creating 100MB backing stores). We have a bunch of hacks in today to try to prevent users from doing this (and crashing Chrome or locking up their entire desktop) and this property would allow us to be much more robust.

Kenneth Rohde Christiansen

unread,
Jul 2, 2013, 11:11:12 AM7/2/13
to Ben Vanik, John Mellor, e...@chromium.org, blink-dev
Didn't the spec say that once a canvas has a bitmap, that canvas must
keep its resolution for its lifetime. So you would also need a way to
get notified if the scale changes.

Kenneth

Emil A Eklund

unread,
Jul 2, 2013, 2:00:55 PM7/2/13
to Brandon Jones, Dimitri Glazkov, Levi Weintraub, blink-dev
On Mon, Jul 1, 2013 at 9:10 PM, Brandon Jones <baj...@google.com> wrote:
> To clarify: If I was to resize a WebGL canvas (which does not automatically
> scale the backing store) and I wanted it to always have a 1:1 pixel ratio
> with the screen, the formula would be ((css width or height) *
> window.screen.canvasResolution)?

Correct.

> I like the feature, but I find the method name a bit confusing, but
> LGTM for implementing!

The method name is a bit confusing but as it is primarily intended to
be used to determine the appropriate image data to use for canvas and
images it seems somewhat appropriate.

Rik Cabanier

unread,
Jul 2, 2013, 5:21:26 PM7/2/13
to John Mellor, Kenneth Rohde Christiansen, e...@chromium.org, blink-dev
I agree. This property is very confusing.
The spec states:
The canvasResolution attribute of the Screen object must return the pixel density, in image pixels per coordinate space units, that any canvas andCanvasRenderingContext2D bitmaps created during this task will use (or have used). [1]

However, a canvas is always created at 96dpi (at least for Canvas 2D). MacOS Safari doubled it for Retina displays but they announced that they will disable this because it caused a lot of confusion.

So, I think this feature is not designed to detect the current zoom level or pixel density.

1: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-screen-canvasresolution

Anne van Kesteren

unread,
Jul 3, 2013, 2:24:26 AM7/3/13
to Rik Cabanier, John Mellor, Kenneth Rohde Christiansen, Emil A Eklund, blink-dev
On Tue, Jul 2, 2013 at 10:21 PM, Rik Cabanier <caba...@gmail.com> wrote:
> However, a canvas is always created at 96dpi (at least for Canvas 2D). MacOS
> Safari doubled it for Retina displays but they announced that they will
> disable this because it caused a lot of confusion.

Surely they would keep it, it's just exposed differently, via *HD methods.


--
http://annevankesteren.nl/

Rik Cabanier

unread,
Jul 3, 2013, 10:39:43 AM7/3/13
to Anne van Kesteren, John Mellor, Kenneth Rohde Christiansen, Emil A Eklund, blink-dev
No, I believe those are gone in Safari 7. 

James Robinson

unread,
Jul 3, 2013, 5:58:16 PM7/3/13
to Anne van Kesteren, Rik Cabanier, John Mellor, Kenneth Rohde Christiansen, Emil A Eklund, blink-dev
On Tue, Jul 2, 2013 at 11:24 PM, Anne van Kesteren <ann...@annevk.nl> wrote:
No.  Auto-doubling is gone.  The *HD methods are simply aliases for the non-*HD methods, when they exist.

- James
 


--
http://annevankesteren.nl/

Rik Cabanier

unread,
Jul 3, 2013, 6:33:41 PM7/3/13
to James Robinson, Anne van Kesteren, John Mellor, Kenneth Rohde Christiansen, Emil A Eklund, blink-dev
Indeed and since it seems that canvasResolution was designed in conjunction with the HD methods, it is now obsolete. 
Some of the writing seems to imply that canvasResolution is dependent on the current zoom level but then this:
window.screen.canvasResolution
Returns the pixel density that has been, or will be, used for bitmaps during this task.

implies that it is a constant.

James Robinson

unread,
Jul 3, 2013, 6:43:36 PM7/3/13
to Emil A Eklund, blink-dev
As defined here, this number will always be 1.  We always construct canvas bitmaps that exactly match the specified width/height attributes.  The only browser I know of that's done anything else was Safari 6 which would return '2' for this when running on retina displays, but that's not the case in Safari 7 or (one would expect) future versions.

I don't think this is very useful and so I suspect you want to return some other number.  However, I don't know what number that is since it isn't defined anywhere.  I think we need to nail this down before proceeding further.  From the rest of the email, it appears you want this to be able to detect browser zoom, but this is a complicated area.  Browsers today have notions of device scales, page scales and page zooms.  Your patch multiplies the device scale and page zoom factors, but ignores page scale.  We already expose the device scale to the web as window.devicePixelRatio, so I'm not sure why we need to include that in this number.  Why does this number exclude the page scale?  How do page authors detect and react to changes in this number?

- James

Emil A Eklund

unread,
Jul 3, 2013, 6:47:13 PM7/3/13
to James Robinson, blink-dev
The use case is to allow an appropriate resource to be loaded for
canvas and images. Recent discussion seems to have converged on
updating devicePixelRatio on zoom instead and if we can agree on that
then this property would no longer be needed. I'll obviously hold of
implementing this until a consensus has been reached and would gladly
implement the devicePixelRatio changes instead if that turns out to be
the way forward.

See https://code.google.com/p/chromium/issues/detail?id=177836 for details.

Adam Barth

unread,
Jul 3, 2013, 7:09:31 PM7/3/13
to Emil A Eklund, James Robinson, blink-dev
I'm skeptical about dynamically changing the devicePixelRatio while a page is rendering.  That's not something pages need to handle today, and I'd expect many to break in weird and wonderful ways.  I also suspect that many pages won't work properly if devicePixelRatio takes on a value other than 1 or 2.

Page zoom is such a nitch feature...  How do we plan to assess the compatibility impact of changing the semantics of devicePixelRatio during a page zoom?

Adam

Emil A Eklund

unread,
Jul 3, 2013, 7:20:00 PM7/3/13
to Adam Barth, James Robinson, blink-dev
On Wed, Jul 3, 2013 at 4:09 PM, Adam Barth <aba...@chromium.org> wrote:
> Page zoom is such a nitch feature... How do we plan to assess the
> compatibility impact of changing the semantics of devicePixelRatio during a
> page zoom?

I wouldn't call it nitch something like 10% of page views are zoomed
(looking at gmail data) and knowing the ratio for css to device pixels
is quite important for pages/apps like maps and docs. I really don't
care about _how_ we expose the css:device ratio but we really do need
to expose it somehow, be it through devicePixelRatio,
canvasResolution, logicalXDPI or some other way.

--
Emil

Adam Barth

unread,
Jul 3, 2013, 7:34:45 PM7/3/13
to Emil A Eklund, James Robinson, blink-dev
On Wed, Jul 3, 2013 at 4:20 PM, Emil A Eklund <e...@chromium.org> wrote:
On Wed, Jul 3, 2013 at 4:09 PM, Adam Barth <aba...@chromium.org> wrote:
> Page zoom is such a nitch feature...  How do we plan to assess the
> compatibility impact of changing the semantics of devicePixelRatio during a
> page zoom?

I wouldn't call it nitch something like 10% of page views are zoomed
(looking at gmail data)

Really!  That's interesting.
 
and knowing the ratio for css to device pixels
is quite important for pages/apps like maps and docs. I really don't
care about _how_ we expose the css:device ratio but we really do need
to expose it somehow, be it through devicePixelRatio,
canvasResolution, logicalXDPI or some other way.

I wonder if we should report the data with integer snaps so that code like the following doesn't break:

var image = new Image("foo@" + window.devicePixelRatio + "x.png");

Here's a random tutorial that advocates an approach like the above: http://egorkhmelev.github.io/retina/.

---8<---
jQuery( document ).ready(function(){
  if( 'devicePixelRatio' in window && window.devicePixelRatio == 2 ){
    var img_to_replace = jQuery( 'img.replace-2x' ).get();
 
    for (var i=0,l=img_to_replace.length; i<l; i++) {
      var src = img_to_replace[i].src;
      src = src.replace(/\.(png|jpg|gif)+$/i, '@2x.$1');
      img_to_replace[i].src = src;
    };
  }
});
--->8---

The code from that tutorial will also be very confused if the devicePixelRatio changes over time:

---8<---
(function(){
  if( document.cookie.indexOf('device_pixel_ratio') == -1
      && 'devicePixelRatio' in window
      && window.devicePixelRatio == 2 ){
        
    document.cookie = 'device_pixel_ratio=' + window.devicePixelRatio + ';';
    window.location.reload();
  }
})();
 
// The cookie 'device_pixel_ratio' will be available at server-side
--->8---

There's an interesting quirksmode article on devicePixelRatio: <http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html>.  In relation to setting the resolution to non-default values on a MacBook Pro:

"In any case, what Apple has done here is standardise on only two devicePixelRatio values: 1 and 2. If you see 2 you know that you can serve retina-optimised images, while a 1 says you should serve normal images."

... and at the end of the article:

"Update: Turns out Opera's value depends on the zoom level. And I wouldn't be surprised if the same goes for other browsers. I did not test this. Maybe later."

That means that ppk wrote two entire articles about devicePixelRatio and only realized this edge case involving zoom level afterwards.  If we're not careful in how we handle this issue, we run the risk of tormenting developers.

Adam

James Robinson

unread,
Jul 3, 2013, 7:36:20 PM7/3/13
to Adam Barth, Emil A Eklund, blink-dev
On Wed, Jul 3, 2013 at 4:09 PM, Adam Barth <aba...@chromium.org> wrote:
On Wed, Jul 3, 2013 at 3:47 PM, Emil A Eklund <e...@chromium.org> wrote:
The use case is to allow an appropriate resource to be loaded for
canvas and images. Recent discussion seems to have converged on
updating devicePixelRatio on zoom instead and if we can agree on that
then this property would no longer be needed. I'll obviously hold of
implementing this until a consensus has been reached and would gladly
implement the devicePixelRatio changes instead if that turns out to be
the way forward.

See https://code.google.com/p/chromium/issues/detail?id=177836 for details.

I'm skeptical about dynamically changing the devicePixelRatio while a page is rendering.  That's not something pages need to handle today, and I'd expect many to break in weird and wonderful ways.  I also suspect that many pages won't work properly if devicePixelRatio takes on a value other than 1 or 2.

The devicePixelRatio can be 1.4, 1.5, 1.8 and probably other values on currently shipping devices.  Several Android devices have scales in the 1.5 range and Windows 8 supports 1.4/1.8.

- James

Adam Barth

unread,
Jul 3, 2013, 7:42:43 PM7/3/13
to James Robinson, Emil A Eklund, blink-dev
On Wed, Jul 3, 2013 at 4:36 PM, James Robinson <jam...@google.com> wrote:
On Wed, Jul 3, 2013 at 4:09 PM, Adam Barth <aba...@chromium.org> wrote:
On Wed, Jul 3, 2013 at 3:47 PM, Emil A Eklund <e...@chromium.org> wrote:
The use case is to allow an appropriate resource to be loaded for
canvas and images. Recent discussion seems to have converged on
updating devicePixelRatio on zoom instead and if we can agree on that
then this property would no longer be needed. I'll obviously hold of
implementing this until a consensus has been reached and would gladly
implement the devicePixelRatio changes instead if that turns out to be
the way forward.

See https://code.google.com/p/chromium/issues/detail?id=177836 for details.

I'm skeptical about dynamically changing the devicePixelRatio while a page is rendering.  That's not something pages need to handle today, and I'd expect many to break in weird and wonderful ways.  I also suspect that many pages won't work properly if devicePixelRatio takes on a value other than 1 or 2.

The devicePixelRatio can be 1.4, 1.5, 1.8 and probably other values on currently shipping devices.  Several Android devices have scales in the 1.5 range and Windows 8 supports 1.4/1.8.

How many web pages are broken on those devices?

Adam

Rik Cabanier

unread,
Jul 3, 2013, 7:50:49 PM7/3/13
to Adam Barth, Emil A Eklund, James Robinson, blink-dev
On Wed, Jul 3, 2013 at 4:09 PM, Adam Barth <aba...@chromium.org> wrote:
On Wed, Jul 3, 2013 at 3:47 PM, Emil A Eklund <e...@chromium.org> wrote:
The use case is to allow an appropriate resource to be loaded for
canvas and images. Recent discussion seems to have converged on
updating devicePixelRatio on zoom instead and if we can agree on that
then this property would no longer be needed. I'll obviously hold of
implementing this until a consensus has been reached and would gladly
implement the devicePixelRatio changes instead if that turns out to be
the way forward.

See https://code.google.com/p/chromium/issues/detail?id=177836 for details.

I'm skeptical about dynamically changing the devicePixelRatio while a page is rendering.  That's not something pages need to handle today, and I'd expect many to break in weird and wonderful ways.

Yes,
please don't make devicePixelRatio. Not only will you break content, on large ratio's you might cause the browser to make huge allocations if people multiply the devicePixelRatio with width and height.

Rik Cabanier

unread,
Jul 3, 2013, 7:52:19 PM7/3/13
to Adam Barth, James Robinson, Emil A Eklund, blink-dev
devicePixelRatio of 1.5 is pretty common so that should work.
I doubt many page optimize for the opera case so they are most likely broken (in that they won't update on opera as the user zooms in/out) 

John Mellor

unread,
Jul 3, 2013, 8:36:44 PM7/3/13
to Rik Cabanier, blink-dev, e...@chromium.org, James Robinson, Adam Barth

Adam wrote:
> I'm skeptical about dynamically changing the devicePixelRatio while
> a page is rendering.  That's not something pages need to handle
> today, and I'd expect many to break in weird and wonderful ways.

Yes, that is my only concern. I see two paths:

A) Ideal but risky: after testing (somehow) whether sites break if devicePixelRatio changes, if we determine that this isn't a problem then go ahead and make it directly linked to the page zoom factor (and update as much documentation as possible to mention this).

B) The safer option: when the page loads, if full page zoom is persisted for that domain then incorporate the stored page zoom factor into the devicePixelRatio, but don't update the devicePixelRatio if the page zoom factor changes while the page is open. If there are enough sites that do care about full page zoom, we could provide an additional liveDevicePixelRatio property (better names please!) which would update as in A.

I'm ambivalent whether we go for A or B.

Rik wrote:
> Yes, please don't make devicePixelRatio. Not only will you
> break content, on large ratio's you might cause the browser to make
> huge allocations if people multiply the devicePixelRatio with width and
> height.

Huge allocations shouldn't be a problem here. Remember that with full page zoom, we first divide the viewport width by the page zoom factor, so if the page scales textures up by the page zoom factor (via devicePixelRatio), they'll just end up with the same size they would have had if the page wasn't zoomed.

Rik wrote:
> I doubt many page optimize for the opera case so they are most likely
> broken (in that they won't update on opera as the user zooms in/out) 

That's not broken, that's reasonable behaviour. But worse cases are certainly possible, as discussed in my reply to Adam.

James wrote:
> The devicePixelRatio can be 1.4, 1.5, 1.8 and probably other values on
> currently shipping devices.

1.33x (Nexus 7) and 3x (Samsung Galaxy S4) are also common.

Rik Cabanier

unread,
Jul 3, 2013, 11:53:12 PM7/3/13
to John Mellor, blink-dev, e...@chromium.org, James Robinson, Adam Barth
On Wed, Jul 3, 2013 at 5:36 PM, John Mellor <joh...@google.com> wrote:

Adam wrote:
> I'm skeptical about dynamically changing the devicePixelRatio while
> a page is rendering.  That's not something pages need to handle
> today, and I'd expect many to break in weird and wonderful ways.

Yes, that is my only concern. I see two paths:

A) Ideal but risky: after testing (somehow) whether sites break if devicePixelRatio changes, if we determine that this isn't a problem then go ahead and make it directly linked to the page zoom factor (and update as much documentation as possible to mention this).

B) The safer option: when the page loads, if full page zoom is persisted for that domain then incorporate the stored page zoom factor into the devicePixelRatio, but don't update the devicePixelRatio if the page zoom factor changes while the page is open. If there are enough sites that do care about full page zoom, we could provide an additional liveDevicePixelRatio property (better names please!) which would update as in A.


I think we need something new. devicePixelRatio shouldn't be overloaded.
Maybe a parameter that gives you the zoom level? It seems that's really what an author wants to know.
 

I'm ambivalent whether we go for A or B.

Rik wrote:
> Yes, please don't make devicePixelRatio. Not only will you
> break content, on large ratio's you might cause the browser to make
> huge allocations if people multiply the devicePixelRatio with width and
> height.

Huge allocations shouldn't be a problem here. Remember that with full page zoom, we first divide the viewport width by the page zoom factor, so if the page scales textures up by the page zoom factor (via devicePixelRatio), they'll just end up with the same size they would have had if the page wasn't zoomed.

I don't really understand that. If you have a 1024x768 2d canvas on a 1024x768 device and you zoom in to 1000%, doesn't that make the backing store for the canvas 100 times bigger?

Yoav Weiss

unread,
Jul 4, 2013, 2:38:57 AM7/4/13
to Rik Cabanier, John Mellor, blink-dev, e...@chromium.org, James Robinson, Adam Barth
Regarding pages breaking if devicePixelRatio would change dynamically - Firefox is already doing that (See http://codepen.io/anon/pen/gGpyB in Firefox for a quick test) for both window.devicePixelRatio and the resolution MQs.

There have been some reports of pages breaking as a result of DPR not being exactly 2 (https://bugzilla.mozilla.org/show_bug.cgi?id=809788), but one can argue that since Mozilla doesn't intend to change this behavior, and since there are many devices with a DPR value of 1.X, these pages should be fixed anyway.

Adam Barth

unread,
Jul 4, 2013, 3:20:27 AM7/4/13
to Yoav Weiss, Rik Cabanier, John Mellor, blink-dev, Emil A Eklund, James Robinson
It's good that our friends at Mozilla are headed in the same direction.

Given this discussion, I've changed my mind and am now supportive of changing window.devicePixelRatio dynamically based on page zoom.  On #blink, Emil suggested that we measure how many image requests 404 with this behavior to assess the compatibility impact.  That still seems worthwhile to me.

Adam

John Mellor

unread,
Jul 4, 2013, 7:01:35 AM7/4/13
to Rik Cabanier, blink-dev, e...@chromium.org, James Robinson, Adam Barth
On Thu, Jul 4, 2013 at 4:53 AM, Rik Cabanier <caba...@gmail.com> wrote:
If you have a 1024x768 2d canvas on a 1024x768 device and you zoom in to 1000%, doesn't that make the backing store for the canvas 100 times bigger?
 
If you had a 1024x768 device with initial devicePixelRatio of 1x, and you zoomed in to 1000%, we'd tell the page it was a 102x77 device with devicePixelRatio of 10x. So a website with a width:100%;height:100% canvas that scales the backing store by the devicePixelRatio would end up with a 102*10 x 77*10 = 1020x770 backing store, which is fine.

Rik Cabanier

unread,
Jul 4, 2013, 12:19:56 PM7/4/13
to Yoav Weiss, John Mellor, blink-dev, e...@chromium.org, James Robinson, Adam Barth
What type of 'zoom' are we trying to detect? Is it using the ctrl-+/- or using gestures on a tablet?
There's a thread on devicePixelRatio on www-style: http://lists.w3.org/Archives/Public/www-style/2012Nov/0144.html

ctrl-+/- causes layout so changes devicePixelRatio but zooming does not.

On Wed, Jul 3, 2013 at 11:38 PM, Yoav Weiss <yo...@yoav.ws> wrote:

Nico Weber

unread,
Jul 4, 2013, 12:54:04 PM7/4/13
to Rik Cabanier, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org, James Robinson, Adam Barth
If devicePixelRatio and zoom stay independent, devicePixelRatio will probably be an integer multiple eventually, which I think is a nice long term goal. Dealing with fractional pixel magnifications is much trickier than dealing with integer scale factors.

OS X tried to use fractional device pixels and then changed to just 1x and 2x (and maybe 3x one day), Windows is currently trying to use lots of different scaling factors and it's pretty confusing, and web pages have a hard time providing image assets for just 1x and 2x already.

Ben Vanik

unread,
Jul 4, 2013, 2:44:27 PM7/4/13
to Nico Weber, Rik Cabanier, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org, James Robinson, Adam Barth
No no no - please do not tie devicePixelRatio to page zoom - that is terrible behavior for canvas apps like Maps and games!

In those cases the canvases need to have a backing store that is 1:1 native display res and the page zoom should be happening inside of JavaScript code. For example, if I'm drawing a map a page zoom should increase the map zoom level, not the number of pixels in the backing store. If I'm drawing a game UI in canvas, I want to scale the game UI up on page zoom but still render at device pixel resolution (just as the DOM does). If you tie the two together, things would get blurry in the zoom in case (not what the user wants) and crash the machine in the zoom out case (we've had to work around this in Maps already because creating >4kx4k canvas backing stores would hard lock OSX and crash browsers on other platforms).

We need two properties - devicePixelRatio that is not dependent on page zoom AND page zoom that is not dependent on device pixel ratio. Then apps can do the math themselves based on what they are trying to accomplish.

Brandon Jones

unread,
Jul 4, 2013, 3:04:15 PM7/4/13
to Ben Vanik, Nico Weber, Rik Cabanier, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org, James Robinson, Adam Barth
I'm with Ben on this one. devicePixelRatio should represent the physical pixel ratio of the screen, which does not change. This is useful for determining image resolutions to fetch from the server. (I don't want a tiny image because I'm zoomed out)

It would be great to have a separate viewportZoom property. Then there's no ambiguity about what the property represents and the various scenarios that have been discussed can all be addressed.

Brandon Jones

unread,
Jul 4, 2013, 3:12:13 PM7/4/13
to John Mellor, Rik Cabanier, blink-dev, e...@chromium.org, James Robinson, Adam Barth
That's actually still problematic because you'll get some awkward sub-pixel offsets that will make the canvas look weirdly aliased. That's not a problem that can be solved with a single multiplier, though. You would either need to start reporting floating point element width/height (yuck!) or have some way of querying the element's actual on-screen size, which I think would be awesome but isn't the focus of this discussion.

Dana Jansens

unread,
Jul 4, 2013, 9:36:10 PM7/4/13
to Rik Cabanier, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org, James Robinson, Adam Barth
On Thu, Jul 4, 2013 at 9:19 AM, Rik Cabanier <caba...@gmail.com> wrote:
What type of 'zoom' are we trying to detect? Is it using the ctrl-+/- or using gestures on a tablet?
There's a thread on devicePixelRatio on www-style: http://lists.w3.org/Archives/Public/www-style/2012Nov/0144.html

ctrl-+/- causes layout so changes devicePixelRatio but zooming does not.

Page zoom = control +/-

Page scale = pinch gestures

AIUI, page zoom is the only thing being discussed here.

Rik Cabanier

unread,
Jul 4, 2013, 10:32:08 PM7/4/13
to Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org, James Robinson, Adam Barth
On Thu, Jul 4, 2013 at 6:36 PM, Dana Jansens <dan...@chromium.org> wrote:
On Thu, Jul 4, 2013 at 9:19 AM, Rik Cabanier <caba...@gmail.com> wrote:
What type of 'zoom' are we trying to detect? Is it using the ctrl-+/- or using gestures on a tablet?
There's a thread on devicePixelRatio on www-style: http://lists.w3.org/Archives/Public/www-style/2012Nov/0144.html

ctrl-+/- causes layout so changes devicePixelRatio but zooming does not.

Page zoom = control +/-

Page scale = pinch gestures

AIUI, page zoom is the only thing being discussed here.

I'm unsure this is the case. 
For instance see Ben's email: 
If you tie the two together, things would get blurry in the zoom in case (not what the user wants) and crash the machine in the zoom out case (we've had to work around this in Maps already because creating >4kx4k canvas backing stores would hard lock OSX and crash browsers on other platforms).

control +/- would not make things blurry but pinch gestures would

Brandon Jones

unread,
Jul 4, 2013, 10:43:48 PM7/4/13
to Rik Cabanier, Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org, James Robinson, Adam Barth
Ben was specifically talking about setting the canvas backing store width and height. "Blurry" in this case refers to allocating a backing store that is too small and then upscaling to fit the element. That's possible through both page scale and zoom, but the maps issues he mentioned were zoom related.

Michael Davidson

unread,
Jul 9, 2013, 5:21:58 PM7/9/13
to Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org, James Robinson, Adam Barth
This thread seems to have slowed down, but I want to point out that changing devicePixelRatio is absolutely not what we want for Maps.

For Maps, we size our labels in CSS pixels so that they're the same physical size on retina or normal devices. That is, the size of a label is independent of devicePixelRatio.

When the user zooms the browser, the text on the page changes, except for on-map labels! We need tobe able to detect browser zoom separately from devicePixelRatio to be able to give the user a good experience. 

Likewise, zooming the browser should make the existing map tiles bigger or smaller, not change the number of tiles on the screen, which is what changing devicePixelRatio would do.

To provide a consistent experience to users, we need to know the zoom of the browser, and to be able to distinguish it from the native DPI of the device.

Michael

Adam Barth

unread,
Jul 9, 2013, 5:45:24 PM7/9/13
to Michael Davidson, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org, James Robinson
On Tue, Jul 9, 2013 at 2:21 PM, Michael Davidson <m...@google.com> wrote:
This thread seems to have slowed down, but I want to point out that changing devicePixelRatio is absolutely not what we want for Maps.

For Maps, we size our labels in CSS pixels so that they're the same physical size on retina or normal devices. That is, the size of a label is independent of devicePixelRatio.

When the user zooms the browser, the text on the page changes, except for on-map labels! We need tobe able to detect browser zoom separately from devicePixelRatio to be able to give the user a good experience. 

Can you explain more of the "why" behind this statement?  To be clear, we're talking about Ctrl-+/- (i.e., "full-page zoom") rather than the pinch-to-zoom feature of touch interfaces (i.e., page scale).  Typically, when the user uses Ctrl-+, everything on the page occupies more physical space on their monitor, including buttons and labels.  What does change, for example, are rounded corners, which have larger radii but smoother curves.

For maps, I would expect Ctrl-+ to make all the text larger (including labels---I likely used Ctrl-+ because I have difficulty reading small type) but to be able to see more detailed coastlines (similar to how rounded corners are smoother).

Adam

James Robinson

unread,
Jul 9, 2013, 5:48:22 PM7/9/13
to Michael Davidson, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org, Adam Barth
On Tue, Jul 9, 2013 at 2:21 PM, Michael Davidson <m...@google.com> wrote:
This thread seems to have slowed down, but I want to point out that changing devicePixelRatio is absolutely not what we want for Maps.

I think you're confusing the script-exposed devicePixelRatio with the way the browser handles device scale.  Nobody is proposing that the browser handle page zoom in the same way as a change to the device scale - that would not work at all.  The proposal is only to change how the page zoom is exposed to script.  Maps should work just fine with this proposal.
 

For Maps, we size our labels in CSS pixels so that they're the same physical size on retina or normal devices. That is, the size of a label is independent of devicePixelRatio.

That's fine.  Increasing the page zoom level would also increase the number of physical pixels that one CSS pixel maps to and thus increase the label size in the expected way. 


When the user zooms the browser, the text on the page changes, except for on-map labels! We need tobe able to detect browser zoom separately from devicePixelRatio to be able to give the user a good experience. 

The whole tile should be bigger, labels and all.  Let's work out an example.

Initial state: device scale is 1.0, browser window is 2000px wide, page zoom is 100%.  Thus the page is 2000 CSS px wide.  Let's say for the ease of math that maps tiles are 250 CSS px wide, so the screen is 8 tiles wide.  Now let's say that the user increases the page zoom to 120%.  What happens?  Each CSS pixel now occupies 1.2 physical pixels, so 1666 CSS pixels now fully occupy the screen's width.  The tiles are now 300 physical pixels wide and look (visually) larger.  If nothing at all happens in script, the tiles will look rather blurry.  The browser knows that 1 CSS px maps to 1.2 physical pixels and that the actual device scale is still 1.0, so it positions and renders HTML content just fine.  The only question is what to do with author-rasterized content like canvas.

If we modify devicePixelRatio to 1.2 and fire the appropriate event at the page, what will happen?  The situation as far as the page goes is as follows:

window.devicePixelRatio: 1.2
window width: 1666 CSS px, or 6 and 2/3rds tiles

The right thing for the page to do in this situation is construct 7 tiles each representing 250 CSS px worth of content and each with a 300x300 pixel physical backing store.  Since each tile still represents 250 CSS px worth of content, less will fit on screen (and thus the content will be bigger) but since the backing store is the right size more physical pixels will be used for each unit of content (so the content will be sharp).  If the user increases the page zoom all the way up to 200% then the situation looks like this:

window.devicePixelRatio: 2.0
window width: 1000 CSS px, or 4 tiles

which (not coincidentally) is exactly the same math as if the user was on a retina MBP.  The only difference is how big the end result looks on the user's screen, which is a function of density of their monitor, etc.  All maps has to do is make sure that it sizes logical content (like tiles) in terms of CSS pixels and that it provides enough pixels in the backing store to produce a sharp result.  In no case does maps need to know if the contribution of CSS pixels to physical pixels is due to an actual device scale or to page zoom.  That's purely for the browser to deal with.

Of course, you may want to keep the physical size of the tiles the same as the page zoom increases and have each tile represent a smaller amount of actual content.  The math works out the same way.
 

Likewise, zooming the browser should make the existing map tiles bigger or smaller, not change the number of tiles on the screen, which is what changing devicePixelRatio would do. 

To provide a consistent experience to users, we need to know the zoom of the browser, and to be able to distinguish it from the native DPI of the device.

I don't think we want pages to attempt to "helpfully" interpret page zoom in their own application-specific ways.  Authors are very likely to get the math wrong and end up breaking what the user intended to do.

- James

Michael Davidson

unread,
Jul 9, 2013, 6:26:08 PM7/9/13
to Adam Barth, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org, James Robinson

James, I'm still digesting your mail and will respond. You might be right, my objections might not be correct.


On Tue, Jul 9, 2013 at 2:45 PM, Adam Barth <aba...@chromium.org> wrote:

Can you explain more of the "why" behind this statement?  To be clear, we're talking about Ctrl-+/- (i.e., "full-page zoom") rather than the pinch-to-zoom feature of touch interfaces (i.e., page scale).  Typically, when the user uses Ctrl-+, everything on the page occupies more physical space on their monitor, including buttons and labels.  What does change, for example, are rounded corners, which have larger radii but smoother curves.

Today pinch-to-zoom and Ctrl-+/- do the same thing, yes? They show the same UI, in any case. I realize when touch events are exposed we can interpret pinch-to-zoom as an actual map zoom, which is our desire.

It appears that this might be discussed upthread, so I'll try to catch up.

 
For maps, I would expect Ctrl-+ to make all the text larger (including labels---I likely used Ctrl-+ because I have difficulty reading small type) but to be able to see more detailed coastlines (similar to how rounded corners are smoother).

Seeing a more detailed coastline implies zooming the map in. If you blow up an existing view to make it larger (as will happen if you adjust the devicePixelRatio), you won't necessarily see more detail because we don't have it. To see more detail you need to actually zoom in the map, not the browser. Zoomed in pages will get blurry geometry if devicePixelRatio is adjusted.

Most folks today who pinch-to-zoom intend to zoom the map instead of the browser, which is part of our desire to know the browser zoom. It's likely a mistake. That will change once we have touch event support.

Michael

James Robinson

unread,
Jul 9, 2013, 6:48:09 PM7/9/13
to Michael Davidson, Adam Barth, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org
On Tue, Jul 9, 2013 at 3:26 PM, Michael Davidson <m...@google.com> wrote:

James, I'm still digesting your mail and will respond. You might be right, my objections might not be correct.


On Tue, Jul 9, 2013 at 2:45 PM, Adam Barth <aba...@chromium.org> wrote:

Can you explain more of the "why" behind this statement?  To be clear, we're talking about Ctrl-+/- (i.e., "full-page zoom") rather than the pinch-to-zoom feature of touch interfaces (i.e., page scale).  Typically, when the user uses Ctrl-+, everything on the page occupies more physical space on their monitor, including buttons and labels.  What does change, for example, are rounded corners, which have larger radii but smoother curves.

Today pinch-to-zoom and Ctrl-+/- do the same thing, yes? They show the same UI, in any case. I realize when touch events are exposed we can interpret pinch-to-zoom as an actual map zoom, which is our desire.

Sometimes!  This world is complicated.  Ctrl +/- increase/decrease the page zoom factor which is also controllable as 'Zoom' in the Chrome hot-dog menu.  Most of the time - on Android and Windows 8 touch devices pinching influences a different scale factor called the page scale that is orthogonal to page zoom.  On OS X (10.7+ iirc), pinching on some pointing devices (such as the trackpad on a macbook, some of their external mouse) is interpreted by chrome in a manner similar to Ctrl +/-.  This is pretty inconsistent.  Safari handles pinch gestures on OS X in a different way that's full of rounding errors and fail so let's not talk about that if we can help it.  The OS X behavior for pinch on some devices is really an outlier in the Chrome universe and we might revisit it to mean something else.


It appears that this might be discussed upthread, so I'll try to catch up.

 
For maps, I would expect Ctrl-+ to make all the text larger (including labels---I likely used Ctrl-+ because I have difficulty reading small type) but to be able to see more detailed coastlines (similar to how rounded corners are smoother).

Seeing a more detailed coastline implies zooming the map in. If you blow up an existing view to make it larger (as will happen if you adjust the devicePixelRatio), you won't necessarily see more detail because we don't have it. To see more detail you need to actually zoom in the map, not the browser. Zoomed in pages will get blurry geometry if devicePixelRatio is adjusted.

Isn't that an application issue, though?  If I have more physical pixels to display a certain amount of coastline, why wouldn't you load in whatever data is needed to render that coastline in a pretty way?  The size of UI elements should be determined by CSS pixels and the number of physical pixels used to render that UI element should be determined by the devicePixelRatio.  If for whatever reason (device scale, page zoom, whatever) I decide to map one CSS pixel to lots of physical pixels then I think the proper thing for maps to do is render both the UI elements and the vector content using lots of physical pixels.  I don't think it matters *why* a CSS pixel maps to many physical pixels, the expected rendering is the same.
 

Most folks today who pinch-to-zoom intend to zoom the map instead of the browser, which is part of our desire to know the browser zoom. It's likely a mistake. That will change once we have touch event support.

If you're talking specifically about the OS X gesture, that may be the case.  If we end up exposing that as touch events then the page can decide how to interpret those.  For all other ways to increase/decrease the page zoom (Ctrl +/-, interacting with the browser UI directly, etc) I think we just want to interpret that as a page zoom.

- James

Adam Barth

unread,
Jul 9, 2013, 6:49:38 PM7/9/13
to James Robinson, Michael Davidson, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org
On Tue, Jul 9, 2013 at 3:48 PM, James Robinson <jam...@google.com> wrote:
On Tue, Jul 9, 2013 at 3:26 PM, Michael Davidson <m...@google.com> wrote:
James, I'm still digesting your mail and will respond. You might be right, my objections might not be correct.

On Tue, Jul 9, 2013 at 2:45 PM, Adam Barth <aba...@chromium.org> wrote:

Can you explain more of the "why" behind this statement?  To be clear, we're talking about Ctrl-+/- (i.e., "full-page zoom") rather than the pinch-to-zoom feature of touch interfaces (i.e., page scale).  Typically, when the user uses Ctrl-+, everything on the page occupies more physical space on their monitor, including buttons and labels.  What does change, for example, are rounded corners, which have larger radii but smoother curves.

Today pinch-to-zoom and Ctrl-+/- do the same thing, yes? They show the same UI, in any case. I realize when touch events are exposed we can interpret pinch-to-zoom as an actual map zoom, which is our desire.

Sometimes!  This world is complicated.  Ctrl +/- increase/decrease the page zoom factor which is also controllable as 'Zoom' in the Chrome hot-dog menu.  Most of the time - on Android and Windows 8 touch devices pinching influences a different scale factor called the page scale that is orthogonal to page zoom.  On OS X (10.7+ iirc), pinching on some pointing devices (such as the trackpad on a macbook, some of their external mouse) is interpreted by chrome in a manner similar to Ctrl +/-.  This is pretty inconsistent.  Safari handles pinch gestures on OS X in a different way that's full of rounding errors and fail so let's not talk about that if we can help it.  The OS X behavior for pinch on some devices is really an outlier in the Chrome universe and we might revisit it to mean something else.

I haven't seen it linked in this thread yet, but I've found http://trac.webkit.org/wiki/ScalesAndZooms helpful for sorting out these different concepts.

Adam

Rick Byers

unread,
Jul 9, 2013, 6:51:50 PM7/9/13
to Adam Barth, James Robinson, Michael Davidson, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org
On Tue, Jul 9, 2013 at 6:49 PM, Adam Barth <aba...@chromium.org> wrote:
On Tue, Jul 9, 2013 at 3:48 PM, James Robinson <jam...@google.com> wrote:
On Tue, Jul 9, 2013 at 3:26 PM, Michael Davidson <m...@google.com> wrote:
James, I'm still digesting your mail and will respond. You might be right, my objections might not be correct.

Here's the argument put in another indirect way:  

CSS 'px' is defined in terms of visual angle not physical size, and so should vary with the viewing distance.  In particular, viewing a 96dpi screen at 2' should ideally be an identical experience to viewing a 192dpi screen at 1'.  While the browser can automatically determine the screen DPI, it has to rely on the user to specify the viewing distance, and we do this with browser zoom.  So browser zoom and device scale are two facets of the same problem - trying to get 'px' to have the correct visual angle for the user.

Unfortunately browser zoom brings with it a lot of baggage (not being a perfect abstraction, rounding issues, etc.), so whether we can actually unify with devicePixelRatio in practice is another question.  But in theory they should definitely be exposed to the web app using a common mechanism to avoid inconsistencies with the two mechanisms.

Rick

Michael Davidson

unread,
Jul 10, 2013, 12:21:02 PM7/10/13
to James Robinson, Adam Barth, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org
On Tue, Jul 9, 2013 at 3:48 PM, James Robinson <jam...@google.com> wrote:


Seeing a more detailed coastline implies zooming the map in. If you blow up an existing view to make it larger (as will happen if you adjust the devicePixelRatio), you won't necessarily see more detail because we don't have it. To see more detail you need to actually zoom in the map, not the browser. Zoomed in pages will get blurry geometry if devicePixelRatio is adjusted.

Isn't that an application issue, though?  If I have more physical pixels to display a certain amount of coastline, why wouldn't you load in whatever data is needed to render that coastline in a pretty way?  The size of UI elements should be determined by CSS pixels and the number of physical pixels used to render that UI element should be determined by the devicePixelRatio.  If for whatever reason (device scale, page zoom, whatever) I decide to map one CSS pixel to lots of physical pixels then I think the proper thing for maps to do is render both the UI elements and the vector content using lots of physical pixels.  I don't think it matters *why* a CSS pixel maps to many physical pixels, the expected rendering is the same.

There are two scenarios to imagine:

1) The user wants to "zoom in" on the map, for example to see a more detailed coastline. They do not want the labels (or other elements that are specified in CSS pixels, like road widths) to get bigger. This is what we typically think of as zooming in in an application sense.

2) The user wants the labels and other CSS pixel-sized things to get bigger. This is when they are likely to use browser zoom.

If they use browser zoom to make the CSS pixels bigger, but we load finer detail from the server (which might have things sized differently in CSS pixels because the details are finer), then we've done the user a disservice. 

This is really the heart of why we'd like to be able to tell what the zoom level is, so that we can distinguish these two cases. 

Put another way, if you're looking at the US, cranking up the browser zoom is not the appropriate way to see city-level detail. For one thing, the other UI elements on the page will be enormous. 

That said, I think that if you treat zooming the browser as adjusting the devicePixelRatio we will behave reasonably. You'll just get blurry tiles, which is probably OK. 

Michael

Brandon Jones

unread,
Jul 10, 2013, 12:58:55 PM7/10/13
to Michael Davidson, James Robinson, Adam Barth, Rik Cabanier, Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org
On Wed, Jul 10, 2013 at 9:21 AM, Michael Davidson <m...@google.com> wrote:

That said, I think that if you treat zooming the browser as adjusting the devicePixelRatio we will behave reasonably. You'll just get blurry tiles, which is probably OK. 

Why is this OK? If I, as a maps user, feel like I need bigger UI elements for accessibility reasons should I be expected to simply deal with blurry maps? That sounds like an extremely poor user experience. Also, the situation where you have zoomed out is more troubling: You get tiles that are 2x, 4x, 8x higher res than the screen can actually display, which is not only a waste of GPU resources and bandwidth but poses serious performance problems and can even cause device instability (we have to blacklist WebGL antialiasing on some Macs for exactly this reason.)

What you really want for pretty much any WebGL/Canvas app is behavior like the WebGL aquarium shows where zooming in an out resizes the HTML controls but the canvas always stays at a fixed resolution relative to the display. (I honestly don't know how they do the canvas size calculations here, but it works well.) 

--Brandon

John Mellor

unread,
Jul 10, 2013, 1:01:46 PM7/10/13
to Michael Davidson, James Robinson, Adam Barth, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, blink-dev, e...@chromium.org
> If they use browser zoom to make the CSS pixels bigger, but we load finer detail from the server (which might have things sized differently in CSS pixels because the details are finer), then we've done the user a disservice.

Sure - Maps ideally needs to have multiple ways of rendering fine detail. Lets suppose initially all of San Francisco fits inside one 128x128 CSS pixel map tile, and devicePixelRatio is 1x.

A) If the user uses the Maps controls to zoom in by a factor of 2, you now represent San Francisco with four adjacent 128x128 tiles. Each label you draw has the the same CSS font size as before, but takes up a smaller portion of the area of San Francisco, since SF is now represented using more tiles.

B) If instead the user views the same scene on a high dpi device with devicePixelRatio of 2x, then you need to render the map differently. As before, you now need to represent San Francisco with four adjacent 128x128 tiles (or a single 256x256 tile) - i.e. you should have the same fine detail on coastlines etc as in A. But your labels need to remain as big as they were in the unzoomed case in order to remain legible; and since the physical area of screen on which you are drawing this hasn't increased, that means you'll probably have to draw less labels than in A (or at least space them out less); in fact you probably want to draw the labels the same way you were drawing them in the unzoomed case.

Obviously having both A and B requires more work. You'd like to have one set of tiles per application zoom level, and instead you need a set of tiles per application zoom level per devicePixelRatio (at least 1x and 2x, preferably more). But you needed this already; high dpi devices are standard on mobile, and becoming more common on desktop too (e.g. the MacBook Pro Retina and Chromebook Pixel), and this is the correct way to render maps to them (modulo performance concerns).

If you don't want to do B, then it's better to serve blurry low-res tiles than to serve them the same tiles as in A (which would be illegible). But the map won't look crisp.

So how does browser zoom come into this? Exposing browser zoom by dynamically changing devicePixelRatio means it will soon be possible for Maps to use strategy B when browser zoom is in use, by transparently reusing the logic used for high-dpi devices, whereas previously Maps had no choice except to become blurry (as it wasn't possible to detect browser zoom).

PhistucK

unread,
Jul 10, 2013, 1:19:35 PM7/10/13
to Brandon Jones, Michael Davidson, James Robinson, Adam Barth, Rik Cabanier, Dana Jansens, Yoav Weiss, John Mellor, blink-dev, e...@chromium.org
Usually, in my (insignificant) experience with map services, you have limited zoom options (say, eight zoom levels for an island) due to tiles existing for every specific zoom level.
Supporting the detail level for every browser zoom level per map zoom level has severe implications which might not be realistic.
But perhaps (new or old) Google Maps is doing it differently and drawing maps using data and not using actual fixed images.


PhistucK

Michael Davidson

unread,
Jul 10, 2013, 1:20:24 PM7/10/13
to John Mellor, James Robinson, Adam Barth, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, blink-dev, e...@chromium.org
On Wed, Jul 10, 2013 at 10:01 AM, John Mellor <joh...@google.com> wrote:
B) If instead the user views the same scene on a high dpi device with devicePixelRatio of 2x, then you need to render the map differently. As before, you now need to represent San Francisco with four adjacent 128x128 tiles (or a single 256x256 tile) - i.e. you should have the same fine detail on coastlines etc as in A. But your labels need to remain as big as they were in the unzoomed case in order to remain legible; and since the physical area of screen on which you are drawing this hasn't increased, that means you'll probably have to draw less labels than in A (or at least space them out less); in fact you probably want to draw the labels the same way you were drawing them in the unzoomed case.

The way this works today is that we use a single 256x256 tile, but things like label size and road width are specified in CSS pixels, so it looks essentially the same. The server stores geometry with ~.25px detail, so you do get some finer detail, but you won't if your devicePixelRatio gets above 4. You get the same number of labels in the same position; SF still takes up 128x128 CSS pixels, we just have a bigger backing store.

We've done the work to make this work.

Brandon is correct, though, that if you get much larger than 2 in the ratio your viewports can get too large for the browser to render. At this point we could start using CSS to scale.

As far as blurriness when you zoom in, we could definitely make this better if it's a common case, although this would be easier to do if we actually knew the browser zoom. Right now we get labels as pre-rendered glyphs from the server at twice the size they're going to display. This lets us rotate them and get reasonable quality, as well as render them reasonably sharp at high DPI. To keep labels sharp at much larger ratios we'd have to re-request tiles with bigger labels, which would be costly.

Michael

John Mellor

unread,
Jul 10, 2013, 2:45:24 PM7/10/13
to Michael Davidson, James Robinson, Adam Barth, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, blink-dev, e...@chromium.org
Comments inline

On Wed, Jul 10, 2013 at 6:20 PM, Michael Davidson <m...@google.com> wrote:

On Wed, Jul 10, 2013 at 10:01 AM, John Mellor <joh...@google.com> wrote:
B) If instead the user views the same scene on a high dpi device with devicePixelRatio of 2x, then you need to render the map differently. As before, you now need to represent San Francisco with four adjacent 128x128 tiles (or a single 256x256 tile) - i.e. you should have the same fine detail on coastlines etc as in A. But your labels need to remain as big as they were in the unzoomed case in order to remain legible; and since the physical area of screen on which you are drawing this hasn't increased, that means you'll probably have to draw less labels than in A (or at least space them out less); in fact you probably want to draw the labels the same way you were drawing them in the unzoomed case.

The way this works today is that we use a single 256x256 tile, but things like label size and road width are specified in CSS pixels, so it looks essentially the same. The server stores geometry with ~.25px detail, so you do get some finer detail, but you won't if your devicePixelRatio gets above 4.

That should be fine. Chrome's max zoom is only 500%, and if a user is zooming in to more than 400% (or more than 200% on a 2x device), it's probably because they find the Maps UI (inc. labels) too small to read, and such users probably can't make out pixel-sized details, so don't need the tiles to be perfectly crisp.
 
You get the same number of labels in the same position; SF still takes up 128x128 CSS pixels, we just have a bigger backing store.

We've done the work to make this work.

Sounds perfect; I figured you'd already have this covered.

Brandon is correct, though, that if you get much larger than 2 in the ratio your viewports can get too large for the browser to render. At this point we could start using CSS to scale.

If you're talking about browser zoom, that shouldn't be a problem. Browser zoom (aka Ctrl-+) first makes the page narrower (fewer CSS pixels), then scales it back up to fit within the same space (unless the page has a min-width which gets hit, but Maps doesn't have a min-width). Hence the backing store takes up the same number of (physical) pixels as it did before zooming. See my earlier reply to Rik:

"If you had a 1024x768 device with initial devicePixelRatio of 1x, and you zoomed in to 1000%, we'd tell the page it was a 102x77 device with devicePixelRatio of 10x. So a website with a width:100%;height:100% canvas that scales the backing store by the devicePixelRatio would end up with a 102*10 x 77*10 = 1020x770 backing store, which is fine."

As far as blurriness when you zoom in, we could definitely make this better if it's a common case, although this would be easier to do if we actually knew the browser zoom. Right now we get labels as pre-rendered glyphs from the server at twice the size they're going to display. This lets us rotate them and get reasonable quality, as well as render them reasonably sharp at high DPI. To keep labels sharp at much larger ratios we'd have to re-request tiles with bigger labels, which would be costly.

Once we update the devicePixelRatio based on browser zoom, you'll be able to check the devicePixelRatio in onresize, and load appropriate assets using the exact same logic you use for high dpi displays. Of course you may choose not to load new assets if you already have ones that are close enough, and you probably want to wait until the user has settled on a particular zoom level (aka a particular page width), rather than loading new assets at every intermediate zoom level while the user is zooming (just like you wouldn't load new assets at every intermediate page width while the user is resizing the window).

Ben Vanik

unread,
Jul 10, 2013, 3:02:56 PM7/10/13
to John Mellor, Michael Davidson, James Robinson, Adam Barth, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, blink-dev, e...@chromium.org
I'm not sure I'm following what's being proposed here. I worry at comments like 'so [they] don't need the tiles to be perfectly crisp' because I don't at all agree with the idea that people who want UI elements larger don't care if things are blurrier.

If I'm building an application that uses <canvas> to draw its UI I want to be able to get the same behavior DOM elements do with respect to page zoom. That is, I want a rounded rect drawn in my canvas to be just as crisp as a <div> with rounded borders when my page zoom is >100%. Am I just misreading that it's considered ok if that's not possible?

I could of course accomplish scaling this in custom code with a custom options menu that let the user choose a 'UI scale' (as most native games do), however I'd much rather use the consistent page zoom mechanic built into browsers.

John Mellor

unread,
Jul 10, 2013, 3:35:25 PM7/10/13
to Ben Vanik, Michael Davidson, James Robinson, Adam Barth, Brandon Jones, Rik Cabanier, Dana Jansens, Yoav Weiss, blink-dev, e...@chromium.org
On Wed, Jul 10, 2013 at 8:02 PM, Ben Vanik <benv...@google.com> wrote:
I'm not sure I'm following what's being proposed here. I worry at comments like 'so [they] don't need the tiles to be perfectly crisp' because I don't at all agree with the idea that people who want UI elements larger don't care if things are blurrier.

That's not a limitation of exposing browser zoom via devicePixelRatio, that's just a limitation in Maps: they happen not to show higher resolution graphics when devicePixelRatio goes above 4x. I maintain that's probably fine, as someone who needs UI elements to be more than 400% of the usual size is unlikely to have pixel-perfect vision (and it wouldn't be worth loading enormous images just in case).

Most sites don't (currently) show higher resolution graphics when devicePixelRatio goes above 2x or 3x (as 3x is the highest pixel density of current devices). That's not quite perfect, as I imagine some users with 20/20 vision do occasionally zoom further than that; but bear in mind that these sites currently all just get blurry when browser zoom happens - so the fact that we get higher resolution graphics "for free" in some cases is still a nice bonus.

If I'm building an application that uses <canvas> to draw its UI I want to be able to get the same behavior DOM elements do with respect to page zoom. That is, I want a rounded rect drawn in my canvas to be just as crisp as a <div> with rounded borders when my page zoom is >100%. Am I just misreading that it's considered ok if that's not possible?

That will be possible (but currently isn't, without hacks). Just as when rendering on a high dpi device, you'll have to make the backing store of your canvas be size in CSS pixels * devicePixelRatio.

Brandon Jones

unread,
Jul 10, 2013, 5:22:09 PM7/10/13
to John Mellor, Ben Vanik, Michael Davidson, James Robinson, Adam Barth, Rik Cabanier, Dana Jansens, Yoav Weiss, blink-dev, e...@chromium.org
Some additional info: It was mentioned early on in the thread that Opera used to change devicePixelRatio based on browser zoom, but it appears that Firefox currently does as well. They have marked bugs requesting that this behavior be removed as "WONTFIX", so apparently they intend to keep it around. There are some community complaints about that (see linked bug's comments) but in light of the conversations here I feel more and more like this is the right way to go. 

Not only would scaling dPR be simpler for users than juggling two seemingly similar properties, it also has the nice side effect of "just working" for most canvas applications that have already been coded for High DPI displays. Compatibility with Firefox is a happy bonus.

--Brandon

Rik Cabanier

unread,
Jul 10, 2013, 11:44:55 PM7/10/13
to Brandon Jones, John Mellor, Ben Vanik, Michael Davidson, James Robinson, Adam Barth, Dana Jansens, Yoav Weiss, blink-dev, e...@chromium.org
I think a large part of the confusion is that people have been told to use devicePixelRatio to distinguish between high and low resolution displays and that the ratio was always the same.

The srcset attribute [1] was added so an image could load a high resolution. After this change, that spec should change so it loads a hi-res images when the ratio is equal or larger (instead of just equal)
Maybe this applies to media queries as well...

With this change, the browser might also have to swap hi-res or low res images when the user zooms.

James Robinson

unread,
Jul 11, 2013, 2:02:17 AM7/11/13
to Rik Cabanier, blink-dev, Brandon Jones, e...@chromium.org, Dana Jansens, Michael Davidson, John Mellor, Yoav Weiss, Ben Vanik, Adam Barth

window.devicePixelRatio has always been a value that can change at runtime. For instance, a user may drag a tab from a high-DPI monitor to a lower one or may change their system settings. Correctly authored pages should deal with this today no matter what page zoom does. The browser will handle updating which media queries match, so the author only had to worry about assets they manage themselves.

- James

Emil A Eklund

unread,
Jul 11, 2013, 2:04:48 AM7/11/13
to James Robinson, Rik Cabanier, blink-dev, Brandon Jones, Dana Jansens, Michael Davidson, John Mellor, Yoav Weiss, Ben Vanik, Adam Barth
Based on feedback here and elsewhere we no longer intent do implement
canvasResolution and instead intend to experiment with change
devicePixelRatio to take full-page-zoom into account. The details are
still being determined but will likely include a test-run of some sort
with 404 tracking for resources on pages using devicePixelRatio.
Reply all
Reply to author
Forward
0 new messages