-
Notifications
You must be signed in to change notification settings - Fork 28.9k
RenderFlex
baseline intrinsics
#145483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RenderFlex
baseline intrinsics
#145483
Conversation
9c518bc
to
f1655ee
Compare
reason: 'Baseline metrics are only available after a full layout.', | ||
)); | ||
return Size.zero; | ||
return _computeSizes(constraints, ChildLayoutHelper.dryLayoutChild, ChildLayoutHelper.getDryBaseline).$1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using $1 could you give the items in the record meaningful names that could be used here? That would also remove the guesswork from figuring out what the "double" represents?
@@ -1419,33 +1420,46 @@ class RenderBaseline extends RenderShiftedBox { | |||
markNeedsLayout(); | |||
} | |||
|
|||
(Size, double) _computeSizes(covariant BoxConstraints constraints, ChildLayouter layoutChild, ChildBaselineGetter computeBaseline) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: shoud the last argument be named getBaseline (to avoid the confusion of whether the method passed in here should use the getBaseline methods over the computeBaseline methods)?
} | ||
final BoxConstraints childConstraints = constraints.loosen(); | ||
final Size childSize = layoutChild(child, childConstraints); | ||
final double childBaseline = computeBaseline(child, childConstraints, baselineType) ?? childSize.height; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my own understanding: There is a slight semantics change here, right? Previously, we would blow up if the child didn't have a baseline? Now, we assume the baseline to be the child's height. I suspect that this is fine, just making sure that this is intentional... (Maybe also worthwhile to add a test for this case)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right now it returns null if the child doesn't have a baseline.
if (result1 == null || result2 == null) { | ||
return this.baseline; | ||
} | ||
return this.baseline + result1 - result2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know, the new dry baseline and dry layout support is indirectly already tested, but I think this logic deserves some dedicated tests.
// A type that describes a 2D size along the main axis and the cross axis of a | ||
// [RenderFlex]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what this represents. Isn't every size by default aligned with the cross and main axis? What does it mean to "convert" a size to a direction?
Also: Should this just be a regular class with two fields: mainAxisExtent and crossAxisExtent? How do we benefit from wrapping Size here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's just ({double mainAxisExtent, double crossAxisExtent})
. Under the hood it's still a size so I don't have to reimplement methods like BoxConstraints.constrained(Size size)
.
|
||
static const _LayoutAxisDimensions empty = _LayoutAxisDimensions((axisSize: _AxisSize(Size.zero), ascentDescent: null)); | ||
|
||
// Updates the `current` _LayoutAxisDimensions with the dimensions of the given |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH, it is not clear to me what updating a _LayoutAxisDimensions with a _AxisSize means semantically? What does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replaced the class with _AscentDscent
and _AxisSize
. Both of them have a +
binary operator to add to the sizes when a new child is laid out.
} | ||
inflexibleSpace += mainSize; | ||
maxCrossSize = math.max(maxCrossSize, crossSize); | ||
Size computeIntrinsicCrossExtentForChild(RenderBox child, BoxConstraints constraints) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: these names seem inaccurate. It does not only return the extend, it returns a full size.
FWIW, I found this code easier to follow when it was implemented in terms of mainExtend and crossExtend and not in terms of width/height.
} | ||
|
||
return maxCrossSize; | ||
return _computeSizes(constraints: extentConstraints, layoutChild: computeIntrinsicCrossExtentForChild, computeBaseline: ChildLayoutHelper.getDryBaseline).size.crossAxisExtent; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here and elsewhere in this method: these long method calls should probably be formatted over multiple lines.
@@ -12,6 +12,84 @@ import 'layer.dart'; | |||
import 'layout_helper.dart'; | |||
import 'object.dart'; | |||
|
|||
// A type that describes a 2D size along the main axis and the cross axis of a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, I found the sizing and positioning algorithm way harder to follow with the _AxisSize and _LayoutAxisDimensions abstractions in place - compared to what it was before. Part of the problem is that after reading everything I couldn't explain what an _AxisSize or a _LayoutAxisDimensions is, which makes me think that these are not helpful abstractions?
// `defaultComputeDistanceToFirstActualBaseline` does not work even for | ||
// Columns, because the children reorder with VerticalDirection.up. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was it a bug that we used defaultComputeDistanceToFirstActualBaseline here before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. there's a test that would fail if this diff gets reverted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to revert this change because of G3 failures. Will create an issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2a676e7
to
8b7a1f5
Compare
e81b19d
to
1503b30
Compare
1503b30
to
899e331
Compare
@goderbauer I found it strange that the last flex child gets the remaining main axis extent instead of |
179eaaa
to
5e27bbb
Compare
5e27bbb
to
9fac18c
Compare
This does look strange in deed. I am not aware of a reason for this. But is it really worth it to change this since nobody seems to actually depend on it? Also, if we do change it, maybe we should do it in a dedicated change and not as part of this already pretty big change. |
I tried the change out in a separate PR and there appeared to be no internal failures. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
// | ||
// Baseline-aligned children contributes to the cross axis extent of a [RenderFlex] | ||
// differently from chidren with other [CrossAxisAlignment]s. | ||
extension type const _AscentDescent._((double ascent, double descent)? ascentDescent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This extension type I am still not sure about. What are we getting by wrapping a record here? Seems like this could easily be just a plain old data class with two fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type doesn't exist at runtime I guess? Probably not much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's still allocating a record at runtime. It shouldn't matter whether you allocate an instance of a class or a record? Since the extension type isn't giving us anything here my suggestion is to use the simpler concept of a regular class here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The (double, double)?
pair is probably still needed even if switch to using a class, because it needs an additional bit to represent the "no baselines" state.
spaceEvenly, | ||
spaceEvenly; | ||
|
||
// Returns (leadingSpace, betweenSpace). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Giving it proper names here would make the function signature self-documenting though and remove the need for this comment.
@@ -273,6 +273,11 @@ class RenderConstrainedBox extends RenderProxyBox { | |||
return height; | |||
} | |||
|
|||
@override | |||
double? computeDryBaseline(covariant BoxConstraints constraints, TextBaseline baseline) { | |||
return child?.computeDryBaseline(_additionalConstraints.enforce(constraints), baseline); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this call the get* method instead?
If this causes any issues in the future, it will be much easier to bisect and root cause it if those independent changes are submitted separately. |
well I tried to create a separate PR for the flex factor change, and when writing tests I realized I read the code wrong. There's no difference between the two except for minor floating point errors, which shouldn't make much of a difference because inconsequential overflow is ignored anyway. |
5b73103
to
eba50c5
Compare
flutter/flutter@89ea492...8528881 2024-03-29 34871572+gmackall@users.noreply.github.com Remove trailing commas in android dependency version checking gradle plugin (flutter/flutter#145718) 2024-03-29 polinach@google.com Upgrade leak_tracker. (flutter/flutter#145940) 2024-03-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from 8b893cb3b607 to 68aa9ba386e1 (2 revisions) (flutter/flutter#145946) 2024-03-29 103135467+sealesj@users.noreply.github.com Refactor flutter_plugins (flutter/flutter#145870) 2024-03-29 34871572+gmackall@users.noreply.github.com Point kotlin message in `gradle_errors.dart` towards new place where templates define the kotlin version (flutter/flutter#145936) 2024-03-29 engine-flutter-autoroll@skia.org Roll Flutter Engine from b917b24836fd to 8b893cb3b607 (1 revision) (flutter/flutter#145941) 2024-03-28 engine-flutter-autoroll@skia.org Roll Flutter Engine from c176d114d01e to b917b24836fd (4 revisions) (flutter/flutter#145938) 2024-03-28 31859944+LongCatIsLooong@users.noreply.github.com `RenderFlex` baseline intrinsics (flutter/flutter#145483) 2024-03-28 godofredoc@google.com Use reporter extended consistently. (flutter/flutter#145617) 2024-03-28 36861262+QuncCccccc@users.noreply.github.com Update tokens to v2.3.5 (flutter/flutter#145356) 2024-03-28 engine-flutter-autoroll@skia.org Roll Flutter Engine from a396dc1a03a9 to c176d114d01e (2 revisions) (flutter/flutter#145934) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC dit@google.com,rmistry@google.com,stuartmorgan@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Implements
RenderFlex
intrinsics calculation when children are baseline aligned in the cross axis.Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.