Bug 1803861 - Implement nsPageFrame::FirstContinuation and nsPageContentFrame::FirstContinuation with constant complexity r=dholbert

Differential Revision: https://phabricator.services.mozilla.com/D163759
This commit is contained in:
Emily McDonough 2022-12-06 00:07:09 +00:00
Родитель f75d08ab66
Коммит 7a576abe2d
5 изменённых файлов: 59 добавлений и 1 удалений

Просмотреть файл

@ -421,6 +421,21 @@ void nsPageContentFrame::EnsurePageName() {
SetComputedStyleWithoutNotification(pageContentPseudoStyle);
}
nsIFrame* nsPageContentFrame::FirstContinuation() const {
const nsContainerFrame* const parent = GetParent();
MOZ_ASSERT(parent && parent->IsPageFrame(),
"Parent of nsPageContentFrame should be nsPageFrame");
// static cast so the compiler has a chance to devirtualize the call.
const auto* const pageFrameParent = static_cast<const nsPageFrame*>(parent);
nsPageContentFrame* const pageContentFrame =
static_cast<const nsPageFrame*>(pageFrameParent->FirstContinuation())
->PageContentFrame();
MOZ_ASSERT(pageContentFrame && !pageContentFrame->GetPrevContinuation(),
"First descendent of nsPageSequenceFrame should not have a "
"previous continuation");
return pageContentFrame;
}
#ifdef DEBUG_FRAME_DUMP
nsresult nsPageContentFrame::GetFrameName(nsAString& aResult) const {
return MakeFrameName(u"PageContent"_ns, aResult);

Просмотреть файл

@ -51,6 +51,13 @@ class nsPageContentFrame final : public mozilla::ViewportFrame {
void EnsurePageName();
// The default implementation of FirstContinuation in nsSplittableFrame is
// implemented in linear time, walking back through the linked list of
// continuations via mPrevContinuation.
// For nsPageContentFrames, we can find the first continuation through the
// frame tree structure in constant time.
nsIFrame* FirstContinuation() const final;
#ifdef DEBUG_FRAME_DUMP
// Debugging
nsresult GetFrameName(nsAString& aResult) const override;

Просмотреть файл

@ -656,6 +656,35 @@ float nsPageFrame::ComputePageSizeScale(const nsSize aContentPageSize) const {
return scale;
}
nsIFrame* nsPageFrame::FirstContinuation() const {
// Walk up to our grandparent, and then to down the grandparent's first
// child, and then that frame's first child.
// At every step we assert the frames are the type we expect them to be.
const nsContainerFrame* const parent = GetParent();
MOZ_ASSERT(parent && parent->IsPrintedSheetFrame(),
"Parent of nsPageFrame should be PrintedSheetFrame");
const nsContainerFrame* const pageSequenceFrame = parent->GetParent();
MOZ_ASSERT(pageSequenceFrame && pageSequenceFrame->IsPageSequenceFrame(),
"Parent of PrintedSheetFrame should be nsPageSequenceFrame");
const nsIFrame* const firstPrintedSheetFrame =
pageSequenceFrame->PrincipalChildList().FirstChild();
MOZ_ASSERT(
firstPrintedSheetFrame && firstPrintedSheetFrame->IsPrintedSheetFrame(),
"Should have at least one child in nsPageSequenceFrame, and all "
"children of nsPageSequenceFrame should be PrintedSheetFrames");
nsIFrame* const firstPageFrame =
static_cast<const nsContainerFrame*>(firstPrintedSheetFrame)
->PrincipalChildList()
.FirstChild();
MOZ_ASSERT(firstPageFrame && firstPageFrame->IsPageFrame(),
"Should have at least one child in PrintedSheetFrame, and all "
"children of PrintedSheetFrame should be nsPageFrames");
MOZ_ASSERT(!firstPageFrame->GetPrevContinuation(),
"First descendent of nsPageSequenceFrame should not have a "
"previous continuation");
return firstPageFrame;
}
void nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) {
nsDisplayList content(aBuilder);

Просмотреть файл

@ -81,6 +81,13 @@ class nsPageFrame final : public nsContainerFrame {
return ComputePageSizeScale(ComputePageSize());
}
// The default implementation of FirstContinuation in nsSplittableFrame is
// implemented in linear time, walking back through the linked list of
// continuations via mPrevContinuation.
// For nsPageFrames, we can find the first continuation through the frame
// tree structure in constant time.
nsIFrame* FirstContinuation() const final;
protected:
explicit nsPageFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
virtual ~nsPageFrame();

Просмотреть файл

@ -50,7 +50,7 @@ class nsSplittableFrame : public nsIFrame {
void SetNextContinuation(nsIFrame*) final;
// Get the first/last continuation for this frame.
nsIFrame* FirstContinuation() const final;
nsIFrame* FirstContinuation() const override;
nsIFrame* LastContinuation() const final;
#ifdef DEBUG