On optimized builds for all desktop platforms, `nsBlockFrame` is 192 bytes, and
`mFloats` is 16 bytes. With this patch, we can reduce the size of `nsBlockFrame`
to 176 bytes, saving 8.33% memory on every `nsBlockFrame` and its derived
subclasses allocated.
On a real webpage like https://en.wikipedia.org/wiki/Firefox, `about:memory`
shows that we allocate 0.36 MB of `nsBlockFrame` consistently. After this patch,
we allocate 0.33 MB, saving approximately 30 KB (0.36 MB * 8.33%) of the memory.
Differential Revision: https://phabricator.services.mozilla.com/D214046
On optimized builds for all desktop platforms, `nsBlockFrame` is 192 bytes, and
`mFloats` is 16 bytes. With this patch, we can reduce the size of `nsBlockFrame`
to 176 bytes, saving 8.33% memory on every `nsBlockFrame` and its derived
subclasses allocated.
On a real webpage like https://en.wikipedia.org/wiki/Firefox, `about:memory`
shows that we allocate 0.36 MB of `nsBlockFrame` consistently. After this patch,
we allocate 0.33 MB, saving approximately 30 KB (0.36 MB * 8.33%) of the memory.
Differential Revision: https://phabricator.services.mozilla.com/D214046
`BlockReflowState::mPushedFloats` is a pointer to `mBlock`'s pushed floats
list. However, it is only used in `AppendPushedFloatChain()`. We can just get
the pushed floats list directly.
This is a preparation for the next part that removes a possible scenario where
`mPushedFloats` can point to a removed pushed floats list.
Differential Revision: https://phabricator.services.mozilla.com/D213701
This is Fantasai's original patch, massively simplified:
* We now can switch whether we're a BFC dynamically (bug 1765615), which
simplifies the patch quite a lot.
* I removed some changes that were specific to pagination but were untested.
I left them as D202814, just in case we need some of those in the future.
All in all this makes the patch much more manageable.
Co-authored-by: Emilio Cobos Álvarez <[email protected]>
Differential Revision: https://phabricator.services.mozilla.com/D181858
A simple form of balance for short blocks, implemented by incrementally reducing
the effective inline-size used during line-breaking, up to the point where an
extra line would be created.
This fails the test text-wrap-balance-line-clamp-001.html, but it's unclear to me
if that test is correct (see https://github.com/w3c/csswg-drafts/issues/9310).
If we do want the behavior expected by that test, an additional patch to handle
the interaction with line-clamp will be required.
Depends on D187543
Differential Revision: https://phabricator.services.mozilla.com/D187544
A simple form of balance for short blocks, implemented by incrementally reducing
the effective inline-size used during line-breaking, up to the point where an
extra line would be created.
This fails the test text-wrap-balance-line-clamp-001.html, but it's unclear to me
if that test is correct (see https://github.com/w3c/csswg-drafts/issues/9310).
If we do want the behavior expected by that test, an additional patch to handle
the interaction with line-clamp will be required.
Depends on D187543
Differential Revision: https://phabricator.services.mozilla.com/D187544
A simple form of balance for short blocks, implemented by incrementally reducing
the effective inline-size used during line-breaking, up to the point where an
extra line would be created.
This fails the test text-wrap-balance-line-clamp-001.html, but it's unclear to me
if that test is correct (see https://github.com/w3c/csswg-drafts/issues/9310).
If we do want the behavior expected by that test, an additional patch to handle
the interaction with line-clamp will be required.
Depends on D187543
Differential Revision: https://phabricator.services.mozilla.com/D187544
* Rename `mBreakType` to `mFloatClearType` in nsLineBox and nsReflowStatus and
the methods around it.
* Rename `mBreakType` to `mClear` in nsStyleDisplay.
* Many other method parameters or local variables rename such as from
`aBreakType` to `aClearType`.
Differential Revision: https://phabricator.services.mozilla.com/D158276
This patch shouldn't change the behavior.
* Rename BlockReflowState's `mFloatBreakType` to `mTrailingClearFromPIF` since
it's the cached result of `FindTrailingClear()` from the block's prev-in-flow.
Note that `mTrailingClearFromPIF` can have `StyleClear::Line`, which is
not a float clear value. We'll remove `StyleClear::Line` in a later part to
make this 100% correct.
* Rename `nsLayoutUtils::CombineBreakType` to `CombineClearType` as well as its
arguments.
* Simplify FindTrailingClear()'s implementation.
Differential Revision: https://phabricator.services.mozilla.com/D158221
Nowadays, nsFloatCache stores no extra information but `nsIFrame*`, which makes
nsFloatCacheList and nsFloatCacheFreeList are just singly and doubly linked
list of frames, respectively.
Most of this patch is a plain rewrite to use nsTArray APIs. There are two
rewrite that need more explanation.
1. `BlockReflowState::mFloatCacheFreeList` is served as a temporarily list to
avoid extra allocations of nsFloatCache. It takes the ownership of floats
from a line via FreeFloats(), and later reuses the cache in AddFloat().
We don't need this anymore, so we remove it.
2. In `PlaceBelowCurrentLineFloats()`, the old code removes a float which
needs to be pushed to next continuation from `mBelowCurrentLineFloats`.
After looking through all of the floats, the remaining of
`mBelowCurrentLineFloats` are moved to the line because they belong to the
line. In this patch, rather than removing the pushed floats one by one from
`mBelowCurrentLineFloats`, I use a new list to collect the floats that need
to be added to the line, and just clear `mBelowCurrentLineFloats` at the
end of the method.
Differential Revision: https://phabricator.services.mozilla.com/D157976
This is a hack, sorta, similar to Chromium's:
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/layout/layout_object.cc;l=356;drc=312b74e385e6aba98ab31fd911238c0dc16b396c
except at computed-value rather than used-value time, because it's both
simpler to reason about and prevents lying in the computed style.
This fixes the relevant test-case, and matches closer what Chromium does,
by not creating anonymous flex items for all elements inside the
line-clamp context.
The behavior change is covered by the test changes. I had to also fix a
couple pre-existing bugs that were caught by tests, now that the
line-clamped block is the -webkit-box-styled element rather than an anonymous
flex item (and thus now had padding).
Depends on D155180
Differential Revision: https://phabricator.services.mozilla.com/D155181
The old code tweaks mIsTopOfPage in ReflowFloat(). However
`aAvailableSize.ISize()` (in containing block's writing-mode) always equals to
ContentISize() because it is computed via ComputeAvailableSizeForFloat().
Therefore, the only reason the floatRI's mIsTopOfPage can be `false` is when
some floats are already being placed, and we only check this in the
`!earlyFloatReflow` branch.
By tweaking mIsTopOfPage bit in FlowAndPlaceFloat(), we can also remove two
unused parameters in ReflowFloat().
This patch shouldn't change the behavior.
Differential Revision: https://phabricator.services.mozilla.com/D151457
There is some advantage to creating the float's ReflowInput in
FlowAndPlaceFloat().
1. ReflowFloat() doesn't need to output the float's margin and offset via the
output arguments. FlowAndPlaceFloat() can get them from the local ReflowInput
directly.
2. Since we are going to reflow the float, we have to create a ReflowInput
anyway. FloatMarginISize() can take the ReflowInput and be simplified. No need
to waste time to create a separate SizeComputationInput.
Also, delete the comment "Pass floatRS so the frame hierarchy can be
used (redoFloatRS has the same hierarchy)" because I believe it is obsolete.
This patch also lays the foundation for other improvements in the later patches.
Differential Revision: https://phabricator.services.mozilla.com/D151455
The old code in AddFloat() used to call nsBlockFrame::ComputeFloatISize() to
compute a float's inline-size, compare it with current line's available
inline-size, and determine whether FlowAndPlaceFloat() should be called.
However, it doesn't handle an orthogonal float with an auto block-size.
Luckily, FlowAndPlaceFloat() already has logic dealing with orthogonal
floats (bug 1141867), so this patch defers the decision to place a float below
the current line until the float's margin inline-size is computed in
FlowAndPlaceFloat().
Differential Revision: https://phabricator.services.mozilla.com/D151209
This patch is a preparation for the next part, and doesn't change the behavior
yet.
FlowAndPlaceFloat() is used to return true and false. This patch changes its
return value `true` to `PlaceFloatResult::Placed` and `false` to
`PlaceFloatResult::ShouldPlaceInNextContinuation`.
In the next part, we'll move the logic dealing with "below the current line
floats" into FlowAndPlaceFloat(), and make it return
`PlaceFloatResult::ShouldPlaceBelowCurrentLine`.
Differential Revision: https://phabricator.services.mozilla.com/D151208
First of all, `nsBlockFrame::AdjustFloatAvailableSpace()` is misleading. It
doesn't adjust the argument `aFloatAvailableSpace` at all, nor does it use any
fields in nsBlockFrame. It simply returns the available space in the parent
block's content area. Thus, I move it into BlockReflowState, and have it return
the available size rather than a rect because a size is sufficient for reflowing
a float.
Also, nsBlockFrame::ReflowFloat() only cares about the available size, but not
the position of the available space, so it is sufficient to pass a LogicalSize
computed by the new method ComputeAvailableSizeForFloat().
In FlowAndPlaceFloat(), there is a loop searching for a wide enough band to
place the float. We don't need to adjust availSize every time mBCoord is changed
in the loop. We can just call ComputeAvailableSizeForFloat() to get a new
available size before reflowing the float in the `!earlyFloatReflow` branch.
This patch shouldn't change the behavior.
Differential Revision: https://phabricator.services.mozilla.com/D151207
In FlowAndPlaceFloat(), condense two identical assertions about float frame
parent into one.
FlowAndPlaceFloat() calls ReflowFloat() only once, either an early reflow (when
`earlyFloatReflow` is `true`) or a late reflow (when `earlyFloatReflow` is
`false`), so the reflow status is always fresh.
Differential Revision: https://phabricator.services.mozilla.com/D151203
Without this patch, the test case, floats-aspect-ratio-001.html, hangs because:
1. The initial float available space is correct, and its size is 100px x 50px.
And the bfc element is "width: auto; height: auto; aspect-ratio: 1/1;".
So its width and height depend on the available space.
2. And then, we try to get a new available area based on the height of
the bfc element (note: its size is 100px x 100px). However, we get an
invalid zero-width float available area which is occupied by the element
with float:right (i.e. the pink one), in the first band, and the size of
float available space is 0px x 100px. This makes the size of bfc element
become 0px x 0px when checking `FloatAvoidingBlockFitsInAvailSpace()`.
So it always fits in this float available area. And because we get two
different available areas in the first band (i.e. same `aBCoord`), so we
don't go into the break condition, and contine to get a new
`childReflowInput`, and then go to the next iteration.
3. In the 2nd loop, we try to get a new float available space by the
height of the bfc element (note: its size is 0px x 0px now because
the width of current float available space is 0px), so the
new float available space is 100px x 0px, and the bfc element fits in
this available area, but again, we have two different available
areas, so we still don't go into the break condition. Instead, we use
the new available area to compute the childReflowInput for the next
iteration, and now the size of the bfc element becomes 100px x 100px.
And then we go back to the state of (2).
4. So the bfc element enters a resize oscillation due to the invalid
float available space together with the aspect-ratio and auto sizes
(i.e. "widht: auto; height: auto;") I think. And the invalid float
available space also let |AvailableSpaceShrunk()| be unexpected because
we hit an assertion: "ASSERTION: available space should not grow on the
start side and shrink on the end side".
A possible way is to make sure we get a suitable float available area for
`floatAvoidingBlock`, so this can avoid the bfc element from entering
a resize oscillation.
Note:
1. bfc means block-formatting-context, and its variable name is
`floatAvoidingBlock` in nsBlockFrame.cpp.
2. We don't need to check zere or positive inline size for the float
available space because `AvailableSpaceShrunk()` should make sure we
leave the loop properly.
See https://phabricator.services.mozilla.com/D145524#4766290 for the
the example when the inline size is exactly zero.
Besides, we also fix contain-inline-size-bfc-floats-001.html with this
patch.
Differential Revision: https://phabricator.services.mozilla.com/D145524
This patch does not impact behavior.
Before this patch, these variables' names are abbreviations of their original
type-name, "nsCSSOffsetState". We renamed that type to SizeComputationInput in
bug 1277129, and this patch just updates the variable-names to reflect that
renaming, so that now they're abbreviations of the new type-name, rather than
the old one.
This patch also takes this opportunity to move these variables declarations
closer to their usage, and in one case we convert a variable to be a temporary
anonymous value in the middle of another assignment.
Differential Revision: https://phabricator.services.mozilla.com/D145137
This patch does not impact behavior; it's just a handful of renamings and
documentation-updates.
Before this patch, our float-handling code has a bunch of variables and
functions with "replaced" in the name. But in fact these aren't necessarily
replaced; they're just block-level frames that elicit a "false" return-value
from "BlockCanIntersectFloats". This category *includes* replaced boxes, and
it also includes frames that establish a formatting context, e.g.:
scrollframes, flex/grid containers, flow-root, table.
This patch seeks to clarify things by renaming these to refer to the fact that
they "avoid" floats, e.g. s/replacedBlock/floatAvoidingBlock/.
I've included a comment to reference this term in the BlockCanIntersectFloats()
documentation (note that the "can intersect" concept is the opposite of
"avoids"). I've also renamed a few "aFrame" variables to
"aFloatAvoidingBlock", for a few functions that are explicitly dealing with
this scenario and only expect to be passed frames that are in this category.
Differential Revision: https://phabricator.services.mozilla.com/D145131
This patch is generated via:
```
rg -l 'BlockReflowInput' layout/ | xargs sed -i 's/BlockReflowInput/BlockReflowState/g'
```
Manual fixes are in the next part.
Differential Revision: https://phabricator.services.mozilla.com/D139439