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

The CSS Working Group just discussed `device-pixel-border-box size`.

<details><summary>The full IRC log of that discussion</summary>
&lt;dael> Topic: device-pixel-border-box size<br>
&lt;dael> github: https://github.com/w3c/csswg-drafts/issues/3554#issuecomment-513045449<br>
&lt;dael> chrishtr: I'm the one that added it to the agenda<br>
&lt;dael> chrishtr: Main thing is resolving that this is a good approach to resolving responcive design for canvases.<br>
&lt;dael> chrishtr: Exact details of API can be followed up if agree on first step<br>
&lt;dael> jeff: The main thing on figuring out how this works is when we're thinking about scheduling we get a request at beginning of frameso can render webgl<br>
&lt;dael> jeff: Then main thing is take stock of width and height and that's usually when resize happens. I understand resize is only latter after raff when browser thinks we can take current layout<br>
&lt;dael> jeff: Then resize observer kicks off events and says to canvas you're resized. Issues for WebGL is that time is non-trivial. Late in the frame is hard to respond. You can realize in time for end of frame you rendered wrong and can do minor fix but can't render at new resize if observer after raff<br>
&lt;dael> chrishtr: Design of resize observer is to support this responsive design wehre decentralized action causes layout to change. if resize observer callback thinks sized changed non-canvas can change internal layout. If there's change it causes another layout. non-canvas the frame is twice as long and I think that's unavoidable.<br>
&lt;dael> chrishtr: Key is resizes are uncommon and it's only when user changes browser or orientation. COuld be doing layout animation but one that changes layout in every frame is perf problem<br>
&lt;dael> chrishtr: For webGL canvas it is an unavoidable slowdown<br>
&lt;dael> gregwhitworth: Is your issue that you may potentially miss a frame due to ascyn nature?<br>
&lt;dael> jeff: yeah<br>
&lt;dael> gregwhitworth: In current state you're sync. Feels you prefer have a performance thing where effecting frame vs the inverse<br>
&lt;dael> jeff: Not clear. If you rely on resize to tell you size and can't correct ahead of time it's hard to from the get go render frame with proper size<br>
&lt;dael> dbaron: Almost think for this use case resize-observer feels like wrong thing due to structure. Request animation frame was designed as a callback where can write layout information.<br>
&lt;dael> dbaron: One of the problems here is that raff, you get a raff [echo issues]<br>
&lt;astearns> s/raff/RAF/<br>
&lt;dael> dbaron: RAF is early in cycle and you can do it before layout. Layout as result of resize is after raf. Some things people do will flush layoutanyway and may layout twice. What you want here is to know canvas size and then do WebGL stuff<br>
&lt;dael> dbaron: If you want to know size of canvas can do resize-observer but it's designed to not flush layout and you might not need changes. In your use case you want to know this is the new size of box after alyout this cycle. Way you do that is use a sync method that flushes layout. Assuming 1 canvas<br>
&lt;dael> dbaron: What works for this use case is late in the RAF you get width and height of canvas, do WebGL work, don't use resize-observer. You did minium layout and get new canvas size<br>
&lt;dael> jeff: THat's what I've been centering on the solution for the common case. Where it gets muddy is part of the goal is device-pixel-border-box size. This is predominantely useful for canvas and WebGL.<br>
&lt;dael> jeff: A bing chunk of WebGL cases will have this workflow and not want resize-observer to get late resizes. Want the early layout to get box sizes.<br>
&lt;dael> jeff: What we'd be lacking is a way to sync query the device-pixel-border-box<br>
&lt;dael> jeff: Right now can get bounding client rects but it's not device pixel. That's what we want for WebGL.<br>
&lt;dael> jeff: Sounds like what we want is a a getBoundingDeviceRects or something sync to get pixel size. THen resize-observer is helpful for the other use cases. WebGL where they flush layout uses this othercommand<br>
&lt;bradk> I have to leave early. Bye!<br>
&lt;dael> chrishtr: Two things wrong about desc dbaron . Resize-observer is not async. Delivered immediately and cause another layout on same frame. Second is you can't actually know size of WebGL canvas even if you calls a sync method because there can be a different callback regisered by someone else that dirties layout.<br>
&lt;dael> chrishtr: Cna't do it the way you desc<br>
&lt;dael> dbaron: Those are fixable.<br>
&lt;dael> dbaron: Problem with resizeobserver is jeff's use case is a notification every time, not jsut resize.<br>
&lt;dael> dbaron: There's tricks to put yourself after next RAF. There's always problem of multi-observers.<br>
&lt;emilio> q+<br>
&lt;dael> dbaron: I think fundamentlly people want to do different things. THis prop makes a set of data only available in resize-observer but not in other ways and I don't think we want to put to use only resize-observer and other solutions<br>
&lt;dael> chrishtr: Good to only provide right information in right spot<br>
&lt;dael> dbaron: THink it'swrong spot<br>
&lt;dael> ken: resize-observer solves a lot of problems. Fantastic all browsers are impl v0 so that we can encourage everyone to use that. We'd like to recommend just use device-pixel-border-box if they want it exactly correct. sync apis have a host of problems like going to while loops to make layout settle down. resize-observer callback solves problems<br>
&lt;dael> jeff: It does, but it has remaining problems. If WebGL content wants to render...there's no way to deterministically always try and render correct frame size and not occationally double-paint<br>
&lt;dael> ken: I see that. THe live resizeing case is vanishingly small. You're moving a handle on the webcase. In the steady state you'll render nromally. If you end up double painting during live resize not end of world<br>
&lt;dael> Rossen_: A little under statement. Let's not diminish value of resizing and only put it ina corner. I can see multi frame being in same overall app layout each with own observer and then the drawback will be magnified. Let's not diminish effect of this<br>
&lt;bkardell_> if it was really only based on the size of the window, this feature wouldn't be necessary<br>
&lt;astearns> ack emilio<br>
&lt;dael> emilio: DId we figure out...what this device wants to add is a snapped rect. We figured for some combo of transforms that can create non-rect we also need to do transform calcs to get right device snap rect<br>
&lt;Rossen_> q?<br>
&lt;dael> emilio: It stashes a bunch of paint information onto an API. Want a reminder of what the web reprecussions of that discussion were<br>
&lt;smfr> q+<br>
&lt;dael> gregwhitworth: Talked about that asSanFran F2F. Most people thought okay beca'sescope was to canvas. Use case for canvas we won't have transforms and those types of scales so we don't need to go that far down stack. I think chrishtr said they are doing that. You are stashing, but primary case is you want pixel snapping because we're WebGL and want draw to pixel snapping and want ot know about resize to get perfect frame<br>
&lt;dael> gregwhitworth: Not opposed to dbaron where we can't do this anywhere else. But in this specific case where the resize gets a less clean seam and it's only on resize<br>
&lt;dael> gregwhitworth: To your point you have to shove painting knowledge into it. And you don't have all information.<br>
&lt;dael> chrishtr: I think transforms shouldn't apply at all<br>
&lt;dael> chrishtr: Exact def. or impl of pixel thing is different then other discussion. even if want to do something to instruct dev to always resize at beginning of frame you can't get bounding rect and multiple by pixel. Needs to be fixed or canvas can't render<br>
&lt;dael> jeff: Can do work to estimate eventual pixel boundries. I'm told people who know pixel snapping rules find it sketchy because rules aren't defined and we'd have to guess. Need a library that sniffs for UAs and gets right rules.<br>
&lt;gregwhitworth> they're not defined and vary by UA<br>
&lt;astearns> ack smfr<br>
&lt;dael> chrishtr: That's something where it's not going to be a great solution. Dev will hack around and that's not good<br>
&lt;dael> smfr: Remind people not all AU have pixel snapping before paint. We don't know before we go to paint. Even if added the device pixel we'd have to do a fake paint. THat's non-trivial for WK. And makes forced layout be even more expensive and they're already a source of perf issues. Hesitant to add an API that makes fake paints<br>
&lt;dael> jeff: Maybe alternative for WebGL usecase is if there were a callback following RAF like resize-observer but happens as early in the frame as possible and deterministicly every frame might be more workable if people object to a sync call for pixel layout<br>
&lt;dael> jeff: Solves double paints, gives webGL a way to know this is final size as long as nothing else changes it. As long a snothing else changes it is a problem we can't ever get around. might be the way forward there.<br>
&lt;smfr> https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering<br>
&lt;dael> smfr: HTML 5 has rendering steps. Where in those would callback fire?<br>
&lt;dael> jeff: I don't know<br>
&lt;dael> dbaron: Not sure I believe rendering steps in HTML5 make sense. I have an open issue to fix some of it.<br>
&lt;dael> dbaron: I support basic idea from Jeff. I think there's a similar Google proposal. Requires people have separate callbacks to separate writing layout and reading layout. In a refresh you want all writing before all reading<br>
&lt;dael> smfr: GOod idea except APIs we have make it easy to do wrong things. That only works is everyone does reading and writing at same time. Need a whole new set ofDOM APIs that read without forcing layout<br>
&lt;dael> dbaron: resize-observer feels designed for this, but it's a very particular solution<br>
&lt;dael> chrishtr: It's providing a responsive decentralized layout at one time.<br>
&lt;dael> chrishtr: What you desc about post layout callback if you have arbitrary code running it dirties layout<br>
&lt;dael> jeff: Not solvable<br>
&lt;dael> chrishtr: Resize-observer solves it. If you dirty layout should you layout again? If yes it's same as resize-observer.<br>
&lt;dael> jeff: Keep in mind my objections to have resize-observer isn't determatively fired. If we're trying to solve WebGL problem here, the solution shouldn't be half baked. There are problems with as exists resize-observer.<br>
&lt;dael> jeff: Main problem is we can't hit our frametimes if we get resize-observer late. Solutions are sync call or get device-pixel size and other is a resize call that always happens early in theframe. THat solves WebGL problem.<br>
&lt;dael> jeff: Getting confident WebGL problem isn't solved by current PR<br>
&lt;drousso> gtg :(<br>
&lt;dael> ken: USing resize-observer is simplier to explain. It gets 80-90% to solution. I realize poss of duplicate renders but that resize-observer takes into account relayouts that may happen is I think good design. I would advocate adding device-pixel-border-box  to resize observer API as a pretty good solution. We can iterate on it in the future to maybe get alyout earlier and less change of dup. frames<br>
&lt;dael> jeff: I have an 80% solution in hand already<br>
&lt;dael> ken: But it doesn'timpl the real pixel snapping the browsers do. Need access at app level<br>
&lt;dael> jeff: But my JS hack sounds like a better solution then the API<br>
&lt;dael> chrishtr: I don't htink that's true. resize-observer 100% solves get size of canavs<br>
&lt;dael> jeff: Do you think my rec. to have deterministic frame that says we finished layout is unworkable.<br>
&lt;dael> gregwhitworth: That's what it does.<br>
&lt;dael> jefBut we can't hit frame times because takes 12ms<br>
&lt;bkardell_> you always get 1 yes<br>
&lt;dael> dbaron: jeff wants a notification if it does or doesn't change size. For resize-observer when you register a new one do you always get one notifiation?<br>
&lt;dael> ??: Yeah<br>
&lt;dael> dbaron: What happens if you re-register resize observer every frame? Does that solve?<br>
&lt;dael> jeff: Depends how early it fires. Is it designed to fire as soon as possible?<br>
&lt;dael> gregwhitworth: Following layout for as accurate as poss. TO get pixel snapping need to get into paint. I don't understand as early as possible, has to be late to understand layout<br>
&lt;dael> dbaron: Wants it before he does WebGL painting to canvas<br>
&lt;tantek> sounds like maybe you want to both register a RO and a RAF callback, RO for the first notification, and RAF for no-resize notifications, and RO when there is an actual resize<br>
&lt;dael> gregwhitworth: Whichi s fine if not respond to resize. THat's what RAF does now<br>
&lt;dael> dbaron: What Jeff wants si to do layout, know what size results, and then paint to canvas<br>
&lt;dael> gregwhitworth: It's a callback to say hey we changed<br>
&lt;dael> dbaron: He want sto paint when no resize too<br>
&lt;tantek> painting when no resize is what RAF is for right?<br>
&lt;dael> chrishtr: yOu're desc a post-layout animation callback which doesn't exist. One objection is it gets in theway of running layout off main thread. resize prob has same problem<br>
&lt;gregwhitworth> tantek: that's my confusion<br>
&lt;gregwhitworth> if you don't want resize calls you add it to RAF<br>
&lt;gregwhitworth> and what chrishtr just said if you want both<br>
&lt;dael> chrishtr: Can get same thing except potentially slower during resize with resize-observer but need request animation callback as well.<br>
&lt;tantek> hah literally what I just said in IRC<br>
&lt;gregwhitworth> chrishtr: added it to TPAC<br>
&lt;dael> astearns: Nearly at time. I don't think we will resolve today, but good to have back and forth<br>
&lt;tantek> jeff, does that solve your use-case? using *both* RO and RAF?<br>
&lt;gregwhitworth> sorry, meant that to be a statement - not to you<br>
&lt;dael> astearns: Interesting to have fuller proposal for the post layout callback. I htink should continue in GH and come back.<br>
&lt;dael> many people: thanks<br>
</details>


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

Received on Wednesday, 24 July 2019 16:56:00 UTC