New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 879642 link

Starred by 2 users

Issue metadata

Status: Started
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android , Mac
Pri: 1
Type: Feature



Sign in to add a comment

Prototype adding snappedConcreteObjectSize to ResizeObserverEntry

Project Member Reported by kbr@chromium.org, Aug 31

Issue description

A longstanding problem in the WebGL specification is that it's not possible to measure the size of the canvas in device pixels. On high-DPI displays, which are effectively the norm today, this means that it's not possible to render pixel-accurate WebGL content to the screen.

There is now a proposal https://github.com/WICG/ResizeObserver/issues/61 adding this information to ResizeObserverEntry. As long as the page uses ResizeObserver to measure the size of the canvas, it would then theoretically be possible to understand the exact number of device pixels covered by the canvas, and size the canvas's backing store to be 1:1 with those pixels.

Could we try adding these fields to ResizeObserverEntry behind the --enable-experimental-web-platform-features flag? Then we could write a couple of examples and see how well they work.

 
FYI I'm planning to talk to atotic about it next week.
Status: Available (was: Untriaged)
After talking briefly with atotic@: is this information already available in the Element at the time LayoutBox::SizeChanged calls Element::SetNeedsResizeObserverUpdate? I thought that lower layers than Blink (e.g. cc) were also involved in snapping of layers to device pixels and that this was one of the reasons it was difficult to provide this information to JavaScript.

cc is generally not needed, if --enable-zoom-for-dsf is on. The information is available within Blink. The only caveat is composited transforms which are not integer translations,
but I would argue that case is not reasonable to solve, because composited transform
is (intentionally) trading off pixel control for speed.
Thanks Chris. Could you point out exactly what measurements from Element should be plumbed into these new fields?

Hoping --enable-zoom-for-dsf is reenabled soon after the performance implications are solved.

--enable-zoom-for-dsf is already on for Windows and Linux, it's Android that
got reverted this time around. Mac is still not there.

Re your latest question: I can do that, but I think it's getting ahead of things
a little...unless you're actually planning to prototype it right now?
Yes, I'm planning to hook it up to a WebGL example to understand whether this will in fact allow pixel-accurate rendering.

Ok.

In a method on Element, and assuming it's a canvas:

IntSize Element::SnappedConcreteObjectSize() {
  LayoutObject* obj = GetLayoutObject();

  // For LayoutHTMLCanvas, this will always evaluate to false.
  if (!obj->IsLayoutReplaced() || ! obj->HasLayer())
    return IntSize();

  LayoutRect rect = ToLayoutReplaced(obj)->ReplacedContentRect();
  rect.MoveBy(obj->FirstFragment().PaintOffset());

  return PixelSnappedIntRect(rect).Size();
}

See also:

https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/paint/html_canvas_painter.cc?type=cs&q=htmlcanvaspainter&sq=package:chromium&g=0&l=46

for more hints on why this is correct.
Labels: -Pri-2 OS-Android OS-Mac Pri-1
Bumping to P1 RFE. We have a customer who really wants to try this. Can anyone on the CC: list devote a couple of hours to hooking this up?

This little page has a 2D canvas and tries to draw single-pixel lines into the right-most column and bottom-most row. It works well on my desktop and high-DPI laptop, but it seems impossible to get right on my Pixel 2.

https://github.com/grhp/pixels

(My real-world use case is drawing pixel-perfect text into a WebGL canvas.)

I can help with ResizeObserver side of things. I'd need help with canvas sizing code:
- how it the rectangle defined (in terms of CSS)
- how to compute it in our code.

I have two large CLs I'd like to land before focusing on RO. Hoping to have them done by Sept 23rd.

I need to work on RO spec before TPAC, and prototype some ideas. This work would be complementary.


atotic@: thanks – it looks like chrishtr added proposed code for this in #8 above.

@kbr: that answers "how to compute it in our code".

The other part is knowing when it's value has changed. Since SnappedSize seems to be keying off regular size, I think we can reuse that code.
Cc: fs...@chromium.org kbr@chromium.org
Owner: atotic@chromium.org
Status: Assigned (was: Available)
Assigning for P-1. cc'ing fserb@ for canvas.
Note that there's another example attempting to do 1:1 mapping of the WebGL canvas's back buffer to device pixels in this thread:
https://github.com/KhronosGroup/WebGL/issues/2460

Status: Started (was: Assigned)

Sign in to add a comment