From 6a49e31e078527c87d4cac9ccfd868d2da088762 Mon Sep 17 00:00:00 2001 From: Fedor Date: Wed, 10 Jun 2020 21:11:38 +0300 Subject: [PATCH] Complete improve performance of table drawing. --- layout/base/nsDisplayList.cpp | 65 ++-- layout/base/nsDisplayList.h | 75 +++-- layout/base/nsLayoutUtils.cpp | 6 +- layout/base/nsPresShell.cpp | 4 +- layout/forms/nsButtonFrameRenderer.cpp | 4 +- layout/forms/nsComboboxControlFrame.cpp | 13 +- layout/forms/nsComboboxControlFrame.h | 1 - layout/forms/nsFieldSetFrame.cpp | 15 +- layout/forms/nsFieldSetFrame.h | 1 - layout/forms/nsFileControlFrame.cpp | 3 +- layout/forms/nsFileControlFrame.h | 1 - layout/forms/nsFormControlFrame.h | 1 - layout/forms/nsGfxCheckboxControlFrame.cpp | 3 +- layout/forms/nsGfxCheckboxControlFrame.h | 1 - layout/forms/nsGfxRadioControlFrame.cpp | 3 +- layout/forms/nsGfxRadioControlFrame.h | 1 - layout/forms/nsHTMLButtonControlFrame.cpp | 5 +- layout/forms/nsHTMLButtonControlFrame.h | 1 - layout/forms/nsListControlFrame.cpp | 3 +- layout/forms/nsListControlFrame.h | 1 - layout/forms/nsProgressFrame.cpp | 3 +- layout/forms/nsProgressFrame.h | 1 - layout/forms/nsRangeFrame.cpp | 5 +- layout/forms/nsRangeFrame.h | 1 - layout/forms/nsSelectsAreaFrame.cpp | 10 +- layout/forms/nsSelectsAreaFrame.h | 2 - layout/forms/nsTextControlFrame.cpp | 3 +- layout/forms/nsTextControlFrame.h | 1 - layout/generic/nsBackdropFrame.cpp | 1 - layout/generic/nsBackdropFrame.h | 1 - layout/generic/nsBlockFrame.cpp | 31 +- layout/generic/nsBlockFrame.h | 1 - layout/generic/nsBulletFrame.cpp | 1 - layout/generic/nsBulletFrame.h | 1 - layout/generic/nsCanvasFrame.cpp | 7 +- layout/generic/nsCanvasFrame.h | 1 - layout/generic/nsColumnSetFrame.cpp | 3 +- layout/generic/nsColumnSetFrame.h | 1 - layout/generic/nsContainerFrame.cpp | 9 +- layout/generic/nsContainerFrame.h | 7 +- layout/generic/nsFirstLetterFrame.cpp | 3 +- layout/generic/nsFirstLetterFrame.h | 1 - layout/generic/nsFlexContainerFrame.cpp | 3 +- layout/generic/nsFlexContainerFrame.h | 1 - layout/generic/nsFrame.cpp | 204 +++++++----- layout/generic/nsFrameSetFrame.cpp | 7 +- layout/generic/nsFrameSetFrame.h | 1 - layout/generic/nsGfxScrollFrame.cpp | 60 ++-- layout/generic/nsGfxScrollFrame.h | 8 +- layout/generic/nsGridContainerFrame.cpp | 6 +- layout/generic/nsGridContainerFrame.h | 1 - layout/generic/nsHTMLCanvasFrame.cpp | 1 - layout/generic/nsHTMLCanvasFrame.h | 1 - layout/generic/nsIFrame.h | 13 +- layout/generic/nsImageFrame.cpp | 1 - layout/generic/nsImageFrame.h | 1 - layout/generic/nsInlineFrame.cpp | 3 +- layout/generic/nsInlineFrame.h | 1 - layout/generic/nsLeafFrame.h | 1 - layout/generic/nsPageFrame.cpp | 20 +- layout/generic/nsPageFrame.h | 1 - layout/generic/nsPlaceholderFrame.cpp | 1 - layout/generic/nsPlaceholderFrame.h | 1 - layout/generic/nsPluginFrame.cpp | 1 - layout/generic/nsPluginFrame.h | 1 - layout/generic/nsRubyTextFrame.cpp | 3 +- layout/generic/nsRubyTextFrame.h | 1 - layout/generic/nsSimplePageSequenceFrame.cpp | 10 +- layout/generic/nsSimplePageSequenceFrame.h | 1 - layout/generic/nsSubDocumentFrame.cpp | 34 +- layout/generic/nsSubDocumentFrame.h | 1 - layout/generic/nsTextFrame.cpp | 1 - layout/generic/nsTextFrame.h | 1 - layout/generic/nsVideoFrame.cpp | 18 +- layout/generic/nsVideoFrame.h | 1 - layout/generic/nsViewportFrame.cpp | 9 +- layout/generic/nsViewportFrame.h | 1 - layout/ipc/RenderFrameParent.cpp | 1 - layout/ipc/RenderFrameParent.h | 1 - layout/mathml/nsMathMLChar.cpp | 3 +- layout/mathml/nsMathMLContainerFrame.cpp | 4 +- layout/mathml/nsMathMLContainerFrame.h | 1 - layout/mathml/nsMathMLSelectedFrame.cpp | 5 +- layout/mathml/nsMathMLSelectedFrame.h | 1 - layout/mathml/nsMathMLmencloseFrame.cpp | 3 +- layout/mathml/nsMathMLmencloseFrame.h | 1 - layout/mathml/nsMathMLmfencedFrame.cpp | 3 +- layout/mathml/nsMathMLmfencedFrame.h | 1 - layout/mathml/nsMathMLmfracFrame.cpp | 3 +- layout/mathml/nsMathMLmfracFrame.h | 1 - layout/mathml/nsMathMLmoFrame.cpp | 3 +- layout/mathml/nsMathMLmoFrame.h | 1 - layout/mathml/nsMathMLmrootFrame.cpp | 3 +- layout/mathml/nsMathMLmrootFrame.h | 1 - .../position-relative/1409114-1-ref.html | 12 + .../reftests/position-relative/1409114-1.html | 11 + .../reftests/position-relative/1409114-2.html | 13 + .../reftests/position-relative/1409114-3.html | 13 + .../reftests/position-relative/reftest.list | 3 + ...llapse-opacity-table-column-group-ref.html | 6 +- ...der-collapse-opacity-table-column-ref.html | 6 +- ...parate-opacity-table-column-group-ref.html | 6 +- ...der-separate-opacity-table-column-ref.html | 6 +- layout/reftests/table-background/reftest.list | 3 + .../table-col-overlapping-ref.html | 28 ++ .../table-col-overlapping.html | 28 ++ .../table-col-span-1-ref.html | 15 + .../table-background/table-col-span-1.html | 15 + layout/svg/SVGFEUnstyledLeafFrame.cpp | 1 - layout/svg/SVGTextFrame.cpp | 1 - layout/svg/SVGTextFrame.h | 1 - layout/svg/nsSVGClipPathFrame.h | 1 - layout/svg/nsSVGContainerFrame.cpp | 3 +- layout/svg/nsSVGContainerFrame.h | 2 - layout/svg/nsSVGFilterFrame.h | 1 - layout/svg/nsSVGForeignObjectFrame.cpp | 3 +- layout/svg/nsSVGForeignObjectFrame.h | 1 - layout/svg/nsSVGMarkerFrame.h | 1 - layout/svg/nsSVGMaskFrame.h | 1 - layout/svg/nsSVGOuterSVGFrame.cpp | 3 +- layout/svg/nsSVGOuterSVGFrame.h | 1 - layout/svg/nsSVGPaintServerFrame.h | 1 - layout/svg/nsSVGPathGeometryFrame.cpp | 1 - layout/svg/nsSVGPathGeometryFrame.h | 1 - layout/svg/nsSVGStopFrame.cpp | 1 - layout/svg/nsSVGSwitchFrame.cpp | 4 +- layout/tables/nsTableCellFrame.cpp | 54 +++- layout/tables/nsTableCellFrame.h | 1 - layout/tables/nsTableColFrame.cpp | 9 +- layout/tables/nsTableColFrame.h | 1 - layout/tables/nsTableColGroupFrame.cpp | 9 +- layout/tables/nsTableColGroupFrame.h | 1 - layout/tables/nsTableFrame.cpp | 297 ++++-------------- layout/tables/nsTableFrame.h | 99 +++--- layout/tables/nsTableRowFrame.cpp | 58 +++- layout/tables/nsTableRowFrame.h | 6 +- layout/tables/nsTableRowGroupFrame.cpp | 50 ++- layout/tables/nsTableRowGroupFrame.h | 1 - layout/tables/nsTableWrapperFrame.cpp | 13 +- layout/tables/nsTableWrapperFrame.h | 2 - layout/xul/nsBoxFrame.cpp | 8 +- layout/xul/nsBoxFrame.h | 2 - layout/xul/nsButtonBoxFrame.cpp | 3 +- layout/xul/nsButtonBoxFrame.h | 1 - layout/xul/nsDeckFrame.cpp | 6 +- layout/xul/nsDeckFrame.h | 2 - layout/xul/nsGroupBoxFrame.cpp | 7 +- layout/xul/nsImageBoxFrame.cpp | 3 +- layout/xul/nsImageBoxFrame.h | 1 - layout/xul/nsLeafBoxFrame.cpp | 1 - layout/xul/nsLeafBoxFrame.h | 1 - layout/xul/nsListItemFrame.cpp | 3 +- layout/xul/nsListItemFrame.h | 1 - layout/xul/nsMenuFrame.cpp | 7 +- layout/xul/nsMenuFrame.h | 1 - layout/xul/nsRootBoxFrame.cpp | 8 +- layout/xul/nsSliderFrame.cpp | 10 +- layout/xul/nsSliderFrame.h | 2 - layout/xul/nsSplitterFrame.cpp | 3 +- layout/xul/nsSplitterFrame.h | 1 - layout/xul/nsStackFrame.cpp | 4 +- layout/xul/nsStackFrame.h | 1 - layout/xul/nsTextBoxFrame.cpp | 3 +- layout/xul/nsTextBoxFrame.h | 1 - layout/xul/nsTitleBarFrame.cpp | 3 +- layout/xul/nsTitleBarFrame.h | 1 - layout/xul/tree/nsTreeBodyFrame.cpp | 3 +- layout/xul/tree/nsTreeBodyFrame.h | 1 - layout/xul/tree/nsTreeColFrame.cpp | 7 +- layout/xul/tree/nsTreeColFrame.h | 1 - 170 files changed, 824 insertions(+), 822 deletions(-) create mode 100644 layout/reftests/position-relative/1409114-1-ref.html create mode 100644 layout/reftests/position-relative/1409114-1.html create mode 100644 layout/reftests/position-relative/1409114-2.html create mode 100644 layout/reftests/position-relative/1409114-3.html create mode 100644 layout/reftests/table-background/table-col-overlapping-ref.html create mode 100644 layout/reftests/table-background/table-col-overlapping.html create mode 100644 layout/reftests/table-background/table-col-span-1-ref.html create mode 100644 layout/reftests/table-background/table-col-span-1.html diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 8a34d108f..73e991246 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -721,7 +721,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, : mReferenceFrame(aReferenceFrame), mIgnoreScrollFrame(nullptr), mLayerEventRegions(nullptr), - mCurrentTableItem(nullptr), mCurrentFrame(aReferenceFrame), mCurrentReferenceFrame(aReferenceFrame), mCurrentAGR(&mRootAGR), @@ -731,6 +730,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, mGlassDisplayItem(nullptr), mScrollInfoItemsForHoisting(nullptr), mMode(aMode), + mTableBackgroundSet(nullptr), mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID), mCurrentScrollbarTarget(FrameMetrics::NULL_SCROLL_ID), mCurrentScrollbarFlags(0), @@ -864,10 +864,9 @@ nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsDisplayItem* aItem) void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, - nsIFrame* aFrame, - const nsRect& aDirtyRect) + nsIFrame* aFrame) { - nsRect dirtyRectRelativeToDirtyFrame = aDirtyRect; + nsRect dirtyRectRelativeToDirtyFrame = GetDirtyRect(); if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) && IsPaintingToWindow()) { NS_ASSERTION(aDirtyFrame == aFrame->GetParent(), "Dirty frame should be viewport frame"); @@ -882,6 +881,7 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, dirtyRectRelativeToDirtyFrame.SizeTo(aDirtyFrame->GetSize()); } } + nsRect dirty = dirtyRectRelativeToDirtyFrame - aFrame->GetOffsetTo(aDirtyFrame); nsRect overflowRect = aFrame->GetVisualOverflowRect(); @@ -925,7 +925,6 @@ nsDisplayListBuilder::~nsDisplayListBuilder() { "All frames should have been unmarked"); NS_ASSERTION(mPresShellStates.Length() == 0, "All presshells should have been exited"); - NS_ASSERTION(!mCurrentTableItem, "No table item should be active"); nsCSSRendering::EndFrameTreesLocked(); @@ -1008,8 +1007,22 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame, } state->mInsidePointerEventsNoneDoc = pointerEventsNone; - if (!buildCaret) + state->mPresShellIgnoreScrollFrame = + state->mPresShell->IgnoringViewportScrolling() + ? state->mPresShell->GetRootScrollFrame() + : nullptr; + + nsPresContext* pc = aReferenceFrame->PresContext(); + nsCOMPtr docShell = pc->GetDocShell(); + if (docShell) { + docShell->GetWindowDraggingAllowed(&mWindowDraggingAllowed); + } + + mIsInChromePresContext = pc->IsChrome(); + + if (!buildCaret) { return; + } RefPtr caret = state->mPresShell->GetCaret(); state->mCaretFrame = caret->GetPaintGeometry(&state->mCaretRect); @@ -1017,13 +1030,6 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame, mFramesMarkedForDisplay.AppendElement(state->mCaretFrame); MarkFrameForDisplay(state->mCaretFrame, nullptr); } - - nsPresContext* pc = aReferenceFrame->PresContext(); - nsCOMPtr docShell = pc->GetDocShell(); - if (docShell) { - docShell->GetWindowDraggingAllowed(&mWindowDraggingAllowed); - } - mIsInChromePresContext = pc->IsChrome(); } // A non-blank paint is a paint that does not just contain the canvas background. @@ -1094,8 +1100,7 @@ nsDisplayListBuilder::ResetMarkedFramesForDisplayList() void nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame, - const nsFrameList& aFrames, - const nsRect& aDirtyRect) { + const nsFrameList& aFrames) { for (nsIFrame* e : aFrames) { // Skip the AccessibleCaret frame when building no caret. if (!IsBuildingCaret()) { @@ -1107,9 +1112,8 @@ nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame, } } } - mFramesMarkedForDisplay.AppendElement(e); - MarkOutOfFlowFrameForDisplay(aDirtyFrame, e, aDirtyRect); + MarkOutOfFlowFrameForDisplay(aDirtyFrame, e); } } @@ -2573,8 +2577,7 @@ static nsStyleContext* GetBackgroundStyleContext(nsIFrame* aFrame) /* static */ void SetBackgroundClipRegion(DisplayListClipState::AutoSaveRestore& aClipState, - nsIFrame* aFrame, const nsPoint& aToReferenceFrame, - const nsStyleImageLayers::Layer& aLayer, + nsIFrame* aFrame, const nsStyleImageLayers::Layer& aLayer, const nsRect& aBackgroundRect, bool aWillPaintBorder) { @@ -2626,7 +2629,6 @@ SpecialCutoutRegionCase(nsDisplayListBuilder* aBuilder, return true; } - /*static*/ bool nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, @@ -2635,14 +2637,16 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil bool aAllowWillPaintBorderOptimization, nsStyleContext* aStyleContext, const nsRect& aBackgroundOriginRect, - nsIFrame* aSecondaryReferenceFrame) + nsIFrame* aSecondaryReferenceFrame, + Maybe* + aAutoBuildingDisplayList) { nsStyleContext* bgSC = aStyleContext; const nsStyleBackground* bg = nullptr; - nsRect bgRect = aBackgroundRect + aBuilder->ToReferenceFrame(aFrame); + nsRect bgRect = aBackgroundRect; nsRect bgOriginRect = bgRect; if (!aBackgroundOriginRect.IsEmpty()) { - bgOriginRect = aBackgroundOriginRect + aBuilder->ToReferenceFrame(aFrame); + bgOriginRect = aBackgroundOriginRect; } nsPresContext* presContext = aFrame->PresContext(); bool isThemed = aFrame->IsThemed(); @@ -2678,8 +2682,6 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil !isThemed && !hasInsetShadow && borderStyle->HasBorder(); - nsPoint toRef = aBuilder->ToReferenceFrame(aFrame); - // An auxiliary list is necessary in case we have background blending; if that // is the case, background items need to be wrapped by a blend container to // isolate blending to the background @@ -2688,6 +2690,9 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil // to create an item for hit testing. if ((drawBackgroundColor && color != NS_RGBA(0,0,0,0)) || aBuilder->IsForEventDelivery()) { + if (aAutoBuildingDisplayList && !*aAutoBuildingDisplayList) { + aAutoBuildingDisplayList->emplace(aBuilder, aFrame); + } DisplayListClipState::AutoSaveRestore clipState(aBuilder); if (bg && !aBuilder->IsForEventDelivery()) { // Disable the will-paint-border optimization for background @@ -2699,7 +2704,7 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil // artifacts along the rounded corners. bool useWillPaintBorderOptimization = willPaintBorder && nsLayoutUtils::HasNonZeroCorner(borderStyle->mBorderRadius); - SetBackgroundClipRegion(clipState, aFrame, toRef, + SetBackgroundClipRegion(clipState, aFrame, bg->BottomLayer(), bgRect, useWillPaintBorderOptimization); } @@ -2752,6 +2757,10 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil continue; } + if (aAutoBuildingDisplayList && !*aAutoBuildingDisplayList) { + aAutoBuildingDisplayList->emplace(aBuilder, aFrame); + } + if (bg->mImage.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) { needBlendContainer = true; } @@ -2759,8 +2768,8 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil DisplayListClipState::AutoSaveRestore clipState(aBuilder); if (!aBuilder->IsForEventDelivery()) { const nsStyleImageLayers::Layer& layer = bg->mImage.mLayers[i]; - SetBackgroundClipRegion(clipState, aFrame, toRef, - layer, bgRect, willPaintBorder); + SetBackgroundClipRegion(clipState, aFrame, layer, bgRect, + willPaintBorder); } nsDisplayList thisItemList; diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 9cee7b517..9eac132fa 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -48,6 +48,7 @@ class nsISelection; class nsIScrollableFrame; class nsDisplayLayerEventRegions; class nsDisplayScrollInfoLayer; +class nsDisplayTableBackgroundSet; class nsCaret; namespace mozilla { @@ -444,6 +445,10 @@ public: * BuildDisplayList on right now). */ const nsRect& GetDirtyRect() { return mDirtyRect; } + + void SetDirtyRect(const nsRect& aDirtyRect) { mDirtyRect = aDirtyRect; } + void IntersectDirtyRect(const nsRect& aDirtyRect) { mDirtyRect.IntersectRect(mDirtyRect, aDirtyRect); } + const nsIFrame* GetCurrentFrame() { return mCurrentFrame; } const nsIFrame* GetCurrentReferenceFrame() { return mCurrentReferenceFrame; } const nsPoint& GetCurrentFrameOffsetToReferenceFrame() { return mCurrentOffsetToReferenceFrame; } @@ -493,11 +498,10 @@ public: /** * Display the caret if needed. */ - void DisplayCaret(nsIFrame* aFrame, const nsRect& aDirtyRect, - nsDisplayList* aList) { + void DisplayCaret(nsIFrame* aFrame, nsDisplayList* aList) { nsIFrame* frame = GetCaretFrame(); if (aFrame == frame) { - frame->DisplayCaret(this, aDirtyRect, aList); + frame->DisplayCaret(this, aList); } } /** @@ -517,6 +521,14 @@ public: * Get the caret associated with the current presshell. */ nsCaret* GetCaret(); + + /** + * Returns the root scroll frame for the current PresShell, if the PresShell + * is ignoring viewport scrolling. + */ + nsIFrame* GetPresShellIgnoreScrollFrame() { + return CurrentPresShellState()->mPresShellIgnoreScrollFrame; + } /** * Notify the display list builder that we're entering a presshell. * aReferenceFrame should be a frame in the new presshell. @@ -577,6 +589,16 @@ public: mSyncDecodeImages = aSyncDecodeImages; } + nsDisplayTableBackgroundSet* SetTableBackgroundSet( + nsDisplayTableBackgroundSet* aTableSet) { + nsDisplayTableBackgroundSet* old = mTableBackgroundSet; + mTableBackgroundSet = aTableSet; + return old; + } + nsDisplayTableBackgroundSet* GetTableBackgroundSet() const { + return mTableBackgroundSet; + } + /** * Helper method to generate background painting flags based on the * information available in the display list builder. Currently only @@ -602,8 +624,7 @@ public: * destroyed. */ void MarkFramesForDisplayList(nsIFrame* aDirtyFrame, - const nsFrameList& aFrames, - const nsRect& aDirtyRect); + const nsFrameList& aFrames); /** * Mark all child frames that Preserve3D() as needing display. * Because these frames include transforms set on their parent, dirty rects @@ -700,8 +721,12 @@ public: friend class AutoBuildingDisplayList; class AutoBuildingDisplayList { public: - AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, - nsIFrame* aForChild, + + AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* aForChild) + : AutoBuildingDisplayList( + aBuilder, aForChild, aBuilder->GetDirtyRect(), aForChild->IsTransformed()){} + + AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* aForChild, const nsRect& aDirtyRect, bool aIsRoot) : mBuilder(aBuilder), mPrevFrame(aBuilder->mCurrentFrame), @@ -803,10 +828,11 @@ public: friend class AutoSaveRestorePerspectiveIndex; class AutoSaveRestorePerspectiveIndex { public: - AutoSaveRestorePerspectiveIndex(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) + AutoSaveRestorePerspectiveIndex(nsDisplayListBuilder* aBuilder, + const bool aChildrenHavePerspective) : mBuilder(nullptr) { - if (aFrame->ChildrenHavePerspective()) { + if (aChildrenHavePerspective) { mBuilder = aBuilder; mCachedItemIndex = aBuilder->mPerspectiveItemIndex; aBuilder->mPerspectiveItemIndex = 0; @@ -981,10 +1007,6 @@ public: return mPreserves3DCtx.mAccumulatedRectLevels; } - // Helpers for tables - nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; } - void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; } - struct OutOfFlowDisplayData { OutOfFlowDisplayData(const DisplayItemClip* aContainingBlockClip, const DisplayItemScrollClip* aContainingBlockScrollClip, @@ -1120,11 +1142,11 @@ public: Preserves3DContext mSavedCtx; }; - const nsRect GetPreserves3DDirtyRect(const nsIFrame *aFrame) const { + const nsRect GetPreserves3DRects() const { return mPreserves3DCtx.mDirtyRect; } - void SetPreserves3DDirtyRect(const nsRect &aDirtyRect) { - mPreserves3DCtx.mDirtyRect = aDirtyRect; + void SavePreserves3DRects() { + mPreserves3DCtx.mDirtyRect = mDirtyRect; } bool IsBuildingInvisibleItems() const { return mBuildingInvisibleItems; } @@ -1133,8 +1155,7 @@ public: } private: - void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame, - const nsRect& aDirtyRect); + void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame); /** * Returns whether a frame acts as an animated geometry root, optionally @@ -1178,6 +1199,7 @@ private: // in the document, and is set when we enter a subdocument for a pointer- // events:none frame. bool mInsidePointerEventsNoneDoc; + nsIFrame* mPresShellIgnoreScrollFrame; }; PresShellState* CurrentPresShellState() { @@ -1202,7 +1224,6 @@ private: AutoTArray mPresShellStates; AutoTArray mFramesMarkedForDisplay; AutoTArray mThemeGeometries; - nsDisplayTableItem* mCurrentTableItem; DisplayListClipState mClipState; // mCurrentFrame is the frame that we're currently calling (or about to call) // BuildDisplayList on. @@ -1245,6 +1266,7 @@ private: nsTArray mScrollClipsToDestroy; nsTArray mDisplayItemClipsToDestroy; nsDisplayListBuilderMode mMode; + nsDisplayTableBackgroundSet* mTableBackgroundSet; ViewID mCurrentScrollParentId; ViewID mCurrentScrollbarTarget; uint32_t mCurrentScrollbarFlags; @@ -2287,12 +2309,13 @@ protected: * to the object, and all distinct. */ struct nsDisplayListCollection : public nsDisplayListSet { - nsDisplayListCollection() : - nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4], - &mLists[5]) {} - explicit nsDisplayListCollection(nsDisplayList* aBorderBackground) : - nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4], + explicit nsDisplayListCollection(nsDisplayListBuilder* aBuilder) + : nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4], &mLists[5]) {} + explicit nsDisplayListCollection(nsDisplayListBuilder* aBuilder, + nsDisplayList* aBorderBackground) + : nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4], + &mLists[5]) {} /** * Sort all lists by content order. @@ -2739,7 +2762,9 @@ public: bool aAllowWillPaintBorderOptimization = true, nsStyleContext* aStyleContext = nullptr, const nsRect& aBackgroundOriginRect = nsRect(), - nsIFrame* aSecondaryReferenceFrame = nullptr); + nsIFrame* aSecondaryReferenceFrame = nullptr, + mozilla::Maybe* + aAutoBuildingDisplayList = nullptr); virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 710463a5f..fdcdcac78 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -3111,7 +3111,8 @@ nsLayoutUtils::GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect, } builder.EnterPresShell(aFrame); - aFrame->BuildDisplayListForStackingContext(&builder, aRect, &list); + builder.SetDirtyRect(aRect); + aFrame->BuildDisplayListForStackingContext(&builder, &list); builder.LeavePresShell(aFrame, nullptr); #ifdef MOZ_DUMP_PAINTING @@ -3460,7 +3461,8 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram PROFILER_LABEL("nsLayoutUtils", "PaintFrame::BuildDisplayList", js::ProfileEntry::Category::GRAPHICS); - aFrame->BuildDisplayListForStackingContext(&builder, dirtyRect, &list); + builder.SetDirtyRect(dirtyRect); + aFrame->BuildDisplayListForStackingContext(&builder, &list); } nsIAtom* frameType = aFrame->GetType(); diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 8b469185f..e8670ff3b 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -4868,8 +4868,8 @@ PresShell::CreateRangePaintInfo(nsIDOMRange* aRange, nsIFrame* frame = aNode->AsContent()->GetPrimaryFrame(); // XXX deal with frame being null due to display:contents for (; frame; frame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(frame)) { - frame->BuildDisplayListForStackingContext(&info->mBuilder, - frame->GetVisualOverflowRect(), &info->mList); + info->mBuilder.SetDirtyRect(frame->GetVisualOverflowRect()); + frame->BuildDisplayListForStackingContext(&info->mBuilder, &info->mList); } }; if (startParent->NodeType() == nsIDOMNode::TEXT_NODE) { diff --git a/layout/forms/nsButtonFrameRenderer.cpp b/layout/forms/nsButtonFrameRenderer.cpp index 096031385..5372acb7f 100644 --- a/layout/forms/nsButtonFrameRenderer.cpp +++ b/layout/forms/nsButtonFrameRenderer.cpp @@ -263,8 +263,8 @@ nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder, nsDisplayButtonBoxShadowOuter(aBuilder, this)); } - nsRect buttonRect; - GetButtonRect(mFrame->GetRectRelativeToSelf(), buttonRect); + nsRect buttonRect = + mFrame->GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(mFrame); nsDisplayBackgroundImage::AppendBackgroundItemsToTop( aBuilder, mFrame, buttonRect, aBackground); diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 98a91b9f5..1064778d6 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1295,7 +1295,6 @@ public: nsReflowStatus& aStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; protected: @@ -1336,11 +1335,10 @@ nsComboboxDisplayFrame::Reflow(nsPresContext* aPresContext, void nsComboboxDisplayFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsDisplayListCollection set; - nsBlockFrame::BuildDisplayList(aBuilder, aDirtyRect, set); + nsDisplayListCollection set(aBuilder); + nsBlockFrame::BuildDisplayList(aBuilder, set); // remove background items if parent frame is themed if (mComboBox->IsThemed()) { @@ -1541,13 +1539,8 @@ void nsDisplayComboboxFocus::Paint(nsDisplayListBuilder* aBuilder, void nsComboboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { -#ifdef NOISY - printf("%p paint at (%d, %d, %d, %d)\n", this, - aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); -#endif if (aBuilder->IsForEventDelivery()) { // Don't allow children to receive events. @@ -1556,7 +1549,7 @@ nsComboboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } else { // REVIEW: Our in-flow child frames are inline-level so they will paint in our // content list, so we don't need to mess with layers. - nsBlockFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsBlockFrame::BuildDisplayList(aBuilder, aLists); } // draw a focus indicator only when focus rings should be drawn diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index de713576f..9f5005f3c 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -92,7 +92,6 @@ public: nsEventStatus* aEventStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; void PaintFocus(DrawTarget& aDrawTarget, nsPoint aPt); diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index fc9f0571b..a5177560d 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -153,7 +153,6 @@ nsDisplayFieldSetBorderBackground::ComputeInvalidationRegion(nsDisplayListBuilde void nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // Paint our background and border in a special way. // REVIEW: We don't really need to check frame emptiness here; if it's empty, @@ -166,9 +165,11 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsDisplayBoxShadowOuter(aBuilder, this)); } + const nsRect rect = + VisualBorderRectRelativeToSelf() + aBuilder->ToReferenceFrame(this); + nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, this, VisualBorderRectRelativeToSelf(), - aLists.BorderBackground(), + aBuilder, this, rect, aLists.BorderBackground(), /* aAllowWillPaintBorderOptimization = */ false); aLists.BorderBackground()->AppendNewToTop(new (aBuilder) @@ -180,10 +181,10 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } if (GetPrevInFlow()) { - DisplayOverflowContainers(aBuilder, aDirtyRect, aLists); + DisplayOverflowContainers(aBuilder, aLists); } - nsDisplayListCollection contentDisplayItems; + nsDisplayListCollection contentDisplayItems(aBuilder); if (nsIFrame* inner = GetInner()) { // Collect the inner frame's display items into their own collection. // We need to be calling BuildDisplayList on it before the legend in @@ -191,13 +192,13 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // legend. However, we want the inner frame's display items to be // after the legend's display items in z-order, so we need to save them // and append them later. - BuildDisplayListForChild(aBuilder, inner, aDirtyRect, contentDisplayItems); + BuildDisplayListForChild(aBuilder, inner, contentDisplayItems); } if (nsIFrame* legend = GetLegend()) { // The legend's background goes on our BlockBorderBackgrounds list because // it's a block child. nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds()); - BuildDisplayListForChild(aBuilder, legend, aDirtyRect, set); + BuildDisplayListForChild(aBuilder, legend, set); } // Put the inner frame's display items on the master list. Note that this // moves its border/background display items to our BorderBackground() list, diff --git a/layout/forms/nsFieldSetFrame.h b/layout/forms/nsFieldSetFrame.h index 5eb67c320..7c162515e 100644 --- a/layout/forms/nsFieldSetFrame.h +++ b/layout/forms/nsFieldSetFrame.h @@ -53,7 +53,6 @@ public: nscoord* aBaseline) const override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; DrawResult PaintBorder(nsDisplayListBuilder* aBuilder, diff --git a/layout/forms/nsFileControlFrame.cpp b/layout/forms/nsFileControlFrame.cpp index 659371615..d60e4fb46 100644 --- a/layout/forms/nsFileControlFrame.cpp +++ b/layout/forms/nsFileControlFrame.cpp @@ -485,10 +485,9 @@ nsFileControlFrame::SetFormProperty(nsIAtom* aName, void nsFileControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); + BuildDisplayListForInline(aBuilder, aLists); } #ifdef ACCESSIBILITY diff --git a/layout/forms/nsFileControlFrame.h b/layout/forms/nsFileControlFrame.h index 55c51d426..4f975af29 100644 --- a/layout/forms/nsFileControlFrame.h +++ b/layout/forms/nsFileControlFrame.h @@ -33,7 +33,6 @@ public: nsIFrame* aPrevInFlow) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; NS_DECL_QUERYFRAME diff --git a/layout/forms/nsFormControlFrame.h b/layout/forms/nsFormControlFrame.h index fd3e95d93..41bb1d9e8 100644 --- a/layout/forms/nsFormControlFrame.h +++ b/layout/forms/nsFormControlFrame.h @@ -40,7 +40,6 @@ public: // nsIFrame replacements virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override { DO_GLOBAL_REFLOW_COUNT_DSP("nsFormControlFrame"); DisplayBorderBackgroundOutline(aBuilder, aLists); diff --git a/layout/forms/nsGfxCheckboxControlFrame.cpp b/layout/forms/nsGfxCheckboxControlFrame.cpp index 061c92349..80009eff2 100644 --- a/layout/forms/nsGfxCheckboxControlFrame.cpp +++ b/layout/forms/nsGfxCheckboxControlFrame.cpp @@ -107,10 +107,9 @@ nsGfxCheckboxControlFrame::AccessibleType() //------------------------------------------------------------ void nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsFormControlFrame::BuildDisplayList(aBuilder, aLists); // Get current checked state through content model. if ((!IsChecked() && !IsIndeterminate()) || !IsVisibleForPainting(aBuilder)) diff --git a/layout/forms/nsGfxCheckboxControlFrame.h b/layout/forms/nsGfxCheckboxControlFrame.h index 70b8d8d6a..9234b5057 100644 --- a/layout/forms/nsGfxCheckboxControlFrame.h +++ b/layout/forms/nsGfxCheckboxControlFrame.h @@ -23,7 +23,6 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; #ifdef ACCESSIBILITY diff --git a/layout/forms/nsGfxRadioControlFrame.cpp b/layout/forms/nsGfxRadioControlFrame.cpp index e4a35a998..9c1ec070b 100644 --- a/layout/forms/nsGfxRadioControlFrame.cpp +++ b/layout/forms/nsGfxRadioControlFrame.cpp @@ -70,10 +70,9 @@ PaintCheckedRadioButton(nsIFrame* aFrame, void nsGfxRadioControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsFormControlFrame::BuildDisplayList(aBuilder, aLists); if (!IsVisibleForPainting(aBuilder)) return; diff --git a/layout/forms/nsGfxRadioControlFrame.h b/layout/forms/nsGfxRadioControlFrame.h index f91e6b94c..dd268dec1 100644 --- a/layout/forms/nsGfxRadioControlFrame.h +++ b/layout/forms/nsGfxRadioControlFrame.h @@ -25,7 +25,6 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; }; diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp index c6d8e1c4f..495686cfc 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -98,7 +98,6 @@ nsHTMLButtonControlFrame::ShouldClipPaintingToBorderBox() void nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // Clip to our border area for event hit testing. @@ -117,7 +116,7 @@ nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, mRenderer.DisplayButton(aBuilder, aLists.BorderBackground(), &onTop); } - nsDisplayListCollection set; + nsDisplayListCollection set(aBuilder); // Do not allow the child subtree to receive events. if (!isForEventDelivery) { @@ -132,7 +131,7 @@ nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, clipState.ClipContainingBlockDescendants(rect, hasRadii ? radii : nullptr); } - BuildDisplayListForChild(aBuilder, mFrames.FirstChild(), aDirtyRect, set, + BuildDisplayListForChild(aBuilder, mFrames.FirstChild(), set, DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT); // That should put the display items in set.Content() } diff --git a/layout/forms/nsHTMLButtonControlFrame.h b/layout/forms/nsHTMLButtonControlFrame.h index 432afa12c..8837daf74 100644 --- a/layout/forms/nsHTMLButtonControlFrame.h +++ b/layout/forms/nsHTMLButtonControlFrame.h @@ -27,7 +27,6 @@ public: NS_DECL_FRAMEARENA_HELPERS virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override; diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index 58e81039f..2233c5996 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -155,7 +155,6 @@ nsListControlFrame::DestroyFrom(nsIFrame* aDestructRoot) void nsListControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // We allow visibility:hidden