Implement a mechanism to override style sizes when constructing ReflowInput
Categories
(Core :: Layout, task)
Tracking
()
Tracking | Status | |
---|---|---|
firefox87 | --- | fixed |
People
(Reporter: TYLin, Assigned: TYLin)
References
(Blocks 1 open bug)
Details
Attachments
(8 files)
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review |
Currently, when we want to compute sizes for a child frame by using certain restrictions (like treating block-size as 'auto'), or just want to tell the child frame to use a computed size, we use some customize code and ComputeSizeFlag
in nsIFrame::ComputeSize()
or nsContainerFrame::ComputeSizeWithIntrinsicDimensions()
. Or we just build a ReflowInput
and throw away computed inline-size or block-size by setting them afterwards.
I can think of some use cases that can be easier to implement if we have a mechanism to override style sizes when constructing ReflowInput.
- When resolving flex base size, we might need to replace the preferred main size with
flex-basis
property. Currently, we have similar logic in bothnsIFrame::ComputeSize()
andnsContainerFrame::ComputeSizeWithIntrinsicDimensions()
. - When measuring flex / grid item's content block-size, we use UseAutoBSize flag.
- Flex container can override main size & cross size for flex item.
I'm planning to add a struct containing StyleSize
s to ReflowInput's constructor, nsIFrame::ComputeSize
, etc, so a parent frame can have a easy way to tell a child to compute the size in a desirable way, and convert a few use case in flex container as a proof. There might be more opportunities to use the mechanism. Any callsite of SetComputedBSize
may be a good candidate.
Assignee | ||
Comment 1•5 years ago
|
||
The last consumer was removed in
https://hg.mozilla.org/mozilla-central/rev/2775681c72a3
Assignee | ||
Comment 2•5 years ago
|
||
This patch adds the struct as a parameter to various functions.
The struct is cached in ReflowInput so that we don't need to pass it
down to the internal method where nsIFrame::ComputeSize() is called.
In the subsequent patches, we'll use it to revise the implementation of
flex container's flex base size resolution, and size overrides.
Depends on D101791
Assignee | ||
Comment 3•5 years ago
|
||
Depends on D101793
Assignee | ||
Comment 4•5 years ago
|
||
Depends on D101794
Assignee | ||
Comment 5•5 years ago
|
||
FlexItem::StyleCrossSize() hasn't been used in this patch, but it will
be used in a later patch that revises size overrides in flex item's
final reflow.
Depends on D101795
Assignee | ||
Comment 6•5 years ago
|
||
We don't need to tweak ReflowIpnut flags as much as we did because
ReflowInput::InitResizeFlags().
Depends on D101796
Assignee | ||
Comment 7•5 years ago
|
||
ComputeSizeFlag::UseAutoISize
and ComputeSizeFlag::UseAutoBSize
[1] can also be converted by using StyleSizeOverride
at callsites, but the patch stack is getting large, so I decide to stop here. They can be done in other bugs assuming the idea of StyleSizeOverride
sounds good in general.
Comment 8•5 years ago
•
|
||
One high-level thing that feels a bit confusing to me... What sort of guarantees do we have here (or intend to ultimately have) about when/where these override args are used (in place of the style-system values)?
There are many functions whose signatures are being modified in part 2, but it doesn't look like we're changing all of their implementations, so I'm guessing that a lot of them just ignore these override values and probably still use the values from the style system -- is that right?
If so: that ignoring might be fine for the way we're using the override values right now (to simplify some flex layout sizing stuff), but it makes these functions a bit more confusing / unpredictable, perhaps... I'm curious if you have thoughts on this, or if I'm misunderstanding this to some extent. (Maybe this could be addressed to some extent with clearer documentation about what sorts of sizing operations will & won't use these values...)
Assignee | ||
Comment 9•5 years ago
|
||
(In reply to Daniel Holbert [:dholbert] from comment #8)
One high-level thing that feels a bit confusing to me... What sort of guarantees do we have here (or intend to ultimately have) about when/where these override args are used (in place of the style-system values)?
There are many functions whose signatures are being modified in part 2, but it doesn't look like we're changing all of their implementations, so I'm guessing that a lot of them just ignore these override values and probably still use the values from the style system -- is that right?
All the ComputeSize
and ComputeAutoSize
implementation that access inline and block sizes from style system should be audited, and should use the sizes provided by StyleSizeOverride
instead. Part 4 should already audit all of them.
But you are right that many replaced elements override ComputeAutoSize()
to provide their intrinsic size, and they don't look at style inline size, or ComputeSizeFlag::{UseAutoISize,UseAutoBSize}
. So we are already kind of in the same situation with the ComputeSizeFlag
.
If so: that ignoring maybe fine for the way we're using the override values right now (to simplify some flex layout sizing stuff), but it makes these functions a bit more confusing / unpredictable, perhaps... I'm curious if you have thoughts on this, or if I'm misunderstanding this to some extent. (Maybe this could be addressed to some extent with clearer documentation about what sorts of sizing operations will & won't use these values...)
Ideally, I would only add the struct StyleSizeOverride
to ReflowInput
and ComputeSize
, but not to ComputeAutoSize
. However, I discovered two issues while writing my patches.
- Due to the current contract of
nsIFrame::ComputeAutoSize
, the implementation may return garbage inline-size ifStylePosition()->ISize()
is not 'auto' [1]. So we still need to addStyleSizeOverride
to make them compute inline-size if the caller wants to override inline-size with 'auto' value. - Also, table wrapper's
ComputeAutoSize
can call table frame'sComputeSize
viaChildShrinkWrapISize()
[2]. If we want to let the size overrides to table wrapper really affects internal table, this seems necessary unless we want to have table wrapper to overrideComputeSize
instead.
And I agree that it's confusion to add StyleSizeOverride
to ComputeAutoSize
while most of the implementation don't even take a look at it. I wonder whether it makes senses to disallow the optimization in 1) and change the implementation of table wrapper's so that we don't need to provide StyleSizeOverride
to ComputeAutoSize
? Note 2) is just a preparation towards fixing <table>
as a flex item, and doesn't need to happen in this bug.
[1] https://searchfox.org/mozilla-central/rev/03224522336f60a1a61a87e1fcd4feb0a0315a9b/layout/generic/nsIFrame.h#2773-2775
[2] https://searchfox.org/mozilla-central/rev/03224522336f60a1a61a87e1fcd4feb0a0315a9b/layout/tables/nsTableWrapperFrame.cpp#386-387
Assignee | ||
Comment 10•5 years ago
|
||
FWIW, the only caller for nsIFrame::ComputeAutoSize
is in nsIFrame::ComputeSize
and it's called unconditionally, so it makes sense for implementation of ComputeAutoSize
to skip calculating inline size if nsIFrame::ComputeSize
won't use the value at all. Only nsContainerFrame and nsTextControlFrame have this optimization though.
Comment 11•5 years ago
|
||
Thanks, that makes sense. I think this approach is fine, as long as things are clearly documented. (RE the optimization that you mentioned: I would bet we lean on the nsContainerFrame "return garbage" optimization, to avoid computing the intrinsic widths of subtrees when we don't need to; so we probably shouldn't change that contract for item (1) at this point.)
BTW, it looks like your Part 1 patch needs a rebase, due to some contextual code (InitFrameType()
) having been recently removed in bug 1686310.
Assignee | ||
Comment 12•5 years ago
|
||
After Part 5 & Part 6, we don't need to override flex item's flex-basis
proprety or preferred main size in ComputeSize() and
ComputeSizeWithIntrinsicDimensions(), we can change the two style sizes
to references, and give both of them to shorter names.
Depends on D101797
Comment 13•5 years ago
|
||
Comment 14•5 years ago
|
||
Backed out 7 changesets (Bug 1686603) for causing crashtest assertion failures.
Backout link: https://hg.mozilla.org/integration/autoland/rev/40bc01de5e10a7ad5b19ba0fbdf43eaddde74a3e
Failure log: https://treeherder.mozilla.org/logviewer?job_id=327340673&repo=autoland&lineNumber=50299
Assignee | ||
Comment 15•5 years ago
|
||
See bug 1688115 for the description of an existing bug.
Depends on D102475
Assignee | ||
Comment 16•5 years ago
|
||
Part 8 adjusts the assertion count seen in comment 14.
Comment 17•5 years ago
|
||
Comment 18•5 years ago
•
|
||
Backed out for causing crashtest failures
backout: https://hg.mozilla.org/integration/autoland/rev/f8446e5139b64669581d5ba6667ea74f4a57ff87
failure log: https://treeherder.mozilla.org/logviewer?job_id=327780914&repo=autoland&lineNumber=18094
[task 2021-01-26T02:19:52.574Z] 02:19:52 INFO - REFTEST TEST-START | layout/style/crashtests/1383981.html
[task 2021-01-26T02:19:52.575Z] 02:19:52 INFO - REFTEST TEST-LOAD | file:///builds/worker/workspace/build/tests/reftest/tests/layout/style/crashtests/1383981.html | 3176 / 3880 (81%)
[task 2021-01-26T02:19:52.713Z] 02:19:52 INFO - AddressSanitizer:DEADLYSIGNAL
[task 2021-01-26T02:19:52.714Z] 02:19:52 INFO - =================================================================
[task 2021-01-26T02:19:52.715Z] 02:19:52 ERROR - ==1663==ERROR: AddressSanitizer: stack-overflow on address 0x7fff0b426d48 (pc 0x55a83d609056 bp 0x7fff0b427590 sp 0x7fff0b426d50 T0)
[task 2021-01-26T02:19:52.879Z] 02:19:52 INFO - #0 0x55a83d609056 in __asan_memcpy /builds/worker/fetches/llvm-project/llvm/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
[task 2021-01-26T02:19:55.635Z] 02:19:55 INFO - #1 0x7f41abfcbb54 in GetTransform /builds/worker/workspace/obj-build/dist/include/mozilla/gfx/2D.h:1580:40
[task 2021-01-26T02:19:55.635Z] 02:19:55 INFO - #2 0x7f41abfcbb54 in gfxFont::GetRoundOffsetsToPixels(mozilla::gfx::DrawTarget*) /builds/worker/checkouts/gecko/gfx/thebes/gfxFont.cpp:847:20
[task 2021-01-26T02:19:55.635Z] 02:19:55 INFO - #3 0x7f41abfe1e62 in bool gfxFont::SplitAndInitTextRun<unsigned char>(mozilla::gfx::DrawTarget*, gfxTextRun*, unsigned char const*, unsigned int, unsigned int, mozilla::unicode::Script, nsAtom*, mozilla::gfx::ShapedTextFlags) /builds/worker/checkouts/gecko/gfx/thebes/gfxFont.cpp:3068:28
[task 2021-01-26T02:19:55.656Z] 02:19:55 INFO - #4 0x7f41ac1562c1 in void gfxFontGroup::InitScriptRun<unsigned char>(mozilla::gfx::DrawTarget*, gfxTextRun*, unsigned char const*, unsigned int, unsigned int, mozilla::unicode::Script, gfxMissingFontRecorder*) /builds/worker/checkouts/gecko/gfx/thebes/gfxTextRun.cpp:2711:25
[task 2021-01-26T02:19:55.656Z] 02:19:55 INFO - #5 0x7f41ac128e2a in void gfxFontGroup::InitTextRun<unsigned char>(mozilla::gfx::DrawTarget*, gfxTextRun*, unsigned char const*, unsigned int, gfxMissingFontRecorder*) /builds/worker/checkouts/gecko/gfx/thebes/gfxTextRun.cpp:2572:7
[task 2021-01-26T02:19:55.656Z] 02:19:55 INFO - #6 0x7f41ac127499 in gfxFontGroup::MakeTextRun(unsigned char const*, unsigned int, gfxTextRunFactory::Parameters const*, mozilla::gfx::ShapedTextFlags, nsTextFrameUtils::Flags, gfxMissingFontRecorder*) /builds/worker/checkouts/gecko/gfx/thebes/gfxTextRun.cpp:2462:3
[task 2021-01-26T02:19:55.684Z] 02:19:55 INFO - #7 0x7f41b199b68e in BuildTextRunsScanner::BuildTextRunForFrames(void*) /builds/worker/checkouts/gecko/layout/generic/nsTextFrame.cpp:2566:28
[task 2021-01-26T02:19:55.684Z] 02:19:55 INFO - #8 0x7f41b1997916 in BuildTextRunsScanner::FlushFrames(bool, bool) /builds/worker/checkouts/gecko/layout/generic/nsTextFrame.cpp:1662:17
[task 2021-01-26T02:19:55.684Z] 02:19:55 INFO - #9 0x7f41b19a3f49 in BuildTextRuns /builds/worker/checkouts/gecko/layout/generic/nsTextFrame.cpp:1586:11
[task 2021-01-26T02:19:55.685Z] 02:19:55 INFO - #10 0x7f41b19a3f49 in nsTextFrame::EnsureTextRun(nsTextFrame::TextRunType, mozilla::gfx::DrawTarget*, nsIFrame*, nsLineList_iterator const*, unsigned int*) /builds/worker/checkouts/gecko/layout/generic/nsTextFrame.cpp:3003:7
[task 2021-01-26T02:19:55.685Z] 02:19:55 INFO - #11 0x7f41b19de3d2 in nsTextFrame::ReflowText(nsLineLayout&, int, mozilla::gfx::DrawTarget*, mozilla::ReflowOutput&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/nsTextFrame.cpp:9198:7
[task 2021-01-26T02:19:55.700Z] 02:19:55 INFO - #12 0x7f41b1952812 in nsLineLayout::ReflowFrame(nsIFrame*, nsReflowStatus&, mozilla::ReflowOutput*, bool&) /builds/worker/checkouts/gecko/layout/generic/nsLineLayout.cpp:878:40
[task 2021-01-26T02:19:55.721Z] 02:19:55 INFO - #13 0x7f41b171c74d in nsBlockFrame::ReflowInlineFrame(mozilla::BlockReflowInput&, nsLineLayout&, nsLineList_iterator, nsIFrame*, LineReflowStatus*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:4531:15
[task 2021-01-26T02:19:55.722Z] 02:19:55 INFO - #14 0x7f41b171b821 in nsBlockFrame::DoReflowInlineFrames(mozilla::BlockReflowInput&, nsLineLayout&, nsLineList_iterator, nsFlowAreaRect&, int&, nsFloatManager::SavedState*, bool*, LineReflowStatus*, bool) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:4333:5
[task 2021-01-26T02:19:55.722Z] 02:19:55 INFO - #15 0x7f41b171367e in nsBlockFrame::ReflowInlineFrames(mozilla::BlockReflowInput&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:4218:9
[task 2021-01-26T02:19:55.722Z] 02:19:55 INFO - #16 0x7f41b170c103 in nsBlockFrame::ReflowLine(mozilla::BlockReflowInput&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:3190:5
[task 2021-01-26T02:19:55.722Z] 02:19:55 INFO - #17 0x7f41b1703741 in nsBlockFrame::ReflowDirtyLines(mozilla::BlockReflowInput&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:2724:7
[task 2021-01-26T02:19:55.725Z] 02:19:55 INFO - #18 0x7f41b16fd291 in nsBlockFrame::Reflow(nsPresContext*, mozilla::ReflowOutput&, mozilla::ReflowInput const&, nsReflowStatus&) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:1375:3
[task 2021-01-26T02:19:55.726Z] 02:19:55 INFO - #19 0x7f41b1718eda in nsBlockReflowContext::ReflowBlock(mozilla::LogicalRect const&, bool, nsCollapsingMargin&, int, bool, nsLineBox*, mozilla::ReflowInput&, nsReflowStatus&, mozilla::BlockReflowInput&) /builds/worker/checkouts/gecko/layout/generic/nsBlockReflowContext.cpp:288:11
[task 2021-01-26T02:19:55.727Z] 02:19:55 INFO - #20 0x7f41b170fc11 in nsBlockFrame::ReflowBlockFrame(mozilla::BlockReflowInput&, nsLineList_iterator, bool*) /builds/worker/checkouts/gecko/layout/generic/nsBlockFrame.cpp:3854:11
Also SUMMARY: AddressSanitizer: stack-overflow /builds/worker/checkouts/gecko/gfx/thebes/gfxTextRun.cpp:2237 in gfxFontGroup::GetFirstValidFont(unsigned int, mozilla::StyleGenericFontFamily*)
Assignee | ||
Comment 19•5 years ago
|
||
In Part 8, I adjust the test expectations to skip bug 1383981's crashtests on AddressSanitizer. They were enabled in https://hg.mozilla.org/mozilla-central/rev/bf11f56d91cb7cf31564095d6e4467beeb8a4687, but they start to overflow the stack again because of this patch stack.
Comment 20•5 years ago
|
||
Comment 21•5 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/4568ea8e43b8
https://hg.mozilla.org/mozilla-central/rev/5279b71d0068
https://hg.mozilla.org/mozilla-central/rev/824d5be79299
https://hg.mozilla.org/mozilla-central/rev/4f25881a9ad0
https://hg.mozilla.org/mozilla-central/rev/812bd46387a9
https://hg.mozilla.org/mozilla-central/rev/5c374273e8a6
https://hg.mozilla.org/mozilla-central/rev/f9d763420a03
https://hg.mozilla.org/mozilla-central/rev/6316c4e1f46e
Description
•