mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 01:08:39 +09:00
moebius#138: Optimize operations on root of deeply-nested frame tree
https://github.com/MoonchildProductions/moebius/pull/138
This commit is contained in:
parent
02f3024a9c
commit
85692a1198
23 changed files with 651 additions and 40 deletions
|
|
@ -154,7 +154,7 @@ RestyleManagerBase::ChangeHintToString(nsChangeHint aHint)
|
|||
"NeutralChange", "InvalidateRenderingObservers",
|
||||
"ReflowChangesSizeOrPosition", "UpdateComputedBSize",
|
||||
"UpdateUsesOpacity", "UpdateBackgroundPosition",
|
||||
"AddOrRemoveTransform"
|
||||
"AddOrRemoveTransform", "CSSOverflowChange",
|
||||
};
|
||||
static_assert(nsChangeHint_AllHints == (1 << ArrayLength(names)) - 1,
|
||||
"Name list doesn't match change hints.");
|
||||
|
|
@ -1070,6 +1070,67 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
|||
FramePropertyTable* propTable = presContext->PropertyTable();
|
||||
nsCSSFrameConstructor* frameConstructor = presContext->FrameConstructor();
|
||||
|
||||
// Handle nsChangeHint_CSSOverflowChange, by either updating the
|
||||
// scrollbars on the viewport, or upgrading the change hint to frame-reconstruct.
|
||||
for (nsStyleChangeData& data : aChangeList) {
|
||||
if (data.mHint & nsChangeHint_CSSOverflowChange) {
|
||||
data.mHint &= ~nsChangeHint_CSSOverflowChange;
|
||||
bool doReconstruct = true; // assume the worst
|
||||
|
||||
// Only bother with this if we're html/body, since:
|
||||
// (a) It'd be *expensive* to reframe these particular nodes. They're
|
||||
// at the root, so reframing would mean rebuilding the world.
|
||||
// (b) It's often *unnecessary* to reframe for "overflow" changes on
|
||||
// these particular nodes. In general, the only reason we reframe
|
||||
// for "overflow" changes is so we can construct (or destroy) a
|
||||
// scrollframe & scrollbars -- and the html/body nodes often don't
|
||||
// need their own scrollframe/scrollbars because they coopt the ones
|
||||
// on the viewport (which always exist). So depending on whether
|
||||
// that's happening, we can skip the reframe for these nodes.
|
||||
if (data.mContent->IsAnyOfHTMLElements(nsGkAtoms::body,
|
||||
nsGkAtoms::html)) {
|
||||
// If the restyled element provided/provides the scrollbar styles for
|
||||
// the viewport before and/or after this restyle, AND it's not coopting
|
||||
// that responsibility from some other element (which would need
|
||||
// reconstruction to make its own scrollframe now), THEN: we don't need
|
||||
// to reconstruct - we can just reflow, because no scrollframe is being
|
||||
// added/removed.
|
||||
nsIContent* prevOverrideNode =
|
||||
presContext->GetViewportScrollbarStylesOverrideNode();
|
||||
nsIContent* newOverrideNode =
|
||||
presContext->UpdateViewportScrollbarStylesOverride();
|
||||
|
||||
if (data.mContent == prevOverrideNode ||
|
||||
data.mContent == newOverrideNode) {
|
||||
// If we get here, the restyled element provided the scrollbar styles
|
||||
// for viewport before this restyle, OR it will provide them after.
|
||||
if (!prevOverrideNode || !newOverrideNode ||
|
||||
prevOverrideNode == newOverrideNode) {
|
||||
// If we get here, the restyled element is NOT replacing (or being
|
||||
// replaced by) some other element as the viewport's
|
||||
// scrollbar-styles provider. (If it were, we'd potentially need to
|
||||
// reframe to create a dedicated scrollframe for whichever element
|
||||
// is being booted from providing viewport scrollbar styles.)
|
||||
//
|
||||
// Under these conditions, we're OK to assume that this "overflow"
|
||||
// change only impacts the root viewport's scrollframe, which
|
||||
// already exists, so we can simply reflow instead of reframing.
|
||||
// When requesting this reflow, we send the exact same change hints
|
||||
// that "width" and "height" would send (since conceptually,
|
||||
// adding/removing scrollbars is like changing the available
|
||||
// space).
|
||||
data.mHint |= (nsChangeHint_ReflowHintsForISizeChange |
|
||||
nsChangeHint_ReflowHintsForBSizeChange);
|
||||
doReconstruct = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doReconstruct) {
|
||||
data.mHint |= nsChangeHint_ReconstructFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure to not rebuild quote or counter lists while we're
|
||||
// processing restyles
|
||||
frameConstructor->BeginUpdate();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue