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

> In this example, the problem is not that the `.getDeviceRects()` API exists, but the second line: developer changes the size after querying the device pixel size. (what would developer expect to happen anyways?) With same rationale(?), one could claim that having e.g. a synchronous `String.length` API is bad since developer can change the string afterwards, leading to `String.length` to return the wrong value. The only way to fix this would be to move to purely functional programming.

I think the String analogy you gave is not all that useful in this case. The difference is that the DOM is laid out according to a global constraint algorithm that has many non-local effects that developers cannot feasibly predict in all cases. Even for the case of changes to the constraints that are introduced by the developer, in a large and dynamic web application it's very difficult to predict every single case that a size *or* offset of an element has changed. This is extra true because pixel snapping is (intentionally) not spelled out in the web specs.

In addition, there are cases where layout occurs even without the developer doing anything. Examples include the user resizing the page or changing zoom factors (you mentioned the former in your earlier comment, I know). Another example is a canvas embedded in a cross-origin iframe that has no idea what its containing frame might do, because that frame is controlled by a third party.

> 
> Having a resize event observer is fine and great, being able to get events from when a size changes is much nicer than polling, I don't argue against that, but I don't see why that would prevent having a `.getDeviceRects()` API?

It's because the return value of getDeviceRects is incorrect and misleading. There is also the problem of deciding whether to return a stale value from the prior frame, or an "up to date" (but not really) value that forces layout. The former doesn't work in cases where the canvas has just been resized since the last frame, and the latter doesn't work if something will happen after the call to getDeviceRects and before the next render to the screen. In addition, the forced layout caused by the latter approach is bad in and of itself, because forced layouts interfere with efficient pipelining of the rendering system (multi-threading, for example). And finally, polling is required on top of getDeviceRects, which is fundamentally worse than an observer which is called only when things actually change.

> I see forcing a layout being the correct thing to do, and not a problem. In 99% of applications with this canvas use case by the time the WebGL context is being initialized the DOM has already been set up and the DOM content is static.

As I mentioned above, I don't think this is accurate. Most web pages are quite dynamic these days, and even for cases where they are not, the user can cause layout changes.

> there does not really exist a more performant, correct, unambiguous nor self-documenting way to initialize the rendering backbuffer size and the GL context than the above code.

Code like the above is what sites already do, except for the getDeviceRects part. Instead they take the CSS sizing and multiply by devicePixelRatio. For sites that want to always be exactly aligned to device pixels no matter what, they can use a ResizeObserver to adjust when needed.

> It has a good guarantee that no badly sized temp GPU backbuffer resources will be allocated. Having a separate resize observer event to allow reacting to when user resizes the page or similar is then great as well (is the existing 'resize' event not already usable for that purpose?)

I agree that avoiding re-allocating GPU buffers is a good thing. Developers can reduce this by allocating the canvas buffer in a ResizeObserver at start, and only re-allocating it in a ResizeObserver subsequently.

ResizeObsever is for sure not a fully "direct" API, but it's the consequence of embedding an immediate-mode API like Canvas into the retained mode + inversion-of-control system that is HTML+CSS. Developers must do a certain amount (and really not all that much in this case) of work to adapt to this paradigm vs a fully immediate-mode they may be used to from prior experience.



-- 
GitHub Notification of comment by chrishtr
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3554#issuecomment-504497079 using your GitHub account

Received on Friday, 21 June 2019 16:58:15 UTC