Commit 1e933299 authored by Andrew Comminos's avatar Andrew Comminos Committed by Commit Bot

Propagate definite height of single-line row flexboxes to child cross size

When we have a single-line definite height row flexbox with a column
flexbox as its child, we always relayout all children of the column
flexbox during LayoutLineItems with a zero-sized height being set.
This patch leverages the definite height of the row flexbox in order to
avoid a relayout of the column flexbox children.

Bug: 703512
Change-Id: I1f67efff3ebc67cdcce57dce2d2567e2abe13625
Reviewed-on: https://chromium-review.googlesource.com/c/1306404Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Commit-Queue: Andrew Comminos <acomminos@fb.com>
Cr-Commit-Position: refs/heads/master@{#607090}
parent bbb9f030
...@@ -1194,6 +1194,20 @@ void LayoutFlexibleBox::SetOverrideMainAxisContentSizeForChild(FlexItem& item) { ...@@ -1194,6 +1194,20 @@ void LayoutFlexibleBox::SetOverrideMainAxisContentSizeForChild(FlexItem& item) {
} }
} }
bool LayoutFlexibleBox::ChildLogicalHeightStretchesToFlexboxSize(
FlexItem& item) const {
if (IsMultiline())
return false;
if (!NeedToStretchChildLogicalHeight(*item.box))
return false;
if (HasAutoMarginsInCrossAxis(*item.box))
return false;
if (item.box->IntrinsicContentLogicalHeight() == -1)
return false;
return HasDefiniteLogicalHeight();
}
LayoutUnit LayoutFlexibleBox::StaticMainAxisPositionForPositionedChild( LayoutUnit LayoutFlexibleBox::StaticMainAxisPositionForPositionedChild(
const LayoutBox& child) { const LayoutBox& child) {
const LayoutUnit available_space = const LayoutUnit available_space =
...@@ -1350,6 +1364,35 @@ void LayoutFlexibleBox::LayoutLineItems(FlexLine* current_line, ...@@ -1350,6 +1364,35 @@ void LayoutFlexibleBox::LayoutLineItems(FlexLine* current_line,
child->SetShouldCheckForPaintInvalidation(); child->SetShouldCheckForPaintInvalidation();
SetOverrideMainAxisContentSizeForChild(flex_item); SetOverrideMainAxisContentSizeForChild(flex_item);
// We may have already forced relayout for orthogonal flowing children in
// computeInnerFlexBaseSizeForChild.
bool force_child_relayout =
relayout_children && !relaid_out_children_.Contains(child);
// Apply optimization 1 from section 9.8 for row flexboxes by overriding
// the logical height of stretchable children to the parent's definite
// height, if present (https://crbug.com/703512).
if (ChildLogicalHeightStretchesToFlexboxSize(flex_item)) {
LogicalExtentComputedValues computed_values;
ComputeLogicalHeight(computed_values);
LayoutUnit cross_axis_extent = computed_values.extent_;
DCHECK_NE(cross_axis_extent, LayoutUnit(-1));
// Compute the maximum possible cross axis extent available, since we
// don't optimize for intrinsically sized children.
LayoutUnit stretched_logical_height =
std::max(child->BorderAndPaddingLogicalHeight(),
cross_axis_extent - flex_item.CrossAxisMarginExtent());
LayoutUnit clamped_logical_height = child->ConstrainLogicalHeightByMinMax(
stretched_logical_height, child->IntrinsicContentLogicalHeight());
child->SetOverrideLogicalHeight(clamped_logical_height);
if (clamped_logical_height != child->LogicalHeight()) {
force_child_relayout = true;
}
}
// The flexed content size and the override size include the scrollbar // The flexed content size and the override size include the scrollbar
// width, so we need to compare to the size including the scrollbar. // width, so we need to compare to the size including the scrollbar.
if (flex_item.flexed_content_size != if (flex_item.flexed_content_size !=
...@@ -1360,10 +1403,6 @@ void LayoutFlexibleBox::LayoutLineItems(FlexLine* current_line, ...@@ -1360,10 +1403,6 @@ void LayoutFlexibleBox::LayoutLineItems(FlexLine* current_line,
// updateAutoMarginsInCrossAxis, we reset the margins here. // updateAutoMarginsInCrossAxis, we reset the margins here.
ResetAutoMarginsAndLogicalTopInCrossAxis(*child); ResetAutoMarginsAndLogicalTopInCrossAxis(*child);
} }
// We may have already forced relayout for orthogonal flowing children in
// computeInnerFlexBaseSizeForChild.
bool force_child_relayout =
relayout_children && !relaid_out_children_.Contains(child);
// TODO(dgrogan): Broaden the NG part of this check once NG types other // TODO(dgrogan): Broaden the NG part of this check once NG types other
// than Mixin derivatives are cached. // than Mixin derivatives are cached.
if (child->IsLayoutBlock() && if (child->IsLayoutBlock() &&
...@@ -1581,7 +1620,7 @@ void LayoutFlexibleBox::ApplyStretchAlignmentToChild(FlexItem& flex_item) { ...@@ -1581,7 +1620,7 @@ void LayoutFlexibleBox::ApplyStretchAlignmentToChild(FlexItem& flex_item) {
flex_item.cross_axis_size != child.LogicalHeight(); flex_item.cross_axis_size != child.LogicalHeight();
if (child.IsLayoutBlock() && if (child.IsLayoutBlock() &&
ToLayoutBlock(child).HasPercentHeightDescendants() && ToLayoutBlock(child).HasPercentHeightDescendants() &&
!CanAvoidLayoutForNGChild(child)) { !CanAvoidLayoutForNGChild(child) && !child.HasOverrideLogicalHeight()) {
// Have to force another relayout even though the child is sized // Have to force another relayout even though the child is sized
// correctly, because its descendants are not sized correctly yet. Our // correctly, because its descendants are not sized correctly yet. Our
// previous layout of the child was done without an override height set. // previous layout of the child was done without an override height set.
......
...@@ -182,6 +182,7 @@ class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock { ...@@ -182,6 +182,7 @@ class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock {
void ResetAutoMarginsAndLogicalTopInCrossAxis(LayoutBox& child); void ResetAutoMarginsAndLogicalTopInCrossAxis(LayoutBox& child);
void SetOverrideMainAxisContentSizeForChild(FlexItem&); void SetOverrideMainAxisContentSizeForChild(FlexItem&);
bool ChildLogicalHeightStretchesToFlexboxSize(FlexItem&) const;
void PrepareChildForPositionedLayout(LayoutBox& child); void PrepareChildForPositionedLayout(LayoutBox& child);
void LayoutLineItems(FlexLine*, bool relayout_children, SubtreeLayoutScope&); void LayoutLineItems(FlexLine*, bool relayout_children, SubtreeLayoutScope&);
void ApplyLineItemsPosition(FlexLine*); void ApplyLineItemsPosition(FlexLine*);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment