WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
234917
[css-grid] Fix rounding of distributed free space to flexible tracks
https://bugs.webkit.org/show_bug.cgi?id=234917
Summary
[css-grid] Fix rounding of distributed free space to flexible tracks
zsun
Reported
2022-01-06 05:39:29 PST
The number of flexible tracks in a grid unevenly divides its leftover space, which causes truncated track sizes not being added as part of the grid available size. Affected WPT test - imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/flex-tracks-with-fractional-size.html
Attachments
Patch
(7.45 KB, patch)
2022-01-06 06:19 PST
,
zsun
no flags
Details
Formatted Diff
Diff
Patch
(6.24 KB, patch)
2022-01-10 05:59 PST
,
zsun
no flags
Details
Formatted Diff
Diff
Show Obsolete
(1)
View All
Add attachment
proposed patch, testcase, etc.
zsun
Comment 1
2022-01-06 06:19:23 PST
Created
attachment 448493
[details]
Patch
EWS Watchlist
Comment 2
2022-01-06 06:20:37 PST
This patch modifies the imported WPT tests. Please ensure that any changes on the tests (not coming from a WPT import) are exported to WPT. Please see
https://trac.webkit.org/wiki/WPTExportProcess
Darin Adler
Comment 3
2022-01-06 10:29:40 PST
Comment on
attachment 448493
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=448493&action=review
Looks good. The test is failing on GTK-WK2, which needs to be resolved before landing this. And there are some coding style issues.
> Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:733 > + double leftOverSize = 0;
Why double instead of float?
> Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:739 > + const double frShare = flexFraction * trackSize.maxTrackBreadth().flex() + leftOverSize;
Why do we compute a double here, and then convert it back to a float? The use of const here isn’t so great. All the local variables could be marked const, like trackIndex, oldBaseSize, and newBaseSize, but normally we don’t do that. Maybe this is Chromium coding style creeping into WebKit?
> Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:741 > + const LayoutUnit stretchedSize = LayoutUnit(frShare + std::numeric_limits<float>::epsilon());
Same thought on the use of const. I also would suggest writing auto instead of writing LayoutUnit twice on this line. The real goal here is to round rather than truncate, I think. Adding epsilon to do that is a risky hack, sure would be nice to find a better strategy. For example, if we had a LayoutUnit function that converted a float to a LayoutUnit using rounding instead of truncation (just add a call to std::round after multiplying by kFixedPointDenominator) that would be a better solution, and I think it would work. The rest of the patch could likely be the same. There are problems with using epsilon if we ever get to larger exponents, so typically we would use std::nextafter instead of epsilon as a basic coding style technique, but it would be better to use neither.
> Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:746 > + leftOverSize = std::max(frShare - stretchedSize.toDouble(), 0.0);
Again, why double instead of float? Mixing double and float is not great.
zsun
Comment 4
2022-01-10 05:59:50 PST
Created
attachment 448739
[details]
Patch
zsun
Comment 5
2022-01-10 06:15:53 PST
(In reply to Darin Adler from
comment #3
)
> Comment on
attachment 448493
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=448493&action=review
> > Looks good. > > The test is failing on GTK-WK2, which needs to be resolved before landing > this. >
Thanks very much for the review comments! Failing in GTK seems related to the calls of "reftest-wait" in the test script. I have raised
bug 235025
. This might need a separate investigation.
> And there are some coding style issues. > > > Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:733 > > + double leftOverSize = 0; > > Why double instead of float?
It is a double because flexfraction & flexFraction * trackSize.maxTrackBreadth().flex() are all doubles, right?
> > > Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:739 > > + const double frShare = flexFraction * trackSize.maxTrackBreadth().flex() + leftOverSize; > > Why do we compute a double here, and then convert it back to a float? >
I thought they are doubles all the way through. Maybe I have missed something here?
> The use of const here isn’t so great. All the local variables could be > marked const, like trackIndex, oldBaseSize, and newBaseSize, but normally we > don’t do that. Maybe this is Chromium coding style creeping into WebKit? > > > Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:741 > > + const LayoutUnit stretchedSize = LayoutUnit(frShare + std::numeric_limits<float>::epsilon()); > > Same thought on the use of const. I also would suggest writing auto instead > of writing LayoutUnit twice on this line. >
Updated.
> The real goal here is to round rather than truncate, I think. Adding epsilon > to do that is a risky hack, sure would be nice to find a better strategy. > For example, if we had a LayoutUnit function that converted a float to a > LayoutUnit using rounding instead of truncation (just add a call to > std::round after multiplying by kFixedPointDenominator) that would be a > better solution, and I think it would work. The rest of the patch could > likely be the same.
> I tried using std::round() in LayoutUnit.h, the overall leftovers seems exceeding what the test expected. The width of the image ends up with 106px rather than 100px. On the other thought, I feel that we might not need calling epsilon after all. The purpose of this patch is the recover the fractional part of the computation lost when we floor the stretched size to fit in a LayoutUnit. The leftover itself does this purpose, right?
> There are problems with using epsilon if we ever get to larger exponents, so > typically we would use std::nextafter instead of epsilon as a basic coding > style technique, but it would be better to use neither. > > > Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:746 > > + leftOverSize = std::max(frShare - stretchedSize.toDouble(), 0.0); > > Again, why double instead of float? Mixing double and float is not great.
Darin Adler
Comment 6
2022-01-10 09:00:41 PST
Comment on
attachment 448493
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=448493&action=review
>>> Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:739 >>> + const double frShare = flexFraction * trackSize.maxTrackBreadth().flex() + leftOverSize; >> >> Why do we compute a double here, and then convert it back to a float? >> >> The use of const here isn’t so great. All the local variables could be marked const, like trackIndex, oldBaseSize, and newBaseSize, but normally we don’t do that. Maybe this is Chromium coding style creeping into WebKit? > > I thought they are doubles all the way through. Maybe I have missed something here?
I think it was inaccurate to say "converted to float"; instead we add the "float epsilon", which itself is converted to a double. That is quite peculiar! I will look at the new patch to see what you chose to do.
Darin Adler
Comment 7
2022-01-10 09:02:47 PST
Comment on
attachment 448739
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=448739&action=review
> Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp:740 > + auto stretchedSize = LayoutUnit(frShare);
This truncates rather than rounding, so it rounds toward zero. Did we want to round in the more traditional way instead? We would do this with the equivalent of LayoutUnit::fromFloatRound, although I suppose we would want a double version of that? Looks like the problem is fixed without that, though, so it may be optional.
Darin Adler
Comment 8
2022-01-10 09:05:39 PST
(In reply to zsun from
comment #5
)
> I tried using std::round() in LayoutUnit.h, the overall leftovers seems > exceeding what the test expected. The width of the image ends up with 106px > rather than 100px.
LayoutUnit::round() rounds a LayoutUnit to a integer. We want to round to the nearest LayoutUnit value (1/64 of an integer), and we want to do that in the process of *creating* the LayoutUnit from a floating point value. Once the LayoutUnit is created the thing we wanted to round is already truncated.
> On the other thought, I feel that we might not need calling epsilon after > all. The purpose of this patch is the recover the fractional part of the > computation lost when we floor the stretched size to fit in a LayoutUnit. > The leftover itself does this purpose, right?
Sure, that sounds fine. I am not sure about the importance of rounding.
Radar WebKit Bug Importer
Comment 9
2022-01-13 05:40:16 PST
<
rdar://problem/87544943
>
EWS
Comment 10
2022-01-13 06:42:21 PST
Committed
r287977
(
246006@main
): <
https://commits.webkit.org/246006@main
> All reviewed patches have been landed. Closing bug and clearing flags on
attachment 448739
[details]
.
zsun
Comment 11
2024-11-04 02:20:19 PST
***
Bug 235025
has been marked as a duplicate of this bug. ***
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug