Re: [css-houdini-drafts] [css-layout-api] Precision and rounding of the css-layout-api.

The Houdini Task Force just discussed `Layout precision`.

<details><summary>The full IRC log of that discussion</summary>
&lt;TabAtkins> Topic: Layout precision<br>
&lt;heycam> github: https://github.com/w3c/css-houdini-drafts/issues/817<br>
&lt;TabAtkins> github: https://github.com/w3c/css-houdini-drafts/issues/830<br>
&lt;heycam> iank_: I wanted to write down the problem clearly<br>
&lt;heycam> ... as specced now, with availableInlineSize: 10.13, the internal representations in each engine will be different<br>
&lt;heycam> ... I believe Blink/WebKit will be 10.125, Gecko will be 10.133, Edge will be 10.13<br>
&lt;heycam> ... similarly, say that child is auto sized, the value that you will get out in JS will be 10.125 for Blink/WebKit, some ugly values near 10.33333 for the others<br>
&lt;heycam> iank_: this is exposed right now<br>
&lt;heycam> ... if you set width:10.13px on an element, and you call getClientRects, you will get similar issues<br>
&lt;dbaron> Some of the ugliness is something that we could fix (by going directly from fixed-point to double rather than fixed-point to float to double)<br>
&lt;heycam> ... part of me thinks this is a non-issue<br>
&lt;heycam> iank_: the thing I worry about with rounding is that you'll get potential tearing<br>
&lt;glazou> LEAVEROU !!!<br>
&lt;heycam> ... imagine if you're doing a flexbox-like thing<br>
&lt;heycam> ... where you're distributing available space between children<br>
&lt;heycam> ... with the current API you won't get any subpixel tear, but if you round inputs and outputs you will<br>
&lt;heycam> ... you'll have to define the whole layout tree working on rounded precision mode<br>
&lt;heycam> eae: when you say rounding, you mean rounding to ints or to these values?<br>
&lt;heycam> iank_: if you round to int values, going in and out of the engine, you might see tearing<br>
&lt;heycam> ... if you're distributing some fractional space in a flexbox-like thing you can't do that<br>
&lt;heycam> ... also you'd need to specify the whole subtree works in rounded int precision<br>
&lt;heycam> smfr: what do you mean by tearing?<br>
&lt;heycam> iank_: if you try to position the two fragments side by side, you'd get a gap<br>
&lt;heycam> ... similarly, the second class there is if you happen to be distribtuing some space that wouldn't get a gap, the element might be smaller<br>
&lt;heycam> bz: to be clear, the container being smaller than the elements is a problem anyway<br>
&lt;heycam> ... even with floats<br>
&lt;heycam> iank_: the conversion to the js float thing, it's still possible to get tears accidentally<br>
&lt;heycam> ... but because the JS repr is high enough, converting from the internal fractional to JS to the internal fractional will result in the same fractional value<br>
&lt;heycam> chrishtr: what about pixel snapping?<br>
&lt;heycam> iank_: we only do that at paint<br>
&lt;heycam> ... we don't pixel snap any of the layout<br>
&lt;heycam> TabAtkins: yes we do<br>
&lt;heycam> ... border widths e.g.<br>
&lt;heycam> eae: borders are very special<br>
&lt;heycam> emilio: device pixels<br>
&lt;heycam> dbaron: there's a small class of things where you care about the with of the thing being the same across repeated occurrences<br>
&lt;heycam> ... borders, column rules, probably line heights as well<br>
&lt;heycam> ... but for most other things we don't do internal snapping<br>
&lt;heycam> ... you round to internal repr then snap edges to the nearest pixels<br>
&lt;heycam> iank_: the pixel snapping borders we can repr that value in the LayoutEdges object<br>
&lt;heycam> bz: presumably this is snapped to dev pixels here<br>
&lt;heycam> iank_: yes<br>
&lt;heycam> chrishtr: Blink currently snaps to CSS px<br>
&lt;heycam> eae: not really<br>
&lt;heycam> chrishtr: in cases where the device pixel ratio is incorporated into zoom it's device pixels<br>
&lt;heycam> ... long term intention is to use device pixels<br>
&lt;heycam> smfr: someone mentioned pixel snapping in border would happen at layout time? isn't purely a paint time operation?<br>
&lt;heycam> dbaron: for us it's a computed value time thing<br>
&lt;heycam> Rossen: for us it's also style<br>
&lt;heycam> ... it matters for lower values, 1, 2, 3, px<br>
&lt;heycam> ... but over 13, 14px it doesn't really matter<br>
&lt;heycam> dbaron: but it does matter for not getting the 1px gaps that you do the snapping before the layout calcs based on it<br>
&lt;heycam> ... if you do layout calcs based on a non pixel snapped border, then snap it later, you'll sometimes get 1px gaps or overlaps<br>
&lt;heycam> Rossen: so we'll do the layout with fractional border sizes<br>
&lt;heycam> ... then snap during paint<br>
&lt;heycam> dbaron: but you need to snap all the things next to that border during paint too or they won't line up<br>
&lt;heycam> Rossen: no they won't<br>
&lt;heycam> dbaron: then your system is more complex then ours<br>
&lt;dbaron> s/more complex then ours/different in more complex ways from ours/<br>
&lt;heycam> chrishtr: is the intention to spec the rounding?<br>
&lt;heycam> iank_: no<br>
&lt;heycam> chrishtr: or just things that UAs may do?<br>
&lt;heycam> iank_: my preference is to allow the UA to do internal rounding to the fractional repr and back<br>
&lt;heycam> ... main thing I want to avoid is the 1px tearing in alyouts<br>
&lt;heycam> chrishtr: it should at least be said if the left/right edge of things are the same number, there should not be a tear<br>
&lt;heycam> eae: can probably find a way to spec that<br>
&lt;heycam> chrishtr: you'd have to say the rounding and layout is the same, and that pixel snapping at paint time preserves that consistency<br>
&lt;heycam> iank_: yep<br>
&lt;heycam> Rossen: does that work for you Simon?<br>
&lt;heycam> smfr: yes I think so<br>
&lt;heycam> ... WebKit does some snapping of border widths as well<br>
&lt;heycam> ... I'm trying to understand when you're laying out fragments iteratively, does the browser tell you how much space is left?  a floating point input<br>
&lt;heycam> ... with custom layout, call layoutnextfragment 3 times<br>
&lt;heycam> ... each time an input is the remaining space?<br>
&lt;heycam> iank_: no you need to do that yourself<br>
&lt;heycam> ... so you'll have some available size, layout first child, subtract the size of it in the JS double<br>
&lt;heycam> smfr: was concerned about the conversions between jS doubles and the quantized values internally<br>
&lt;heycam> iank_: since it's handled by script it's always the JS doubles<br>
&lt;heycam> smfr: trying to think of cases where the rounding woul hurt you<br>
&lt;heycam> ... maybe comvining custom paint and layout<br>
&lt;heycam> ... you ask for a certain with with double precision<br>
&lt;heycam> ... then in paint ...<br>
&lt;heycam> iank_: I think previously you've brought up trying to fit into the one fractional unit, and some engines will leave a tiny fractional unit over<br>
&lt;heycam> ... in one you go into the next line, in another you'll have a skinny box for some reason<br>
&lt;heycam> ... I think it's a super edge case<br>
&lt;heycam> fremy: my impression is that the only case where this could be an issue is where you do the data sharing between custom layout<br>
&lt;heycam> ... you could share with full precision, and on the other side of the API you'd get it<br>
&lt;heycam> ... but I also don't expect this to be a problem<br>
&lt;TabAtkins> Found that the internal->JS->internal conversion is always accurate up to (10^15)px; at 10^16 there's a few rounding errors with Microsoft's precision.<br>
&lt;TabAtkins> http://software.hixie.ch/utilities/js/live-dom-viewer/saved/6318<br>
&lt;heycam> smfr: as a data point, this same problem also happens in media timing values<br>
&lt;heycam> ... currently they're all floating point, but there've been discussions about turning them into a rational type<br>
&lt;heycam> ... they're trying to solve some similar way here<br>
&lt;heycam> iank_: I think there's been talk in JS previously about having value types<br>
&lt;heycam> TabAtkins: they're not ready yet<br>
&lt;heycam> iank_: they've been vapourware for a while<br>
&lt;heycam> ... but the intention would be to work in that fractional type<br>
&lt;heycam> ... we shouldn't depend on that<br>
&lt;heycam> ... could imaging a future where JS does get that fractional type, see if it's compatible to change to that<br>
&lt;heycam> ... or otherwise add an option to opt in to it<br>
&lt;heycam> fremy: this transformation is a rounding<br>
&lt;heycam> iank_: it's a rounding to the fracctional repr<br>
&lt;heycam> fremy: can we floor rather thatn round?<br>
&lt;heycam> ... otherwise if you divide by 7, all your 7 column objects, you give them avail size / 7<br>
&lt;heycam> ... then you have a layout where each gets the size they can. if each is rounded up, the sum will be bigger than 100% and you'll wrap<br>
&lt;heycam> ... better to floor<br>
&lt;heycam> ... you make sure the sum will all fit<br>
&lt;heycam> TabAtkins: flooring starts loosing this internal -> JS double -> internal relationship more quickly<br>
&lt;heycam> eae: you can have a situation where you have a lot of space at the end<br>
&lt;heycam> ... which is also not desirable<br>
&lt;heycam> fremy: people writing the layout will pay attention to this<br>
&lt;heycam> smfr: has anyone tried using the prototpye to see if it's a problem?<br>
&lt;heycam> fremy: the prototype is only in one browser<br>
&lt;heycam> smfr: still possible to make layouts with hairline gaps<br>
&lt;heycam> fremy: I've not tried but I guess it's possible<br>
&lt;heycam> iank_: we can see if people run into it<br>
&lt;heycam> ... so far surmar and fremy haven't run into it<br>
&lt;heycam> smfr: your masonry layout wasn't trying to fit something into something with a border, not obvious there's a gap<br>
&lt;heycam> iank_: we can experiment with prototypes with borders to see if we can get hairline gaps<br>
&lt;heycam> fremy: grid has the opportunity to ahve these options, but you can position things at particular points, no wrapping<br>
&lt;heycam> ... even with 7 column grids, you place them before sizing, so it doesn't matter<br>
&lt;heycam> ... we should try the flexbox-like thing<br>
&lt;heycam> iank_: I think the action item on us is to play with our impl to see if we can break<br>
&lt;heycam> ... but sounds like people are relatively fine with the float repr and rounding to fractional units internally<br>
&lt;heycam> ... we can report back to the group<br>
&lt;TabAtkins> &lt;br dur=1hr><br>
&lt;heycam> github: end topic<br>
</details>


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

Received on Thursday, 25 October 2018 10:06:07 UTC