layout: Fix depends_on_block_constraints logic (#38318)

The logic was wrong, sometimes we weren't setting it to true on flex
containers that needed it, and then as a workaround we were setting it
to to true on flex items that didn't need it.

For example, this testcase had 5 cache misses when stretching the items,
now we will avoid laying them out again:
```html
<div style="display: flex">
  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>
</div>
```

Also, the workaround wasn't always working, e.g. it failed to stretch
the green element here:
```html
<div style="display: flex; min-height: 200px">
  <div>
    <div style="display: flex; height: 100%; background-color: red">
      <div style="width: 200px; background-color: green;"></div>
    </div>
  </div>
</div>
```

Testing: Adding new test
Fixes: #38023

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2025-07-29 11:59:54 +02:00 committed by GitHub
parent a5d4c49ec6
commit 3d2f0d1be5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 50 additions and 36 deletions

View file

@ -627,7 +627,6 @@ impl FlexContainer {
layout_context: &LayoutContext,
positioning_context: &mut PositioningContext,
containing_block: &ContainingBlock,
depends_on_block_constraints: bool,
lazy_block_size: &LazySize,
) -> CacheableLayoutResult {
let mut flex_context = FlexContext {
@ -953,6 +952,20 @@ impl FlexContainer {
.or(all_baselines.last),
};
// TODO: `depends_on_block_constraints` could be false in some corner cases
// in order to improve performance.
// - In a single-line column container where all items have the grow and shrink
// factors set to zero and the flex basis doesn't depend on block constraints,
// and `justify-content` is `start` or equivalent.
// This is unlikely because the flex shrink factor defaults to 1.
// - In a single-line row container where all items have `align-self: start` or
// equivalent, and the cross size doesn't depend on block constraints.
// This is unlikely because `align-self` stretches by default.
// - In a multi-line row container where `align-content` is `start` or equivalent,
// and no item cross size depends on block constraints.
// This is unlikely because `align-content` defaults to `stretch`.
let depends_on_block_constraints = true;
CacheableLayoutResult {
fragments,
content_block_size,
@ -1880,9 +1893,6 @@ impl FlexItem<'_> {
&item_as_containing_block,
containing_block,
self.preferred_aspect_ratio,
flex_axis == FlexAxis::Column ||
self.cross_size_stretches_to_line ||
self.depends_on_block_constraints,
&lazy_block_size,
);
let CacheableLayoutResult {
@ -2597,7 +2607,6 @@ impl FlexItemBox {
&item_as_containing_block,
flex_context.containing_block,
preferred_aspect_ratio,
false, /* depends_on_block_constraints */
&LazySize::intrinsic(),
)
.content_block_size