[csswg-drafts] [resize-observer] device-pixel-border-box size (#3554)

gregwhitworth has just created a new issue for https://github.com/w3c/csswg-drafts:

== [resize-observer] device-pixel-border-box size ==
device-pixel-border-box size

device-pixel-border-box size is Element's border-box size in device pixels. 
It is always an integer, as there are no fractional device pixels.
It can currently be approximated by `Math.round(borderBoxSize * window.devicePixelRatio)`, but it cannot be computed exactly, because native code uses a [different](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/geometry/layout_unit.h?sq=package:chromium&q=SnapSizeToPixel&g=0&l=687) rounding algorithm.

### Use case
This unusual size request comes from Chrome's WebGL canvas team. It solves the long standing WebGL developers problem: "How to create HiDPI canvas without moire pattern?".

The existing "best practice" for creating a HiDPI canvas is to set size of canvas context to a multiple of canvas's css width/height. Example:

    let cssWidth = 300, cssHeight = 200;
    let c = document.querySelector('canvas');
    c.style.width = cssWidth + "px";
    c.style.height = cssHeight + "px";
    let ctx = c.getContext("webgl2");
    ctx.width = cssWidth * window.devicePixelRatio;
    ctx.height = cssHeight * window.devicePixelRatio;

The webgl context will be HiDPI, one one canvas pixel should correspond to one device pixel.
But, because ctx.width is pixel snapped, ctx.width can differ from "true" device pixel width. This difference can cause visible moire patterns when rendered.

Because of this, WebGL team believes that web platform needs to provide an API for true device pixel width. 

### Discussion

This size has several interesting differences from others reported by ResizeObserver:
- use case is narrow: only useful for canvas Elements.
- changing only Element's position, _not_ size,  can cause device-pixel-size to change.

Q: Does this size belong to ResizeObserver, or should we create a diferent DOM API for it? 

I can't think of a clean API that would provide same functionality. Web developers must observe this size, and respond to its changes. ResizeObserver is the only size-observing API. Observing border-box size, and providing "devicePixelSize()" method will not work, because devicePixelSize could change without border-box changing.

Q: Should we observe device-pixel-size on all elements, or just canvas? 

Observing device-pixel-size comes with performance cost, because size must be checked when Element's position changes. For all other sizes, we do not need to check size when position changes. 
Weak preference: Only allow device-pixel-size observation for canvas.

Q: Should we report device-pixel-size on all elements, or just canvas?

Weak preference: make it canvas-only, because other elements cannot observe this size.

_Originally posted by @atotic in https://github.com/w3c/csswg-drafts/issues/3326#issuecomment-440041374_

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3554 using your GitHub account

Received on Friday, 25 January 2019 18:43:21 UTC