diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2020-02-26 20:51:22 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2020-04-14 12:59:57 +0200 |
commit | dba09fa5c43276bb455cc4da6bd0ec302f798189 (patch) | |
tree | 577a2e42181433dea37dfd8febd7879dc66136e6 | |
parent | afe2b7fa5a576454d3a9b210c708890727243ede (diff) | |
download | UXP-dba09fa5c43276bb455cc4da6bd0ec302f798189.tar UXP-dba09fa5c43276bb455cc4da6bd0ec302f798189.tar.gz UXP-dba09fa5c43276bb455cc4da6bd0ec302f798189.tar.lz UXP-dba09fa5c43276bb455cc4da6bd0ec302f798189.tar.xz UXP-dba09fa5c43276bb455cc4da6bd0ec302f798189.zip |
Revert "Issue #1355 - Better way to create display items for column backgrounds"
This reverts commit 44c47c50388f526c2d134e16d5debebe94a0faf8.
171 files changed, 830 insertions, 1054 deletions
diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index f870c6d97..8a34d108f 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -721,6 +721,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, : mReferenceFrame(aReferenceFrame), mIgnoreScrollFrame(nullptr), mLayerEventRegions(nullptr), + mCurrentTableItem(nullptr), mCurrentFrame(aReferenceFrame), mCurrentReferenceFrame(aReferenceFrame), mCurrentAGR(&mRootAGR), @@ -730,7 +731,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, mGlassDisplayItem(nullptr), mScrollInfoItemsForHoisting(nullptr), mMode(aMode), - mTableBackgroundSet(nullptr), mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID), mCurrentScrollbarTarget(FrameMetrics::NULL_SCROLL_ID), mCurrentScrollbarFlags(0), @@ -783,10 +783,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, "Check nsDisplayItem::TYPE_MAX should not overflow"); } -void -nsDisplayListBuilder::MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) -{ - mFramesMarkedForDisplay.AppendElement(aFrame); +static void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) { for (nsIFrame* f = aFrame; f; f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) { if (f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) @@ -799,22 +796,6 @@ nsDisplayListBuilder::MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFra } } -void -nsDisplayListBuilder::MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* aStopAtFrame) -{ - mFramesMarkedForDisplay.AppendElement(aFrame); - for (nsIFrame* f = aFrame; f; - f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) { - if (f->ForceDescendIntoIfVisible()) - return; - f->SetForceDescendIntoIfVisible(true); - if (f == aStopAtFrame) { - // we've reached a frame that we know will be painted, so we can stop. - break; - } - } -} - bool nsDisplayListBuilder::NeedToForceTransparentSurfaceForItem(nsDisplayItem* aItem) { return aItem == mGlassDisplayItem || aItem->ClearsBackground(); @@ -883,10 +864,10 @@ nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsDisplayItem* aItem) void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, - nsIFrame* aFrame) + nsIFrame* aFrame, + const nsRect& aDirtyRect) { - nsRect visible = GetVisibleRect(); - nsRect dirtyRectRelativeToDirtyFrame = GetDirtyRect(); + nsRect dirtyRectRelativeToDirtyFrame = aDirtyRect; if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) && IsPaintingToWindow()) { NS_ASSERTION(aDirtyFrame == aFrame->GetParent(), "Dirty frame should be viewport frame"); @@ -900,14 +881,8 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, } else { dirtyRectRelativeToDirtyFrame.SizeTo(aDirtyFrame->GetSize()); } - // TODO: We probably don't want visible and dirty to be the same here, figure - // out what to do. - visible = dirtyRectRelativeToDirtyFrame; } - - nsPoint offset = aFrame->GetOffsetTo(aDirtyFrame); - visible -= offset; - nsRect dirty = dirtyRectRelativeToDirtyFrame - offset; + nsRect dirty = dirtyRectRelativeToDirtyFrame - aFrame->GetOffsetTo(aDirtyFrame); nsRect overflowRect = aFrame->GetVisualOverflowRect(); if (aFrame->IsTransformed() && @@ -920,18 +895,15 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, */ overflowRect.Inflate(nsPresContext::CSSPixelsToAppUnits(32)); } - visible.IntersectRect(visible, overflowRect); - dirty.IntersectRect(dirty, overflowRect); - if (!(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) && - dirty.IsEmpty() && - (!aFrame->ForceDescendIntoIfVisible() || - visible.IsEmpty())) { + + if (!dirty.IntersectRect(dirty, overflowRect) && + !(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) { return; } const DisplayItemClip* oldClip = mClipState.GetClipForContainingBlockDescendants(); const DisplayItemScrollClip* sc = mClipState.GetCurrentInnermostScrollClip(); - OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, visible, dirty); + OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, dirty); aFrame->SetProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data); MarkFrameForDisplay(aFrame, aDirtyFrame); @@ -942,11 +914,9 @@ static void UnmarkFrameForDisplay(nsIFrame* aFrame) { for (nsIFrame* f = aFrame; f; f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) { - if (!(f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) && - !f->ForceDescendIntoIfVisible()) + if (!(f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) return; f->RemoveStateBits(NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO); - f->SetForceDescendIntoIfVisible(false); } } @@ -955,6 +925,7 @@ 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(); @@ -1037,27 +1008,22 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame, } state->mInsidePointerEventsNoneDoc = pointerEventsNone; - state->mPresShellIgnoreScrollFrame = - state->mPresShell->IgnoringViewportScrolling() - ? state->mPresShell->GetRootScrollFrame() - : nullptr; - - nsPresContext* pc = aReferenceFrame->PresContext(); - nsCOMPtr<nsIDocShell> docShell = pc->GetDocShell(); - if (docShell) { - docShell->GetWindowDraggingAllowed(&mWindowDraggingAllowed); - } - - mIsInChromePresContext = pc->IsChrome(); - if (!buildCaret) return; RefPtr<nsCaret> caret = state->mPresShell->GetCaret(); state->mCaretFrame = caret->GetPaintGeometry(&state->mCaretRect); if (state->mCaretFrame) { + mFramesMarkedForDisplay.AppendElement(state->mCaretFrame); MarkFrameForDisplay(state->mCaretFrame, nullptr); } + + nsPresContext* pc = aReferenceFrame->PresContext(); + nsCOMPtr<nsIDocShell> 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. @@ -1128,7 +1094,8 @@ nsDisplayListBuilder::ResetMarkedFramesForDisplayList() void nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame, - const nsFrameList& aFrames) { + const nsFrameList& aFrames, + const nsRect& aDirtyRect) { for (nsIFrame* e : aFrames) { // Skip the AccessibleCaret frame when building no caret. if (!IsBuildingCaret()) { @@ -1141,7 +1108,8 @@ nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame, } } - MarkOutOfFlowFrameForDisplay(aDirtyFrame, e); + mFramesMarkedForDisplay.AppendElement(e); + MarkOutOfFlowFrameForDisplay(aDirtyFrame, e, aDirtyRect); } } @@ -1164,6 +1132,7 @@ nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame) for (; !childFrames.AtEnd(); childFrames.Next()) { nsIFrame *child = childFrames.get(); if (child->Combines3DTransformWithAncestors()) { + mFramesMarkedForDisplay.AppendElement(child); MarkFrameForDisplay(child, aDirtyFrame); } } @@ -2349,11 +2318,11 @@ nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(aFrame); MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(), *mAnimatedGeometryRoot), "Bad"); - NS_ASSERTION(aBuilder->GetVisibleRect().width >= 0 || - !aBuilder->IsForPainting(), "visible rect not set"); - // The visible rect is for mCurrentFrame, so we have to use + NS_ASSERTION(aBuilder->GetDirtyRect().width >= 0 || + !aBuilder->IsForPainting(), "dirty rect not set"); + // The dirty rect is for mCurrentFrame, so we have to use // mCurrentOffsetToReferenceFrame - mVisibleRect = aBuilder->GetVisibleRect() + + mVisibleRect = aBuilder->GetDirtyRect() + aBuilder->GetCurrentFrameOffsetToReferenceFrame(); } @@ -2604,7 +2573,8 @@ static nsStyleContext* GetBackgroundStyleContext(nsIFrame* aFrame) /* static */ void SetBackgroundClipRegion(DisplayListClipState::AutoSaveRestore& aClipState, - nsIFrame* aFrame, const nsStyleImageLayers::Layer& aLayer, + nsIFrame* aFrame, const nsPoint& aToReferenceFrame, + const nsStyleImageLayers::Layer& aLayer, const nsRect& aBackgroundRect, bool aWillPaintBorder) { @@ -2656,6 +2626,7 @@ SpecialCutoutRegionCase(nsDisplayListBuilder* aBuilder, return true; } + /*static*/ bool nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, @@ -2664,16 +2635,14 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil bool aAllowWillPaintBorderOptimization, nsStyleContext* aStyleContext, const nsRect& aBackgroundOriginRect, - nsIFrame* aSecondaryReferenceFrame, - Maybe<nsDisplayListBuilder::AutoBuildingDisplayList>* - aAutoBuildingDisplayList) + nsIFrame* aSecondaryReferenceFrame) { nsStyleContext* bgSC = aStyleContext; const nsStyleBackground* bg = nullptr; - nsRect bgRect = aBackgroundRect; + nsRect bgRect = aBackgroundRect + aBuilder->ToReferenceFrame(aFrame); nsRect bgOriginRect = bgRect; if (!aBackgroundOriginRect.IsEmpty()) { - bgOriginRect = aBackgroundOriginRect; + bgOriginRect = aBackgroundOriginRect + aBuilder->ToReferenceFrame(aFrame); } nsPresContext* presContext = aFrame->PresContext(); bool isThemed = aFrame->IsThemed(); @@ -2709,6 +2678,8 @@ 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 @@ -2717,9 +2688,6 @@ 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 @@ -2731,7 +2699,7 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil // artifacts along the rounded corners. bool useWillPaintBorderOptimization = willPaintBorder && nsLayoutUtils::HasNonZeroCorner(borderStyle->mBorderRadius); - SetBackgroundClipRegion(clipState, aFrame, + SetBackgroundClipRegion(clipState, aFrame, toRef, bg->BottomLayer(), bgRect, useWillPaintBorderOptimization); } @@ -2784,10 +2752,6 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil continue; } - if (aAutoBuildingDisplayList && !*aAutoBuildingDisplayList) { - aAutoBuildingDisplayList->emplace(aBuilder, aFrame); - } - if (bg->mImage.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) { needBlendContainer = true; } @@ -2795,8 +2759,8 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil DisplayListClipState::AutoSaveRestore clipState(aBuilder); if (!aBuilder->IsForEventDelivery()) { const nsStyleImageLayers::Layer& layer = bg->mImage.mLayers[i]; - SetBackgroundClipRegion(clipState, aFrame, layer, bgRect, - willPaintBorder); + SetBackgroundClipRegion(clipState, aFrame, toRef, + layer, bgRect, willPaintBorder); } nsDisplayList thisItemList; @@ -4378,7 +4342,7 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, mReferenceFrame = i->ReferenceFrame(); mToReferenceFrame = i->ToReferenceFrame(); } - mVisibleRect = aBuilder->GetVisibleRect() + + mVisibleRect = aBuilder->GetDirtyRect() + aBuilder->GetCurrentFrameOffsetToReferenceFrame(); } @@ -4404,7 +4368,7 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, mReferenceFrame = aItem->ReferenceFrame(); mToReferenceFrame = aItem->ToReferenceFrame(); } - mVisibleRect = aBuilder->GetVisibleRect() + + mVisibleRect = aBuilder->GetDirtyRect() + aBuilder->GetCurrentFrameOffsetToReferenceFrame(); } diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 9ae76e2ac..9cee7b517 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -48,7 +48,6 @@ class nsISelection; class nsIScrollableFrame; class nsDisplayLayerEventRegions; class nsDisplayScrollInfoLayer; -class nsDisplayTableBackgroundSet; class nsCaret; namespace mozilla { @@ -203,7 +202,6 @@ class nsDisplayListBuilder { : mAccumulatedTransform() , mAccumulatedRect() , mAccumulatedRectLevels(0) - , mVisibleRect(aOther.mVisibleRect) , mDirtyRect(aOther.mDirtyRect) {} // Accmulate transforms of ancestors on the preserves-3d chain. @@ -212,7 +210,6 @@ class nsDisplayListBuilder { nsRect mAccumulatedRect; // How far this frame is from the root of the current 3d context. int mAccumulatedRectLevels; - nsRect mVisibleRect; nsRect mDirtyRect; }; @@ -446,14 +443,7 @@ public: * Get dirty rect relative to current frame (the frame that we're calling * BuildDisplayList on right now). */ - const nsRect& GetVisibleRect() { return mVisibleRect; } const nsRect& GetDirtyRect() { return mDirtyRect; } - - void SetVisibleRect(const nsRect& aVisibleRect) { mVisibleRect = aVisibleRect; } - void IntersectVisibleRect(const nsRect& aVisibleRect) { mVisibleRect.IntersectRect(mVisibleRect, aVisibleRect); } - 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; } @@ -503,10 +493,11 @@ public: /** * Display the caret if needed. */ - void DisplayCaret(nsIFrame* aFrame, nsDisplayList* aList) { + void DisplayCaret(nsIFrame* aFrame, const nsRect& aDirtyRect, + nsDisplayList* aList) { nsIFrame* frame = GetCaretFrame(); if (aFrame == frame) { - frame->DisplayCaret(this, aList); + frame->DisplayCaret(this, aDirtyRect, aList); } } /** @@ -526,15 +517,6 @@ 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. @@ -595,16 +577,6 @@ 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 @@ -630,9 +602,8 @@ public: * destroyed. */ void MarkFramesForDisplayList(nsIFrame* aDirtyFrame, - const nsFrameList& aFrames); - void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame = nullptr); - void MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* aStopAtFrame = nullptr); + const nsFrameList& aFrames, + const nsRect& aDirtyRect); /** * Mark all child frames that Preserve3D() as needing display. * Because these frames include transforms set on their parent, dirty rects @@ -647,10 +618,9 @@ public: * the display list, even though it doesn't intersect the dirty * rect, because it may have out-of-flows that do so. */ - bool ShouldDescendIntoFrame(nsIFrame* aFrame, bool aVisible) const { + bool ShouldDescendIntoFrame(nsIFrame* aFrame) const { return (aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) || - (aVisible && aFrame->ForceDescendIntoIfVisible()) || GetIncludeAllOutOfFlows(); } @@ -730,20 +700,14 @@ public: friend class AutoBuildingDisplayList; class AutoBuildingDisplayList { public: - AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* aForChild) - : AutoBuildingDisplayList( - aBuilder, aForChild, aBuilder->GetVisibleRect(), - aBuilder->GetDirtyRect(), aForChild->IsTransformed()){} - - AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* aForChild, - const nsRect& aVisibleRect, + AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, + nsIFrame* aForChild, const nsRect& aDirtyRect, bool aIsRoot) : mBuilder(aBuilder), mPrevFrame(aBuilder->mCurrentFrame), mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame), mPrevLayerEventRegions(aBuilder->mLayerEventRegions), mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame), - mPrevVisibleRect(aBuilder->mVisibleRect), mPrevDirtyRect(aBuilder->mDirtyRect), mPrevAGR(aBuilder->mCurrentAGR), mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext), @@ -769,10 +733,12 @@ public: } MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(), *aBuilder->mCurrentAGR)); aBuilder->mCurrentFrame = aForChild; - aBuilder->mVisibleRect = aVisibleRect; aBuilder->mDirtyRect = aDirtyRect; aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot; } + void SetDirtyRect(const nsRect& aRect) { + mBuilder->mDirtyRect = aRect; + } void SetReferenceFrameAndCurrentOffset(const nsIFrame* aFrame, const nsPoint& aOffset) { mBuilder->mCurrentReferenceFrame = aFrame; mBuilder->mCurrentOffsetToReferenceFrame = aOffset; @@ -794,7 +760,6 @@ public: mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame; mBuilder->mLayerEventRegions = mPrevLayerEventRegions; mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset; - mBuilder->mVisibleRect = mPrevVisibleRect; mBuilder->mDirtyRect = mPrevDirtyRect; mBuilder->mCurrentAGR = mPrevAGR; mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext; @@ -808,7 +773,6 @@ public: nsIFrame* mPrevAnimatedGeometryRoot; nsDisplayLayerEventRegions* mPrevLayerEventRegions; nsPoint mPrevOffset; - nsRect mPrevVisibleRect; nsRect mPrevDirtyRect; AnimatedGeometryRoot* mPrevAGR; bool mPrevIsAtRootOfPseudoStackingContext; @@ -1017,19 +981,20 @@ 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, - const nsRect &aVisibleRect, const nsRect &aDirtyRect) : mContainingBlockClip(aContainingBlockClip ? *aContainingBlockClip : DisplayItemClip()) , mContainingBlockScrollClip(aContainingBlockScrollClip) - , mVisibleRect(aVisibleRect) , mDirtyRect(aDirtyRect) {} DisplayItemClip mContainingBlockClip; const DisplayItemScrollClip* mContainingBlockScrollClip; - nsRect mVisibleRect; nsRect mDirtyRect; }; @@ -1155,13 +1120,11 @@ public: Preserves3DContext mSavedCtx; }; - const nsRect GetPreserves3DRects(nsRect* aOutVisibleRect) const { - *aOutVisibleRect = mPreserves3DCtx.mVisibleRect; + const nsRect GetPreserves3DDirtyRect(const nsIFrame *aFrame) const { return mPreserves3DCtx.mDirtyRect; } - void SavePreserves3DRects() { - mPreserves3DCtx.mVisibleRect = mVisibleRect; - mPreserves3DCtx.mDirtyRect = mDirtyRect; + void SetPreserves3DDirtyRect(const nsRect &aDirtyRect) { + mPreserves3DCtx.mDirtyRect = aDirtyRect; } bool IsBuildingInvisibleItems() const { return mBuildingInvisibleItems; } @@ -1170,7 +1133,8 @@ public: } private: - void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame); + void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame, + const nsRect& aDirtyRect); /** * Returns whether a frame acts as an animated geometry root, optionally @@ -1210,7 +1174,6 @@ private: nsRect mCaretRect; uint32_t mFirstFrameMarkedForDisplay; bool mIsBackgroundOnly; - nsIFrame* mPresShellIgnoreScrollFrame; // This is a per-document flag turning off event handling for all content // in the document, and is set when we enter a subdocument for a pointer- // events:none frame. @@ -1239,6 +1202,7 @@ private: AutoTArray<PresShellState,8> mPresShellStates; AutoTArray<nsIFrame*,400> mFramesMarkedForDisplay; AutoTArray<ThemeGeometry,2> mThemeGeometries; + nsDisplayTableItem* mCurrentTableItem; DisplayListClipState mClipState; // mCurrentFrame is the frame that we're currently calling (or about to call) // BuildDisplayList on. @@ -1265,7 +1229,6 @@ private: nsTHashtable<nsPtrHashKey<nsIFrame> > mAGRBudgetSet; // Relative to mCurrentFrame. - nsRect mVisibleRect; nsRect mDirtyRect; nsRegion mWindowExcludeGlassRegion; nsRegion mWindowOpaqueRegion; @@ -1282,7 +1245,6 @@ private: nsTArray<DisplayItemScrollClip*> mScrollClipsToDestroy; nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy; nsDisplayListBuilderMode mMode; - nsDisplayTableBackgroundSet* mTableBackgroundSet; ViewID mCurrentScrollParentId; ViewID mCurrentScrollbarTarget; uint32_t mCurrentScrollbarFlags; @@ -2325,13 +2287,12 @@ protected: * to the object, and all distinct. */ struct nsDisplayListCollection : public nsDisplayListSet { - explicit nsDisplayListCollection(nsDisplayListBuilder* aBuilder) - : nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4], + 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], &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. @@ -2778,9 +2739,7 @@ public: bool aAllowWillPaintBorderOptimization = true, nsStyleContext* aStyleContext = nullptr, const nsRect& aBackgroundOriginRect = nsRect(), - nsIFrame* aSecondaryReferenceFrame = nullptr, - mozilla::Maybe<nsDisplayListBuilder::AutoBuildingDisplayList>* - aAutoBuildingDisplayList = nullptr); + nsIFrame* aSecondaryReferenceFrame = nullptr); virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 39bef4d56..21d20c69f 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -3189,9 +3189,7 @@ nsLayoutUtils::GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect, } builder.EnterPresShell(aFrame); - builder.SetVisibleRect(aRect); - builder.SetDirtyRect(aRect); - aFrame->BuildDisplayListForStackingContext(&builder, &list); + aFrame->BuildDisplayListForStackingContext(&builder, aRect, &list); builder.LeavePresShell(aFrame, nullptr); #ifdef MOZ_DUMP_PAINTING @@ -3450,8 +3448,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram nsIScrollableFrame* rootScrollableFrame = presShell->GetRootScrollFrameAsScrollable(); MOZ_ASSERT(rootScrollableFrame); nsRect displayPortBase = aFrame->GetVisualOverflowRectRelativeToSelf(); - nsRect temp = displayPortBase; - Unused << rootScrollableFrame->DecideScrollableLayer(&builder, &displayPortBase, &temp, + Unused << rootScrollableFrame->DecideScrollableLayer(&builder, &displayPortBase, /* aAllowCreateDisplayPort = */ true); } @@ -3541,9 +3538,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram PROFILER_LABEL("nsLayoutUtils", "PaintFrame::BuildDisplayList", js::ProfileEntry::Category::GRAPHICS); - builder.SetDirtyRect(dirtyRect); - builder.SetVisibleRect(dirtyRect); - aFrame->BuildDisplayListForStackingContext(&builder, &list); + aFrame->BuildDisplayListForStackingContext(&builder, dirtyRect, &list); } nsIAtom* frameType = aFrame->GetType(); @@ -3555,7 +3550,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram nsRect bounds = nsRect(builder.ToReferenceFrame(aFrame), aFrame->GetSize()); nsDisplayListBuilder::AutoBuildingDisplayList - buildingDisplayList(&builder, aFrame, bounds, bounds, false); + buildingDisplayList(&builder, aFrame, bounds, false); presShell->AddPrintPreviewBackgroundItem(builder, list, aFrame, bounds); } else if (frameType != nsGkAtoms::pageFrame) { // For printing, this function is first called on an nsPageFrame, which @@ -3569,7 +3564,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram // can monkey with the contents if necessary. canvasArea.IntersectRect(canvasArea, visibleRegion.GetBounds()); nsDisplayListBuilder::AutoBuildingDisplayList - buildingDisplayList(&builder, aFrame, canvasArea, canvasArea, false); + buildingDisplayList(&builder, aFrame, canvasArea, false); presShell->AddCanvasBackgroundColorItem( builder, list, aFrame, canvasArea, aBackstop); } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 222428a89..264b52b18 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -4894,9 +4894,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)) { - info->mBuilder.SetVisibleRect(frame->GetVisualOverflowRect()); - info->mBuilder.SetDirtyRect(frame->GetVisualOverflowRect()); - frame->BuildDisplayListForStackingContext(&info->mBuilder, &info->mList); + frame->BuildDisplayListForStackingContext(&info->mBuilder, + frame->GetVisualOverflowRect(), &info->mList); } }; if (startParent->NodeType() == nsIDOMNode::TEXT_NODE) { diff --git a/layout/forms/nsButtonFrameRenderer.cpp b/layout/forms/nsButtonFrameRenderer.cpp index 5372acb7f..096031385 100644 --- a/layout/forms/nsButtonFrameRenderer.cpp +++ b/layout/forms/nsButtonFrameRenderer.cpp @@ -263,8 +263,8 @@ nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder, nsDisplayButtonBoxShadowOuter(aBuilder, this)); } - nsRect buttonRect = - mFrame->GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(mFrame); + nsRect buttonRect; + GetButtonRect(mFrame->GetRectRelativeToSelf(), buttonRect); nsDisplayBackgroundImage::AppendBackgroundItemsToTop( aBuilder, mFrame, buttonRect, aBackground); diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index eb8de8e94..78185616f 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1294,6 +1294,7 @@ public: nsReflowStatus& aStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; protected: @@ -1334,10 +1335,11 @@ nsComboboxDisplayFrame::Reflow(nsPresContext* aPresContext, void nsComboboxDisplayFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsDisplayListCollection set (aBuilder); - nsBlockFrame::BuildDisplayList(aBuilder, set); + nsDisplayListCollection set; + nsBlockFrame::BuildDisplayList(aBuilder, aDirtyRect, set); // remove background items if parent frame is themed if (mComboBox->IsThemed()) { @@ -1545,8 +1547,13 @@ 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. @@ -1555,7 +1562,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, aLists); + nsBlockFrame::BuildDisplayList(aBuilder, aDirtyRect, 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 d83726d81..22849e8d1 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -89,6 +89,7 @@ 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 a5177560d..fc9f0571b 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -153,6 +153,7 @@ 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, @@ -165,11 +166,9 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsDisplayBoxShadowOuter(aBuilder, this)); } - const nsRect rect = - VisualBorderRectRelativeToSelf() + aBuilder->ToReferenceFrame(this); - nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, this, rect, aLists.BorderBackground(), + aBuilder, this, VisualBorderRectRelativeToSelf(), + aLists.BorderBackground(), /* aAllowWillPaintBorderOptimization = */ false); aLists.BorderBackground()->AppendNewToTop(new (aBuilder) @@ -181,10 +180,10 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } if (GetPrevInFlow()) { - DisplayOverflowContainers(aBuilder, aLists); + DisplayOverflowContainers(aBuilder, aDirtyRect, aLists); } - nsDisplayListCollection contentDisplayItems(aBuilder); + nsDisplayListCollection contentDisplayItems; 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 @@ -192,13 +191,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, contentDisplayItems); + BuildDisplayListForChild(aBuilder, inner, aDirtyRect, 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, set); + BuildDisplayListForChild(aBuilder, legend, aDirtyRect, 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 7c162515e..5eb67c320 100644 --- a/layout/forms/nsFieldSetFrame.h +++ b/layout/forms/nsFieldSetFrame.h @@ -53,6 +53,7 @@ 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 d60e4fb46..659371615 100644 --- a/layout/forms/nsFileControlFrame.cpp +++ b/layout/forms/nsFileControlFrame.cpp @@ -485,9 +485,10 @@ nsFileControlFrame::SetFormProperty(nsIAtom* aName, void nsFileControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - BuildDisplayListForInline(aBuilder, aLists); + BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); } #ifdef ACCESSIBILITY diff --git a/layout/forms/nsFileControlFrame.h b/layout/forms/nsFileControlFrame.h index 4f975af29..55c51d426 100644 --- a/layout/forms/nsFileControlFrame.h +++ b/layout/forms/nsFileControlFrame.h @@ -33,6 +33,7 @@ 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 41bb1d9e8..fd3e95d93 100644 --- a/layout/forms/nsFormControlFrame.h +++ b/layout/forms/nsFormControlFrame.h @@ -40,6 +40,7 @@ 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 80009eff2..061c92349 100644 --- a/layout/forms/nsGfxCheckboxControlFrame.cpp +++ b/layout/forms/nsGfxCheckboxControlFrame.cpp @@ -107,9 +107,10 @@ nsGfxCheckboxControlFrame::AccessibleType() //------------------------------------------------------------ void nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsFormControlFrame::BuildDisplayList(aBuilder, aLists); + nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, 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 9234b5057..70b8d8d6a 100644 --- a/layout/forms/nsGfxCheckboxControlFrame.h +++ b/layout/forms/nsGfxCheckboxControlFrame.h @@ -23,6 +23,7 @@ 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 9c1ec070b..e4a35a998 100644 --- a/layout/forms/nsGfxRadioControlFrame.cpp +++ b/layout/forms/nsGfxRadioControlFrame.cpp @@ -70,9 +70,10 @@ PaintCheckedRadioButton(nsIFrame* aFrame, void nsGfxRadioControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsFormControlFrame::BuildDisplayList(aBuilder, aLists); + nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); if (!IsVisibleForPainting(aBuilder)) return; diff --git a/layout/forms/nsGfxRadioControlFrame.h b/layout/forms/nsGfxRadioControlFrame.h index dd268dec1..f91e6b94c 100644 --- a/layout/forms/nsGfxRadioControlFrame.h +++ b/layout/forms/nsGfxRadioControlFrame.h @@ -25,6 +25,7 @@ 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 3289456f2..2e4fa9f67 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -97,6 +97,7 @@ nsHTMLButtonControlFrame::ShouldClipPaintingToBorderBox() void nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // Clip to our border area for event hit testing. @@ -115,7 +116,7 @@ nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, mRenderer.DisplayButton(aBuilder, aLists.BorderBackground(), &onTop); } - nsDisplayListCollection set (aBuilder); + nsDisplayListCollection set; // Do not allow the child subtree to receive events. if (!isForEventDelivery) { @@ -130,7 +131,7 @@ nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, clipState.ClipContainingBlockDescendants(rect, hasRadii ? radii : nullptr); } - BuildDisplayListForChild(aBuilder, mFrames.FirstChild(), set, + BuildDisplayListForChild(aBuilder, mFrames.FirstChild(), aDirtyRect, 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 8837daf74..432afa12c 100644 --- a/layout/forms/nsHTMLButtonControlFrame.h +++ b/layout/forms/nsHTMLButtonControlFrame.h @@ -27,6 +27,7 @@ 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 2233c5996..58e81039f 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -155,6 +155,7 @@ nsListControlFrame::DestroyFrom(nsIFrame* aDestructRoot) void nsListControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // We allow visibility:hidden <select>s to contain visible options. @@ -179,7 +180,7 @@ nsListControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, mLastDropdownBackstopColor)); } - nsHTMLScrollFrame::BuildDisplayList(aBuilder, aLists); + nsHTMLScrollFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); } /** diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h index d8df9ebd6..47f033a9b 100644 --- a/layout/forms/nsListControlFrame.h +++ b/layout/forms/nsListControlFrame.h @@ -81,6 +81,7 @@ public: virtual void DestroyFrom(nsIFrame* aDestructRoot) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsContainerFrame* GetContentInsertionFrame() override; diff --git a/layout/forms/nsProgressFrame.cpp b/layout/forms/nsProgressFrame.cpp index 1e3519f0e..2445defd3 100644 --- a/layout/forms/nsProgressFrame.cpp +++ b/layout/forms/nsProgressFrame.cpp @@ -101,9 +101,10 @@ NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) void nsProgressFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - BuildDisplayListForInline(aBuilder, aLists); + BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); } void diff --git a/layout/forms/nsProgressFrame.h b/layout/forms/nsProgressFrame.h index 9cc72612f..01465ff7c 100644 --- a/layout/forms/nsProgressFrame.h +++ b/layout/forms/nsProgressFrame.h @@ -32,6 +32,7 @@ public: virtual void DestroyFrom(nsIFrame* aDestructRoot) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Reflow(nsPresContext* aCX, diff --git a/layout/forms/nsRangeFrame.cpp b/layout/forms/nsRangeFrame.cpp index 9370acb87..7590da066 100644 --- a/layout/forms/nsRangeFrame.cpp +++ b/layout/forms/nsRangeFrame.cpp @@ -259,6 +259,7 @@ nsDisplayRangeFocusRing::Paint(nsDisplayListBuilder* aBuilder, void nsRangeFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (IsThemed()) { @@ -273,10 +274,10 @@ nsRangeFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* thumb = mThumbDiv->GetPrimaryFrame(); if (thumb) { nsDisplayListSet set(aLists, aLists.Content()); - BuildDisplayListForChild(aBuilder, thumb, set, DISPLAY_CHILD_INLINE); + BuildDisplayListForChild(aBuilder, thumb, aDirtyRect, set, DISPLAY_CHILD_INLINE); } } else { - BuildDisplayListForInline(aBuilder, aLists); + BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); } // Draw a focus outline if appropriate: diff --git a/layout/forms/nsRangeFrame.h b/layout/forms/nsRangeFrame.h index b913b3002..8a2d34a40 100644 --- a/layout/forms/nsRangeFrame.h +++ b/layout/forms/nsRangeFrame.h @@ -43,6 +43,7 @@ public: virtual void DestroyFrom(nsIFrame* aDestructRoot) override; void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Reflow(nsPresContext* aPresContext, diff --git a/layout/forms/nsSelectsAreaFrame.cpp b/layout/forms/nsSelectsAreaFrame.cpp index 167a0d98b..dd613ae9f 100644 --- a/layout/forms/nsSelectsAreaFrame.cpp +++ b/layout/forms/nsSelectsAreaFrame.cpp @@ -126,15 +126,16 @@ public: void nsSelectsAreaFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!aBuilder->IsForEventDelivery()) { - BuildDisplayListInternal(aBuilder, aLists); + BuildDisplayListInternal(aBuilder, aDirtyRect, aLists); return; } - nsDisplayListCollection set (aBuilder); - BuildDisplayListInternal(aBuilder, set); + nsDisplayListCollection set; + BuildDisplayListInternal(aBuilder, aDirtyRect, set); nsOptionEventGrabberWrapper wrapper; wrapper.WrapLists(aBuilder, this, set, aLists); @@ -142,9 +143,10 @@ nsSelectsAreaFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, void nsSelectsAreaFrame::BuildDisplayListInternal(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsBlockFrame::BuildDisplayList(aBuilder, aLists); + nsBlockFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); nsListControlFrame* listFrame = GetEnclosingListFrame(this); if (listFrame && listFrame->IsFocused()) { diff --git a/layout/forms/nsSelectsAreaFrame.h b/layout/forms/nsSelectsAreaFrame.h index 9b0a5b723..3aac8a837 100644 --- a/layout/forms/nsSelectsAreaFrame.h +++ b/layout/forms/nsSelectsAreaFrame.h @@ -18,9 +18,11 @@ public: nsFrameState aFlags); virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; void BuildDisplayListInternal(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists); virtual void Reflow(nsPresContext* aCX, diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index 0f35e02e9..f8fdf3420 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -1433,6 +1433,7 @@ nsTextControlFrame::PeekOffset(nsPeekOffsetStruct *aPos) void nsTextControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { /* @@ -1460,7 +1461,7 @@ nsTextControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // placeholder has to be visible. if (kid->GetContent() != txtCtrl->GetPlaceholderNode() || txtCtrl->GetPlaceholderVisibility()) { - BuildDisplayListForChild(aBuilder, kid, set, 0); + BuildDisplayListForChild(aBuilder, kid, aDirtyRect, set, 0); } kid = kid->GetNextSibling(); } diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index 620cc92b9..7fa39c5fb 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -127,6 +127,7 @@ public: nsFrameList& aChildList) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual mozilla::dom::Element* diff --git a/layout/generic/nsBackdropFrame.cpp b/layout/generic/nsBackdropFrame.cpp index ae847f460..687c5b2e3 100644 --- a/layout/generic/nsBackdropFrame.cpp +++ b/layout/generic/nsBackdropFrame.cpp @@ -39,6 +39,7 @@ nsBackdropFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const /* virtual */ void nsBackdropFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DO_GLOBAL_REFLOW_COUNT_DSP("nsBackdropFrame"); diff --git a/layout/generic/nsBackdropFrame.h b/layout/generic/nsBackdropFrame.h index f3159da31..74d366bef 100644 --- a/layout/generic/nsBackdropFrame.h +++ b/layout/generic/nsBackdropFrame.h @@ -27,6 +27,7 @@ public: virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual mozilla::LogicalSize ComputeAutoSize(nsRenderingContext* aRenderingContext, diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 93de79cef..a37bfc06b 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -6527,14 +6527,13 @@ static void DebugOutputDrawLine(int32_t aDepth, nsLineBox* aLine, bool aDrawn) { static void DisplayLine(nsDisplayListBuilder* aBuilder, const nsRect& aLineArea, - nsBlockFrame::LineIterator& aLine, + const nsRect& aDirtyRect, nsBlockFrame::LineIterator& aLine, int32_t aDepth, int32_t& aDrawnLines, const nsDisplayListSet& aLists, nsBlockFrame* aFrame, TextOverflow* aTextOverflow) { // If the line's combined area (which includes child frames that // stick outside of the line's bounding box or our bounding box) // intersects the dirty rect then paint the line. - bool intersect = aLineArea.Intersects(aBuilder->GetDirtyRect()); - bool visible = aLineArea.Intersects(aBuilder->GetVisibleRect()); + bool intersect = aLineArea.Intersects(aDirtyRect); #ifdef DEBUG if (nsBlockFrame::gLamePaintMetrics) { aDrawnLines++; @@ -6550,14 +6549,14 @@ DisplayLine(nsDisplayListBuilder* aBuilder, const nsRect& aLineArea, // frame in the line, it's also true for aFrame. bool lineInline = aLine->IsInline(); bool lineMayHaveTextOverflow = aTextOverflow && lineInline; - if (!intersect && !aBuilder->ShouldDescendIntoFrame(aFrame, visible) && + if (!intersect && !aBuilder->ShouldDescendIntoFrame(aFrame) && !lineMayHaveTextOverflow) return; // Collect our line's display items in a temporary nsDisplayListCollection, // so that we can apply any "text-overflow" clipping to the entire collection // without affecting previous lines. - nsDisplayListCollection collection(aBuilder); + nsDisplayListCollection collection; // Block-level child backgrounds go on the blockBorderBackgrounds list ... // Inline-level child backgrounds go on the regular child content list. @@ -6569,7 +6568,8 @@ DisplayLine(nsDisplayListBuilder* aBuilder, const nsRect& aLineArea, nsIFrame* kid = aLine->mFirstChild; int32_t n = aLine->GetChildCount(); while (--n >= 0) { - aFrame->BuildDisplayListForChild(aBuilder, kid, childLists, flags); + aFrame->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, + childLists, flags); kid = kid->GetNextSibling(); } @@ -6582,13 +6582,13 @@ DisplayLine(nsDisplayListBuilder* aBuilder, const nsRect& aLineArea, void nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { int32_t drawnLines; // Will only be used if set (gLamePaintMetrics). int32_t depth = 0; #ifdef DEBUG if (gNoisyDamageRepair) { - nsRect dirty = aBuilder->GetDirtyRect(); depth = GetDepth(); nsRect ca; ::ComputeVisualOverflowArea(mLines, mRect.width, mRect.height, ca); @@ -6596,7 +6596,7 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, ListTag(stdout); printf(": bounds=%d,%d,%d,%d dirty(absolute)=%d,%d,%d,%d ca=%d,%d,%d,%d\n", mRect.x, mRect.y, mRect.width, mRect.height, - dirty.x, dirty.y, dirty.width, dirty.height, + aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height, ca.x, ca.y, ca.width, ca.height); } PRTime start = 0; // Initialize these variables to silence the compiler. @@ -6609,21 +6609,21 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, DisplayBorderBackgroundOutline(aBuilder, aLists); if (GetPrevInFlow()) { - DisplayOverflowContainers(aBuilder, aLists); + DisplayOverflowContainers(aBuilder, aDirtyRect, aLists); for (nsIFrame* f : mFloats) { if (f->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT) - BuildDisplayListForChild(aBuilder, f, aLists); + BuildDisplayListForChild(aBuilder, f, aDirtyRect, aLists); } } - aBuilder->MarkFramesForDisplayList(this, mFloats); + aBuilder->MarkFramesForDisplayList(this, mFloats, aDirtyRect); // Prepare for text-overflow processing. UniquePtr<TextOverflow> textOverflow( TextOverflow::WillProcessLines(aBuilder, this)); // We'll collect our lines' display items here, & then append this to aLists. - nsDisplayListCollection linesDisplayListCollection(aBuilder); + nsDisplayListCollection linesDisplayListCollection; // Don't use the line cursor if we might have a descendant placeholder ... // it might skip lines that contain placeholders but don't themselves @@ -6632,8 +6632,8 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // on all our child frames, but that might be expensive. So we // approximate it by checking it on |this|; if it's true for any // frame in our child list, it's also true for |this|. - nsLineBox* cursor = (aBuilder->ShouldDescendIntoFrame(this, true)) ? - nullptr : GetFirstLineContaining(aBuilder->GetDirtyRect().y); + nsLineBox* cursor = aBuilder->ShouldDescendIntoFrame(this) ? + nullptr : GetFirstLineContaining(aDirtyRect.y); LineIterator line_end = LinesEnd(); if (cursor) { @@ -6644,10 +6644,10 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, if (!lineArea.IsEmpty()) { // Because we have a cursor, the combinedArea.ys are non-decreasing. // Once we've passed aDirtyRect.YMost(), we can never see it again. - if (lineArea.y >= aBuilder->GetDirtyRect().YMost()) { + if (lineArea.y >= aDirtyRect.YMost()) { break; } - DisplayLine(aBuilder, lineArea, line, depth, drawnLines, + DisplayLine(aBuilder, lineArea, aDirtyRect, line, depth, drawnLines, linesDisplayListCollection, this, textOverflow.get()); } } @@ -6660,7 +6660,7 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, line != line_end; ++line) { nsRect lineArea = line->GetVisualOverflowArea(); - DisplayLine(aBuilder, lineArea, line, depth, drawnLines, + DisplayLine(aBuilder, lineArea, aDirtyRect, line, depth, drawnLines, linesDisplayListCollection, this, textOverflow.get()); if (!lineArea.IsEmpty()) { if (lineArea.y < lastY @@ -6690,7 +6690,7 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, if (HasOutsideBullet()) { // Display outside bullets manually nsIFrame* bullet = GetOutsideBullet(); - BuildDisplayListForChild(aBuilder, bullet, aLists); + BuildDisplayListForChild(aBuilder, bullet, aDirtyRect, aLists); } #ifdef DEBUG diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index 4775fa626..f515cc26f 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -139,6 +139,7 @@ public: virtual nsSplittableType GetSplittableType() const override; virtual bool IsFloatContainingBlock() const override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsIAtom* GetType() const override; virtual bool IsFrameOfType(uint32_t aFlags) const override diff --git a/layout/generic/nsBulletFrame.cpp b/layout/generic/nsBulletFrame.cpp index db9a70aff..f6595e8f6 100644 --- a/layout/generic/nsBulletFrame.cpp +++ b/layout/generic/nsBulletFrame.cpp @@ -274,6 +274,7 @@ void nsDisplayBullet::Paint(nsDisplayListBuilder* aBuilder, void nsBulletFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) diff --git a/layout/generic/nsBulletFrame.h b/layout/generic/nsBulletFrame.h index 30f4e23cd..e35ed0923 100644 --- a/layout/generic/nsBulletFrame.h +++ b/layout/generic/nsBulletFrame.h @@ -68,6 +68,7 @@ public: // nsIFrame virtual void DestroyFrom(nsIFrame* aDestructRoot) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsIAtom* GetType() const override; virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override; diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index 31baa040c..1a8812fb7 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -410,10 +410,11 @@ public: void nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (GetPrevInFlow()) { - DisplayOverflowContainers(aBuilder, aLists); + DisplayOverflowContainers(aBuilder, aDirtyRect, aLists); } // Force a background to be shown. We may have a background propagated to us, @@ -487,7 +488,7 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, for (nsIFrame* kid : PrincipalChildList()) { // Put our child into its own pseudo-stack. - BuildDisplayListForChild(aBuilder, kid, aLists); + BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); } #ifdef DEBUG_CANVAS_FOCUS @@ -503,7 +504,7 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, docShell->GetHasFocus(&hasFocus); printf("%p - nsCanvasFrame::Paint R:%d,%d,%d,%d DR: %d,%d,%d,%d\n", this, mRect.x, mRect.y, mRect.width, mRect.height, - dirty.x, dirty.y, dirty.width, dirty.height); + aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); } printf("%p - Focus: %s c: %p DoPaint:%s\n", docShell.get(), hasFocus?"Y":"N", focusContent.get(), mDoPaintFocus?"Y":"N"); diff --git a/layout/generic/nsCanvasFrame.h b/layout/generic/nsCanvasFrame.h index 8c59f18c0..8bd9dbf79 100644 --- a/layout/generic/nsCanvasFrame.h +++ b/layout/generic/nsCanvasFrame.h @@ -107,6 +107,7 @@ public: NS_IMETHOD SetHasFocus(bool aHasFocus); virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; void PaintFocus(mozilla::gfx::DrawTarget* aRenderingContext, nsPoint aPt); diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index 90d425ccf..6ea15d4d2 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -1115,6 +1115,7 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext, void nsColumnSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DisplayBorderBackgroundOutline(aBuilder, aLists); @@ -1127,7 +1128,7 @@ nsColumnSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // Our children won't have backgrounds so it doesn't matter where we put them. for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) { - BuildDisplayListForChild(aBuilder, e.get(), aLists); + BuildDisplayListForChild(aBuilder, e.get(), aDirtyRect, aLists); } } diff --git a/layout/generic/nsColumnSetFrame.h b/layout/generic/nsColumnSetFrame.h index 4195742c2..db44183d6 100644 --- a/layout/generic/nsColumnSetFrame.h +++ b/layout/generic/nsColumnSetFrame.h @@ -67,6 +67,7 @@ public: } virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsIAtom* GetType() const override; diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 162e64a3c..abf687c9b 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -329,15 +329,17 @@ nsContainerFrame::GetChildLists(nsTArray<ChildList>* aLists) const void nsContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DisplayBorderBackgroundOutline(aBuilder, aLists); - BuildDisplayListForNonBlockChildren(aBuilder, aLists); + BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists); } void nsContainerFrame::BuildDisplayListForNonBlockChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists, uint32_t aFlags) { @@ -346,7 +348,7 @@ nsContainerFrame::BuildDisplayListForNonBlockChildren(nsDisplayListBuilder* aB nsDisplayListSet set(aLists, aLists.Content()); // The children should be in content order while (kid) { - BuildDisplayListForChild(aBuilder, kid, set, aFlags); + BuildDisplayListForChild(aBuilder, kid, aDirtyRect, set, aFlags); kid = kid->GetNextSibling(); } } @@ -1334,12 +1336,13 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres void nsContainerFrame::DisplayOverflowContainers(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { nsFrameList* overflowconts = GetPropTableFrames(OverflowContainersProperty()); if (overflowconts) { for (nsIFrame* frame : *overflowconts) { - BuildDisplayListForChild(aBuilder, frame, aLists); + BuildDisplayListForChild(aBuilder, frame, aDirtyRect, aLists); } } } diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h index e3cc54b0b..ddf993d91 100644 --- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -437,6 +437,7 @@ public: * Add overflow containers to the display list */ void DisplayOverflowContainers(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists); /** @@ -449,6 +450,7 @@ public: * to emulate what nsContainerFrame::Paint did. */ virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; static void PlaceFrameView(nsIFrame* aFrame) @@ -574,6 +576,7 @@ protected: * display items) go into the Content() list. */ void BuildDisplayListForNonBlockChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists, uint32_t aFlags = 0); @@ -582,9 +585,11 @@ protected: * Intended as a convenience for derived classes. */ void BuildDisplayListForInline(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DisplayBorderBackgroundOutline(aBuilder, aLists); - BuildDisplayListForNonBlockChildren(aBuilder, aLists, DISPLAY_CHILD_INLINE); + BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists, + DISPLAY_CHILD_INLINE); } diff --git a/layout/generic/nsFirstLetterFrame.cpp b/layout/generic/nsFirstLetterFrame.cpp index 426e3caa7..980e1e9be 100644 --- a/layout/generic/nsFirstLetterFrame.cpp +++ b/layout/generic/nsFirstLetterFrame.cpp @@ -50,9 +50,10 @@ nsFirstLetterFrame::GetType() const void nsFirstLetterFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - BuildDisplayListForInline(aBuilder, aLists); + BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); } void diff --git a/layout/generic/nsFirstLetterFrame.h b/layout/generic/nsFirstLetterFrame.h index c8d416a85..40e4ef0cf 100644 --- a/layout/generic/nsFirstLetterFrame.h +++ b/layout/generic/nsFirstLetterFrame.h @@ -20,6 +20,7 @@ public: explicit nsFirstLetterFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) {} virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Init(nsIContent* aContent, diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index 69200117b..94bce1e7a 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -2433,6 +2433,7 @@ GetDisplayFlagsForFlexItem(nsIFrame* aFrame) void nsFlexContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // XXXdholbert hacky temporary band-aid for bug 1059138: Trivially pass this @@ -2451,7 +2452,7 @@ nsFlexContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // the BlockBorderBackgrounds list. nsDisplayListSet childLists(aLists, aLists.BlockBorderBackgrounds()); for (nsIFrame* childFrame : mFrames) { - BuildDisplayListForChild(aBuilder, childFrame, childLists, + BuildDisplayListForChild(aBuilder, childFrame, aDirtyRect, childLists, GetDisplayFlagsForFlexItem(childFrame)); } } diff --git a/layout/generic/nsFlexContainerFrame.h b/layout/generic/nsFlexContainerFrame.h index ac2cc72f6..459ae8e20 100644 --- a/layout/generic/nsFlexContainerFrame.h +++ b/layout/generic/nsFlexContainerFrame.h @@ -64,6 +64,7 @@ public: nsIFrame* aPrevInFlow) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; void MarkIntrinsicISizesDirty() override; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index ab264dd76..8d4ea8754 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1794,13 +1794,6 @@ void nsFrame::DisplayOutlineUnconditional(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) { - // Per https://drafts.csswg.org/css-tables-3/#global-style-overrides: - // "All css properties of table-column and table-column-group boxes are - // ignored, except when explicitly specified by this specification." - // CSS outlines fall into this category, so we skip them on these boxes. - - MOZ_ASSERT(GetType() != nsGkAtoms::tableColGroupFrame && GetType() != nsGkAtoms::tableColFrame); - if (StyleOutline()->mOutlineStyle == NS_STYLE_BORDER_STYLE_NONE) { return; } @@ -1821,7 +1814,7 @@ nsFrame::DisplayOutline(nsDisplayListBuilder* aBuilder, void nsIFrame::DisplayCaret(nsDisplayListBuilder* aBuilder, - nsDisplayList* aList) + const nsRect& aDirtyRect, nsDisplayList* aList) { if (!IsVisibleForPainting(aBuilder)) return; @@ -1847,9 +1840,7 @@ nsFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder, if (aBuilder->IsForEventDelivery() || aForceBackground || !StyleBackground()->IsTransparent() || StyleDisplay()->mAppearance) { return nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, this, - GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(this), - aLists.BorderBackground()); + aBuilder, this, GetRectRelativeToSelf(), aLists.BorderBackground()); } return false; } @@ -1882,9 +1873,7 @@ nsFrame::DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder, // If there's a themed background, we should not create a border item. // It won't be rendered. - // Don't paint borders for tables here, since they paint them in a different - // order. - if (!bgIsThemed && StyleBorder()->HasBorder() && GetType() != nsGkAtoms::tableFrame) { + if (!bgIsThemed && StyleBorder()->HasBorder()) { aLists.BorderBackground()->AppendNewToTop(new (aBuilder) nsDisplayBorder(aBuilder, this)); } @@ -2084,12 +2073,13 @@ ItemParticipatesIn3DContext(nsIFrame* aAncestor, nsDisplayItem* aItem) static void WrapSeparatorTransform(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, + nsRect& aDirtyRect, nsDisplayList* aSource, nsDisplayList* aTarget, int aIndex) { if (!aSource->IsEmpty()) { nsDisplayTransform *sepIdItem = new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aSource, - aBuilder->GetDirtyRect(), Matrix4x4(), aIndex); + aDirtyRect, Matrix4x4(), aIndex); sepIdItem->SetNoExtendContext(); aTarget->AppendToTop(sepIdItem); } @@ -2097,6 +2087,7 @@ WrapSeparatorTransform(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, void nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, nsDisplayList* aList) { if (GetStateBits() & NS_FRAME_TOO_DEEP_IN_FRAME_TREE) return; @@ -2140,14 +2131,13 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, autoPreserves3DContext.emplace(aBuilder); // Save dirty rect on the builder to avoid being distorted for // multiple transforms along the chain. - aBuilder->SavePreserves3DRects(); + aBuilder->SetPreserves3DDirtyRect(aDirtyRect); } // For preserves3d, use the dirty rect already installed on the // builder, since aDirtyRect maybe distorted for transforms along // the chain. - nsRect visibleRect = aBuilder->GetVisibleRect(); - nsRect dirtyRect = aBuilder->GetDirtyRect(); + nsRect dirtyRect = aDirtyRect; bool inTransform = aBuilder->IsInTransform(); bool isTransformed = IsTransformed(); @@ -2158,7 +2148,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, AutoSaveRestoreContainsBlendMode autoRestoreBlendMode(*aBuilder); aBuilder->SetContainsBlendMode(false); - nsRect visibleRectOutsideTransform = visibleRect; + nsRect dirtyRectOutsideTransform = dirtyRect; if (isTransformed) { const nsRect overflow = GetVisualOverflowRectRelativeToSelf(); if (nsDisplayTransform::ShouldPrerenderTransformedContent(aBuilder, @@ -2172,19 +2162,17 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, // If we're in preserve-3d then grab the dirty rect that was given to the root // and transform using the combined transform. if (Combines3DTransformWithAncestors()) { - dirtyRect = aBuilder->GetPreserves3DRects(&visibleRect); + dirtyRect = aBuilder->GetPreserves3DDirtyRect(this); } nsRect untransformedDirtyRect; if (nsDisplayTransform::UntransformRect(dirtyRect, overflow, this, &untransformedDirtyRect)) { dirtyRect = untransformedDirtyRect; - nsDisplayTransform::UntransformRect(visibleRect, overflow, this, &visibleRect); } else { NS_WARNING("Unable to untransform dirty rect!"); // This should only happen if the transform is singular, in which case nothing is visible anyway dirtyRect.SetEmpty(); - visibleRect.SetEmpty(); } } inTransform = true; @@ -2193,13 +2181,11 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, bool usingMask = nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(this); bool usingSVGEffects = usingFilter || usingMask; - nsRect visibleRectOutsideSVGEffects = visibleRect; + nsRect dirtyRectOutsideSVGEffects = dirtyRect; nsDisplayList hoistedScrollInfoItemsStorage; if (usingSVGEffects) { dirtyRect = nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, dirtyRect); - visibleRect = - nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, visibleRect); aBuilder->EnterSVGEffectsContents(&hoistedScrollInfoItemsStorage); } @@ -2219,7 +2205,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, bool useFixedPosition = nsLayoutUtils::IsFixedPosFrameInDisplayPort(this); nsDisplayListBuilder::AutoBuildingDisplayList - buildingDisplayList(aBuilder, this, visibleRect, dirtyRect, true); + buildingDisplayList(aBuilder, this, dirtyRect, true); // Depending on the effects that are applied to this frame, we can create // multiple container display items and wrap them around our contents. @@ -2284,7 +2270,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, clipState.EnterStackingContextContents(clearClip); - nsDisplayListCollection set(aBuilder); + nsDisplayListCollection set; { DisplayListClipState::AutoSaveRestore nestedClipState(aBuilder); nsDisplayListBuilder::AutoInTransformSetter @@ -2296,8 +2282,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, Maybe<nsRect> clipPropClip = GetClipPropClipRect(disp, effects, GetSize()); if (clipPropClip) { - aBuilder->IntersectDirtyRect(*clipPropClip); - aBuilder->IntersectVisibleRect(*clipPropClip); + dirtyRect.IntersectRect(dirtyRect, *clipPropClip); nestedClipState.ClipContentDescendants( *clipPropClip + aBuilder->ToReferenceFrame(this)); } @@ -2310,7 +2295,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, aBuilder->MarkPreserve3DFramesForDisplayList(this); } - MarkAbsoluteFramesForDisplayList(aBuilder); + MarkAbsoluteFramesForDisplayList(aBuilder, dirtyRect); nsDisplayLayerEventRegions* eventRegions = nullptr; if (aBuilder->IsBuildingLayerEventRegions()) { @@ -2319,7 +2304,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, aBuilder->SetLayerEventRegions(eventRegions); } aBuilder->AdjustWindowDraggingRegion(this); - BuildDisplayList(aBuilder, set); + BuildDisplayList(aBuilder, dirtyRect, set); if (eventRegions) { // If the event regions item ended up empty, throw it away rather than // adding it to the display list. @@ -2425,7 +2410,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, clipState.ExitStackingContextContents(&containerItemScrollClip); } // Revert to the post-filter dirty rect. - aBuilder->SetVisibleRect(visibleRectOutsideSVGEffects); + buildingDisplayList.SetDirtyRect(dirtyRectOutsideSVGEffects); // Skip all filter effects while generating glyph mask. if (usingFilter && !aBuilder->IsForGenerateGlyphMask()) { @@ -2458,7 +2443,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, /* If the list is non-empty and there is CSS group opacity without SVG * effects, wrap it up in an opacity item. */ - if (useOpacity) { + if (useOpacity && !resultList.IsEmpty()) { // Don't clip nsDisplayOpacity items. We clip their descendants instead. // The clip we would set on an element with opacity would clip // all descendant content, but some should not be clipped. @@ -2480,7 +2465,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, * We also traverse into sublists created by nsDisplayWrapList, so that we find all the * correct children. */ - if (isTransformed && extend3DContext) { + if (isTransformed && !resultList.IsEmpty() && extend3DContext) { // Install dummy nsDisplayTransform as a leaf containing // descendants not participating this 3D rendering context. nsDisplayList nonparticipants; @@ -2490,7 +2475,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, while (nsDisplayItem* item = resultList.RemoveBottom()) { if (ItemParticipatesIn3DContext(this, item) && !item->GetClip().HasClip()) { // The frame of this item participates the same 3D context. - WrapSeparatorTransform(aBuilder, this, &nonparticipants, &participants, index++); + WrapSeparatorTransform(aBuilder, this, dirtyRect, + &nonparticipants, &participants, index++); participants.AppendToTop(item); } else { // The frame of the item doesn't participate the current @@ -2503,18 +2489,19 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, nonparticipants.AppendToTop(item); } } - WrapSeparatorTransform(aBuilder, this, &nonparticipants, &participants, index++); + WrapSeparatorTransform(aBuilder, this, dirtyRect, + &nonparticipants, &participants, index++); resultList.AppendToTop(&participants); } - if (isTransformed) { + if (isTransformed && !resultList.IsEmpty()) { if (clipCapturedBy == ContainerItemType::eTransform) { // Restore clip state now so nsDisplayTransform is clipped properly. clipState.ExitStackingContextContents(&containerItemScrollClip); } // Revert to the dirtyrect coming in from the parent, without our transform // taken into account. - aBuilder->SetVisibleRect(visibleRectOutsideTransform); + buildingDisplayList.SetDirtyRect(dirtyRectOutsideTransform); // Revert to the outer reference frame and offset because all display // items we create from now on are outside the transform. nsPoint toOuterReferenceFrame; @@ -2527,10 +2514,10 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, GetOffsetToCrossDoc(outerReferenceFrame)); bool isFullyVisible = - visibleRectOutsideSVGEffects.Contains(GetVisualOverflowRectRelativeToSelf()); + dirtyRectOutsideSVGEffects.Contains(GetVisualOverflowRectRelativeToSelf()); nsDisplayTransform *transformItem = new (aBuilder) nsDisplayTransform(aBuilder, this, - &resultList, visibleRect, 0, + &resultList, dirtyRect, 0, isFullyVisible); resultList.AppendNewToTop(transformItem); @@ -2574,7 +2561,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, * not affected by foreground opacity (only background alpha). */ - if (useBlendMode) { + if (useBlendMode && !resultList.IsEmpty()) { DisplayListClipState::AutoSaveRestore mixBlendClipState(aBuilder); mixBlendClipState.Clear(); resultList.AppendNewToTop( @@ -2615,80 +2602,10 @@ WrapInWrapList(nsDisplayListBuilder* aBuilder, return item; } - static bool DescendIntoChild(nsDisplayListBuilder* aBuilder, - const nsIFrame* aChild, const nsRect& aVisible, - const nsRect& aDirty) { - if (aChild->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) { - return true; - } - // No need to descend into child to catch placeholders for visible - // positioned stuff. So see if we can short-circuit frame traversal here. - - // We can stop if child's frame subtree's intersection with the - // dirty area is empty. - // If the child is a scrollframe that we want to ignore, then we need - // to descend into it because its scrolled child may intersect the dirty - // area even if the scrollframe itself doesn't. - // There are cases where the "ignore scroll frame" on the builder is not set - // correctly, and so we additionally want to catch cases where the child is - // a root scrollframe and we are ignoring scrolling on the viewport. - - // If the child is a scrollframe that we want to ignore, then we need - // to descend into it because its scrolled child may intersect the dirty - // area even if the scrollframe itself doesn't. - if (aChild == aBuilder->GetIgnoreScrollFrame()) { - return true; - } - - - // There are cases where the "ignore scroll frame" on the builder is not set - // correctly, and so we additionally want to catch cases where the child is - // a root scrollframe and we are ignoring scrolling on the viewport. - if (aChild == aBuilder->GetPresShellIgnoreScrollFrame()) { - return true; - } - - const nsRect overflow = aChild->GetVisualOverflowRect(); - - if (aDirty.Intersects(overflow)) { - return true; - } - - if (aChild->ForceDescendIntoIfVisible() && aVisible.Intersects(overflow)) { - return true; - } - - if (aChild->IsFrameOfType(nsIFrame::eTablePart)) { - // Relative positioning and transforms can cause table parts to move, but we - // will still paint the backgrounds for their ancestor parts under them at - // their 'normal' position. That means that we must consider the overflow - // rects at both positions. - - // We convert the overflow rect into the nsTableFrame's coordinate - // space, applying the normal position offset at each step. Then we - // compare that against the builder's cached dirty rect in table - // coordinate space. - const nsIFrame* f = aChild; - nsRect normalPositionOverflowRelativeToTable = overflow; - - while (f->IsFrameOfType(nsIFrame::eTablePart)) { - normalPositionOverflowRelativeToTable += f->GetNormalPosition(); - f = f->GetParent(); - } - - nsDisplayTableBackgroundSet* tableBGs = aBuilder->GetTableBackgroundSet(); - if (tableBGs && - tableBGs->GetDirtyRect().Intersects(normalPositionOverflowRelativeToTable)) { - return true; - } - } - - return false; -} - void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, nsIFrame* aChild, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists, uint32_t aFlags) { // If painting is restricted to just the background of the top level frame, @@ -2721,16 +2638,12 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, pseudoStackingContext = true; } + // dirty rect in child-relative coordinates + nsRect dirty = aDirtyRect - child->GetOffsetTo(this); + nsIAtom* childType = child->GetType(); nsDisplayListBuilder::OutOfFlowDisplayData* savedOutOfFlowData = nullptr; bool isPlaceholder = false; - - // dirty rect in child-relative coordinates - NS_ASSERTION(aBuilder->GetCurrentFrame() == this, "Wrong coord space!"); - const nsPoint offset = child->GetOffsetTo(this); - nsRect visible = aBuilder->GetVisibleRect() - offset; - nsRect dirty = aBuilder->GetDirtyRect() - offset; - if (childType == nsGkAtoms::placeholderFrame) { isPlaceholder = true; nsPlaceholderFrame* placeholder = static_cast<nsPlaceholderFrame*>(child); @@ -2760,25 +2673,15 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, return; savedOutOfFlowData = nsDisplayListBuilder::GetOutOfFlowData(child); if (savedOutOfFlowData) { - visible = savedOutOfFlowData->mVisibleRect; dirty = savedOutOfFlowData->mDirtyRect; } else { // The out-of-flow frame did not intersect the dirty area. We may still // need to traverse into it, since it may contain placeholders we need // to enter to reach other out-of-flow frames that are visible. - visible.SetEmpty(); dirty.SetEmpty(); } pseudoStackingContext = true; } - - if (aBuilder->GetIncludeAllOutOfFlows() && - (child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { - visible = child->GetVisualOverflowRect(); - dirty = child->GetVisualOverflowRect(); - } else if (!DescendIntoChild(aBuilder, child, visible, dirty)) { - return; - } NS_ASSERTION(childType != nsGkAtoms::placeholderFrame, "Should have dealt with placeholders already"); @@ -2788,6 +2691,36 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, return; } + if (aBuilder->GetIncludeAllOutOfFlows() && + (child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { + dirty = child->GetVisualOverflowRect(); + } else if (!(child->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) { + // No need to descend into child to catch placeholders for visible + // positioned stuff. So see if we can short-circuit frame traversal here. + + // We can stop if child's frame subtree's intersection with the + // dirty area is empty. + // If the child is a scrollframe that we want to ignore, then we need + // to descend into it because its scrolled child may intersect the dirty + // area even if the scrollframe itself doesn't. + // There are cases where the "ignore scroll frame" on the builder is not set + // correctly, and so we additionally want to catch cases where the child is + // a root scrollframe and we are ignoring scrolling on the viewport. + nsIPresShell* shell = PresContext()->PresShell(); + bool keepDescending = child == aBuilder->GetIgnoreScrollFrame() || + (shell->IgnoringViewportScrolling() && child == shell->GetRootScrollFrame()); + if (!keepDescending) { + nsRect childDirty; + if (!childDirty.IntersectRect(dirty, child->GetVisualOverflowRect())) + return; + // Usually we could set dirty to childDirty now but there's no + // benefit, and it can be confusing. It can especially confuse + // situations where we're going to ignore a scrollframe's clipping; + // we wouldn't want to clip the dirty area to the scrollframe's + // bounds in that case. + } + } + // XXX need to have inline-block and inline-table set pseudoStackingContext const nsStyleDisplay* ourDisp = StyleDisplay(); @@ -2838,8 +2771,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, "Stacking contexts must also be pseudo-stacking-contexts"); nsDisplayListBuilder::AutoBuildingDisplayList - buildingForChild(aBuilder, child, visible, dirty, pseudoStackingContext); - + buildingForChild(aBuilder, child, dirty, pseudoStackingContext); DisplayListClipState::AutoClipMultiple clipState(aBuilder); CheckForApzAwareEventHandlers(aBuilder, child); @@ -2852,7 +2784,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, savedOutOfFlowData->mContainingBlockScrollClip); } else if (GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO && isPlaceholder) { - NS_ASSERTION(visible.IsEmpty(), "should have empty visible rect"); + NS_ASSERTION(dirty.IsEmpty(), "should have empty dirty rect"); // Every item we build from now until we descent into an out of flow that // does have saved out of flow data should be invisible. This state gets // restored when AutoBuildingDisplayList gets out of scope. @@ -2888,19 +2820,18 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, // True stacking context. // For stacking contexts, BuildDisplayListForStackingContext handles // clipping and MarkAbsoluteFramesForDisplayList. - child->BuildDisplayListForStackingContext(aBuilder, &list); - aBuilder->DisplayCaret(child, &list); + child->BuildDisplayListForStackingContext(aBuilder, dirty, &list); + aBuilder->DisplayCaret(child, dirty, &list); } else { Maybe<nsRect> clipPropClip = child->GetClipPropClipRect(disp, effects, child->GetSize()); if (clipPropClip) { - aBuilder->IntersectVisibleRect(*clipPropClip); - aBuilder->IntersectDirtyRect(*clipPropClip); + dirty.IntersectRect(dirty, *clipPropClip); clipState.ClipContentDescendants( *clipPropClip + aBuilder->ToReferenceFrame(child)); } - child->MarkAbsoluteFramesForDisplayList(aBuilder); + child->MarkAbsoluteFramesForDisplayList(aBuilder, dirty); if (aBuilder->IsBuildingLayerEventRegions()) { // If this frame has a different animated geometry root than its parent, @@ -2932,8 +2863,8 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, // return early. aBuilder->AdjustWindowDraggingRegion(child); - child->BuildDisplayList(aBuilder, aLists); - aBuilder->DisplayCaret(child, aLists.Content()); + child->BuildDisplayList(aBuilder, dirty, aLists); + aBuilder->DisplayCaret(child, dirty, aLists.Content()); #ifdef DEBUG DisplayDebugBorders(aBuilder, child, aLists); #endif @@ -2944,10 +2875,10 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, // We allow positioned descendants of the child to escape to our parent // stacking context's positioned descendant list, because they might be // z-index:non-auto - nsDisplayListCollection pseudoStack(aBuilder); + nsDisplayListCollection pseudoStack; aBuilder->AdjustWindowDraggingRegion(child); - child->BuildDisplayList(aBuilder, pseudoStack); - aBuilder->DisplayCaret(child, pseudoStack.Content()); + child->BuildDisplayList(aBuilder, dirty, pseudoStack); + aBuilder->DisplayCaret(child, dirty, pseudoStack.Content()); list.AppendToTop(pseudoStack.BorderBackground()); list.AppendToTop(pseudoStack.BlockBorderBackgrounds()); @@ -2997,10 +2928,11 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, } void -nsIFrame::MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder) +nsIFrame::MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect) { if (IsAbsoluteContainer()) { - aBuilder->MarkFramesForDisplayList(this, GetAbsoluteContainingBlock()->GetChildList()); + aBuilder->MarkFramesForDisplayList(this, GetAbsoluteContainingBlock()->GetChildList(), aDirtyRect); } } diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp index 4315b9b8a..87cb31fd0 100644 --- a/layout/generic/nsFrameSetFrame.cpp +++ b/layout/generic/nsFrameSetFrame.cpp @@ -100,6 +100,7 @@ public: nsIFrame::Cursor& aCursor) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Reflow(nsPresContext* aPresContext, @@ -148,6 +149,7 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Reflow(nsPresContext* aPresContext, @@ -670,9 +672,10 @@ nsHTMLFramesetFrame::GetCursor(const nsPoint& aPoint, void nsHTMLFramesetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - BuildDisplayListForInline(aBuilder, aLists); + BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); if (mDragger && aBuilder->IsForEventDelivery()) { aLists.Content()->AppendNewToTop( @@ -1426,6 +1429,7 @@ void nsDisplayFramesetBorder::Paint(nsDisplayListBuilder* aBuilder, void nsHTMLFramesetBorderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { aLists.Content()->AppendNewToTop( @@ -1636,6 +1640,7 @@ void nsDisplayFramesetBlank::Paint(nsDisplayListBuilder* aBuilder, void nsHTMLFramesetBlankFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { aLists.Content()->AppendNewToTop( diff --git a/layout/generic/nsFrameSetFrame.h b/layout/generic/nsFrameSetFrame.h index b97d10c58..ac6ab07ce 100644 --- a/layout/generic/nsFrameSetFrame.h +++ b/layout/generic/nsFrameSetFrame.h @@ -97,6 +97,7 @@ public: nsIFrame::Cursor& aCursor) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Reflow(nsPresContext* aPresContext, diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index fcd365edf..3ed3b0bb3 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -3031,6 +3031,7 @@ struct HoveredStateComparator void ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists, bool aCreateLayer, bool aPositioned) @@ -3090,30 +3091,25 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, // include all of the scrollbars if we are in a RCD-RSF. We only do // this for the root scrollframe of the root content document, which is // zoomable, and where the scrollbar sizes are bounded by the widget. - nsRect visible = mIsRoot && mOuter->PresContext()->IsRootContentDocument() - ? scrollParts[i]->GetVisualOverflowRectRelativeToParent() - : aBuilder->GetVisibleRect(); nsRect dirty = mIsRoot && mOuter->PresContext()->IsRootContentDocument() ? scrollParts[i]->GetVisualOverflowRectRelativeToParent() - : aBuilder->GetDirtyRect(); + : aDirtyRect; + nsDisplayListBuilder::AutoBuildingDisplayList + buildingForChild(aBuilder, scrollParts[i], + dirty + mOuter->GetOffsetTo(scrollParts[i]), true); // Always create layers for overlay scrollbars so that we don't create a // giant layer covering the whole scrollport if both scrollbars are visible. bool isOverlayScrollbar = (flags != 0) && overlayScrollbars; bool createLayer = aCreateLayer || isOverlayScrollbar; - nsDisplayListCollection partList(aBuilder); - { - nsDisplayListBuilder::AutoBuildingDisplayList - buildingForChild(aBuilder, mOuter, - visible, dirty, true); - - nsDisplayListBuilder::AutoCurrentScrollbarInfoSetter - infoSetter(aBuilder, scrollTargetId, flags, createLayer); - mOuter->BuildDisplayListForChild( - aBuilder, scrollParts[i], partList, - nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT); - } + nsDisplayListBuilder::AutoCurrentScrollbarInfoSetter + infoSetter(aBuilder, scrollTargetId, flags, createLayer); + nsDisplayListCollection partList; + mOuter->BuildDisplayListForChild( + aBuilder, scrollParts[i], dirty, partList, + nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT); + if (createLayer) { appendToTopFlags |= APPEND_OWN_LAYER; } @@ -3121,19 +3117,11 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, appendToTopFlags |= APPEND_POSITIONED; } - { - nsDisplayListBuilder::AutoBuildingDisplayList - buildingForChild(aBuilder, scrollParts[i], - visible + mOuter->GetOffsetTo(scrollParts[i]), - dirty + mOuter->GetOffsetTo(scrollParts[i]), true); - nsDisplayListBuilder::AutoCurrentScrollbarInfoSetter - infoSetter(aBuilder, scrollTargetId, flags, createLayer); // DISPLAY_CHILD_FORCE_STACKING_CONTEXT put everything into // partList.PositionedDescendants(). ::AppendToTop(aBuilder, aLists, partList.PositionedDescendants(), scrollParts[i], appendToTopFlags); - } } } @@ -3258,6 +3246,7 @@ ClipListsExceptCaret(nsDisplayListCollection* aLists, void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (aBuilder->IsForFrameVisibility()) { @@ -3294,15 +3283,12 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, // had dirty rects saved for them by their parent frames calling // MarkOutOfFlowChildrenForDisplayList, so it's safe to restrict our // dirty rect here. - nsRect visibleRect = aBuilder->GetVisibleRect(); - nsRect dirtyRect = aBuilder->GetDirtyRect(); + nsRect dirtyRect = aDirtyRect; if (!ignoringThisScrollFrame) { - visibleRect = visibleRect.Intersect(mScrollPort); dirtyRect = dirtyRect.Intersect(mScrollPort); } - bool usingDisplayPortInvalidRect = false; - Unused << DecideScrollableLayer(aBuilder, &visibleRect, &dirtyRect, + Unused << DecideScrollableLayer(aBuilder, &dirtyRect, /* aAllowCreateDisplayPort = */ !mIsRoot); bool usingDisplayPort = aBuilder->IsPaintingToWindow() && @@ -3314,7 +3300,6 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, // too much expansion in the presence of very large (bigger than the // viewport) scroll ports. dirtyRect = ExpandRectToNearlyVisible(dirtyRect); - visibleRect = dirtyRect; } // We put non-overlay scrollbars in their own layers when this is the root @@ -3340,20 +3325,20 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, if (addScrollBars) { // Add classic scrollbars. - AppendScrollPartsTo(aBuilder, aLists, createLayersForScrollbars, false); + AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, + createLayersForScrollbars, false); } - nsDisplayListBuilder::AutoBuildingDisplayList - building(aBuilder, mOuter, visibleRect, dirtyRect, aBuilder->IsAtRootOfPseudoStackingContext()); - // Don't clip the scrolled child, and don't paint scrollbars/scrollcorner. // The scrolled frame shouldn't have its own background/border, so we // can just pass aLists directly. - mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, aLists); + mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, + dirtyRect, aLists); if (addScrollBars) { // Add overlay scrollbars. - AppendScrollPartsTo(aBuilder, aLists, createLayersForScrollbars, true); + AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, + createLayersForScrollbars, true); } return; @@ -3391,7 +3376,8 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, // Note that this does not apply for overlay scrollbars; those are drawn // in the positioned-elements layer on top of everything else by the call // to AppendScrollPartsTo(..., true) further down. - AppendScrollPartsTo(aBuilder, aLists, createLayersForScrollbars, false); + AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, + createLayersForScrollbars, false); const nsStyleDisplay* disp = mOuter->StyleDisplay(); if (disp && (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) { @@ -3428,7 +3414,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsIScrollableFrame* sf = do_QueryFrame(mOuter); MOZ_ASSERT(sf); - nsDisplayListCollection scrolledContent(aBuilder); + nsDisplayListCollection scrolledContent; { // Note that setting the current scroll parent id here means that positioned children // of this scroll info layer will pick up the scroll info layer as their scroll handoff @@ -3515,15 +3501,12 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, // pixels. // If there is no display port, we don't need this because the clip // from the scroll port is still applied. - scrolledRectClip = scrolledRectClip.Intersect(visibleRect); + scrolledRectClip = scrolledRectClip.Intersect(dirtyRect); } scrolledRectClipState.ClipContainingBlockDescendants( scrolledRectClip + aBuilder->ToReferenceFrame(mOuter)); - nsDisplayListBuilder::AutoBuildingDisplayList - building(aBuilder, mOuter, visibleRect, dirtyRect, aBuilder->IsAtRootOfPseudoStackingContext()); - - mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, scrolledContent); + mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, scrolledContent); } if (contentBoxClipForNonCaretContent) { @@ -3575,8 +3558,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, // recompute the current animated geometry root if needed. // It's too late to change the dirty rect so pass a copy. nsRect copyOfDirtyRect = dirtyRect; - nsRect copyOfVisibleRect = visibleRect; - Unused << DecideScrollableLayer(aBuilder, ©OfVisibleRect, ©OfDirtyRect, + Unused << DecideScrollableLayer(aBuilder, ©OfDirtyRect, /* aAllowCreateDisplayPort = */ false); } } @@ -3611,14 +3593,13 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, } } // Now display overlay scrollbars and the resizer, if we have one. - AppendScrollPartsTo(aBuilder, scrolledContent, createLayersForScrollbars, true); - + AppendScrollPartsTo(aBuilder, aDirtyRect, scrolledContent, + createLayersForScrollbars, true); scrolledContent.MoveTo(aLists); } bool ScrollFrameHelper::DecideScrollableLayer(nsDisplayListBuilder* aBuilder, - nsRect* aVisibleRect, nsRect* aDirtyRect, bool aAllowCreateDisplayPort) { @@ -3634,16 +3615,16 @@ ScrollFrameHelper::DecideScrollableLayer(nsDisplayListBuilder* aBuilder, if (aAllowCreateDisplayPort) { nsLayoutUtils::MaybeCreateDisplayPort(*aBuilder, mOuter); - nsRect displayportBase = *aVisibleRect; + nsRect displayportBase = *aDirtyRect; nsPresContext* pc = mOuter->PresContext(); if (mIsRoot && (pc->IsRootContentDocument() || !pc->GetParentPresContext())) { displayportBase = nsRect(nsPoint(0, 0), nsLayoutUtils::CalculateCompositionSizeForFrame(mOuter)); } else { - // Make the displayport base equal to the visible rect restricted to + // Make the displayport base equal to the dirty rect restricted to // the scrollport and the root composition bounds, relative to the // scrollport. - displayportBase = aVisibleRect->Intersect(mScrollPort); + displayportBase = aDirtyRect->Intersect(mScrollPort); // Only restrict to the root composition bounds if necessary, // as the required coordinate transformation is expensive. @@ -3706,15 +3687,12 @@ ScrollFrameHelper::DecideScrollableLayer(nsDisplayListBuilder* aBuilder, if (usingDisplayPort) { // Override the dirty rectangle if the displayport has been set. - *aVisibleRect = displayPort; *aDirtyRect = displayPort; } else if (mIsRoot) { // The displayPort getter takes care of adjusting for resolution. So if // we have resolution but no displayPort then we need to adjust for // resolution here. nsIPresShell* presShell = mOuter->PresContext()->PresShell(); - *aVisibleRect = aVisibleRect->RemoveResolution( - presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f); *aDirtyRect = aDirtyRect->RemoveResolution( presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f); } @@ -6197,4 +6175,3 @@ ScrollFrameHelper::UsesContainerScrolling() const } return false; } - diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index 8ad510d65..81bbb358f 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -70,9 +70,11 @@ public: void Destroy(); void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists); void AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists, bool aCreateLayer, bool aPositioned); @@ -402,7 +404,6 @@ public: ScrollSnapInfo GetScrollSnapInfo() const; bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder, - nsRect* aVisibleRect, nsRect* aDirtyRect, bool aAllowCreateDisplayPort); void NotifyApproximateFrameVisibilityUpdate(); @@ -686,8 +687,9 @@ public: } virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override { - mHelper.BuildDisplayList(aBuilder, aLists); + mHelper.BuildDisplayList(aBuilder, aDirtyRect, aLists); } bool TryLayout(ScrollReflowInput* aState, @@ -945,10 +947,9 @@ public: return mHelper.UsesContainerScrolling(); } virtual bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder, - nsRect* aVisibleRect, nsRect* aDirtyRect, bool aAllowCreateDisplayPort) override { - return mHelper.DecideScrollableLayer(aBuilder, aVisibleRect, aDirtyRect, aAllowCreateDisplayPort); + return mHelper.DecideScrollableLayer(aBuilder, aDirtyRect, aAllowCreateDisplayPort); } virtual void NotifyApproximateFrameVisibilityUpdate() override { mHelper.NotifyApproximateFrameVisibilityUpdate(); @@ -1104,8 +1105,9 @@ public: bool aClipAllDescendants); virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override { - mHelper.BuildDisplayList(aBuilder, aLists); + mHelper.BuildDisplayList(aBuilder, aDirtyRect, aLists); } // XXXldb Is this actually used? @@ -1451,10 +1453,9 @@ public: mHelper.SetScrollsClipOnUnscrolledOutOfFlow(); } virtual bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder, - nsRect* aVisibleRect, nsRect* aDirtyRect, bool aAllowCreateDisplayPort) override { - return mHelper.DecideScrollableLayer(aBuilder, aVisibleRect, aDirtyRect, aAllowCreateDisplayPort); + return mHelper.DecideScrollableLayer(aBuilder, aDirtyRect, aAllowCreateDisplayPort); } virtual void NotifyApproximateFrameVisibilityUpdate() override { mHelper.NotifyApproximateFrameVisibilityUpdate(); diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index baa554405..959061e33 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -6643,11 +6643,12 @@ nsGridContainerFrame::GetType() const void nsGridContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DisplayBorderBackgroundOutline(aBuilder, aLists); if (GetPrevInFlow()) { - DisplayOverflowContainers(aBuilder, aLists); + DisplayOverflowContainers(aBuilder, aDirtyRect, aLists); } // Our children are all grid-level boxes, which behave the same as @@ -6661,7 +6662,8 @@ nsGridContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, GridItemCSSOrderIterator::eIncludeAll, order); for (; !iter.AtEnd(); iter.Next()) { nsIFrame* child = *iter; - BuildDisplayListForChild(aBuilder, child, aLists, ::GetDisplayFlagsForGridItem(child)); + BuildDisplayListForChild(aBuilder, child, aDirtyRect, aLists, + ::GetDisplayFlagsForGridItem(child)); } } diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h index c9163b95c..960558421 100644 --- a/layout/generic/nsGridContainerFrame.h +++ b/layout/generic/nsGridContainerFrame.h @@ -98,6 +98,7 @@ public: } void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; nscoord GetLogicalBaseline(mozilla::WritingMode aWM) const override diff --git a/layout/generic/nsHTMLCanvasFrame.cpp b/layout/generic/nsHTMLCanvasFrame.cpp index f86ec1136..bad3a710f 100644 --- a/layout/generic/nsHTMLCanvasFrame.cpp +++ b/layout/generic/nsHTMLCanvasFrame.cpp @@ -367,6 +367,7 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder, void nsHTMLCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) diff --git a/layout/generic/nsHTMLCanvasFrame.h b/layout/generic/nsHTMLCanvasFrame.h index b2d159627..e4235deae 100644 --- a/layout/generic/nsHTMLCanvasFrame.h +++ b/layout/generic/nsHTMLCanvasFrame.h @@ -45,6 +45,7 @@ public: nsIFrame* aPrevInFlow) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 90de72d8d..93eb95099 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -1435,14 +1435,21 @@ public: * BuildDisplayListForChild. * * See nsDisplayList.h for more information about display lists. + * + * @param aDirtyRect content outside this rectangle can be ignored; the + * rectangle is in frame coordinates */ virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) {} /** * Displays the caret onto the given display list builder. The caret is * painted on top of the rest of the display list items. + * + * @param aDirtyRect is the dirty rectangle that we're repainting. */ void DisplayCaret(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, nsDisplayList* aList); /** @@ -1476,8 +1483,11 @@ public: /** * Builds a display list for the content represented by this frame, * treating this frame as the root of a stacking context. + * @param aDirtyRect content outside this rectangle can be ignored; the + * rectangle is in frame coordinates */ void BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, nsDisplayList* aList); enum { @@ -1496,6 +1506,7 @@ public: */ void BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, nsIFrame* aChild, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists, uint32_t aFlags = 0); @@ -3519,23 +3530,13 @@ protected: nsRect mRect; nsIContent* mContent; nsStyleContext* mStyleContext; - /** - * This bit is used during BuildDisplayList to mark frames that need to - * have display items rebuilt. We will descend into them if they are - * currently visible, even if they don't intersect the dirty area. - */ - bool mForceDescendIntoIfVisible : 1; private: nsContainerFrame* mParent; nsIFrame* mNextSibling; // doubly-linked list of frames nsIFrame* mPrevSibling; // Do not touch outside SetNextSibling! - void MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder); - public: - bool ForceDescendIntoIfVisible() const { return mForceDescendIntoIfVisible; } - void SetForceDescendIntoIfVisible(bool aForce) { - mForceDescendIntoIfVisible = aForce; - } + void MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect); + static void DestroyPaintedPresShellList(nsTArray<nsWeakPtr>* list) { list->Clear(); delete list; diff --git a/layout/generic/nsIScrollableFrame.h b/layout/generic/nsIScrollableFrame.h index 20a598452..b7e3caf46 100644 --- a/layout/generic/nsIScrollableFrame.h +++ b/layout/generic/nsIScrollableFrame.h @@ -440,16 +440,13 @@ public: /** * Determine if we should build a scrollable layer for this scroll frame and * return the result. It will also record this result on the scroll frame. - * Pass the visible rect in aVisibleRect. On return it will be set to the - * displayport if there is one. * Pass the dirty rect in aDirtyRect. On return it will be set to the - * dirty rect inside the displayport (ie the dirty rect that should be used). + * displayport if there is one (ie the dirty rect that should be used). * This function may create a display port where one did not exist before if * aAllowCreateDisplayPort is true. It is only allowed to be false if there * has been a call with it set to true before on the same paint. */ virtual bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder, - nsRect* aVisibleRect, nsRect* aDirtyRect, bool aAllowCreateDisplayPort) = 0; diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 342370050..c64520f2e 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1730,6 +1730,7 @@ nsImageFrame::PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt, void nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index fceecc43d..5bc59c042 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -82,6 +82,7 @@ public: nsContainerFrame* aParent, nsIFrame* aPrevInFlow) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override; virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override; diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index fb77422a3..7e188c247 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -243,9 +243,10 @@ nsInlineFrame::StealFrame(nsIFrame* aChild) void nsInlineFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - BuildDisplayListForInline(aBuilder, aLists); + BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); // The sole purpose of this is to trigger display of the selection // window for Named Anchors, which don't have any children and diff --git a/layout/generic/nsInlineFrame.h b/layout/generic/nsInlineFrame.h index c1e0d7fe3..36df6be93 100644 --- a/layout/generic/nsInlineFrame.h +++ b/layout/generic/nsInlineFrame.h @@ -31,6 +31,7 @@ public: // nsIFrame overrides virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; #ifdef ACCESSIBILITY diff --git a/layout/generic/nsLeafFrame.h b/layout/generic/nsLeafFrame.h index 7087fb6cf..407f9846d 100644 --- a/layout/generic/nsLeafFrame.h +++ b/layout/generic/nsLeafFrame.h @@ -24,6 +24,7 @@ public: // nsIFrame replacements virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override { DO_GLOBAL_REFLOW_COUNT_DSP("nsLeafFrame"); DisplayBorderBackgroundOutline(aBuilder, aLists); diff --git a/layout/generic/nsPageFrame.cpp b/layout/generic/nsPageFrame.cpp index 7ec90c051..ae3af6ef7 100644 --- a/layout/generic/nsPageFrame.cpp +++ b/layout/generic/nsPageFrame.cpp @@ -437,7 +437,7 @@ PruneDisplayListForExtraPage(nsDisplayListBuilder* aBuilder, static void BuildDisplayListForExtraPage(nsDisplayListBuilder* aBuilder, nsPageFrame* aPage, nsIFrame* aExtraPage, - nsDisplayList* aList) + const nsRect& aDirtyRect, nsDisplayList* aList) { // The only content in aExtraPage we care about is out-of-flow content whose // placeholders have occurred in aPage. If @@ -447,7 +447,7 @@ BuildDisplayListForExtraPage(nsDisplayListBuilder* aBuilder, return; } nsDisplayList list; - aExtraPage->BuildDisplayListForStackingContext(aBuilder, &list); + aExtraPage->BuildDisplayListForStackingContext(aBuilder, aDirtyRect, &list); PruneDisplayListForExtraPage(aBuilder, aPage, aExtraPage, &list); aList->AppendToTop(&list); } @@ -517,9 +517,10 @@ protected: //------------------------------------------------------------------------------ void nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsDisplayListCollection set(aBuilder); + nsDisplayListCollection set; if (PresContext()->IsScreen()) { DisplayBorderBackgroundOutline(aBuilder, aLists); @@ -556,11 +557,8 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, clipState.Clear(); clipState.ClipContainingBlockDescendants(clipRect, nullptr); - nsRect visibleRect = child->GetVisualOverflowRectRelativeToSelf(); - nsDisplayListBuilder::AutoBuildingDisplayList - buildingForChild(aBuilder, child, visibleRect, visibleRect, - aBuilder->IsAtRootOfPseudoStackingContext()); - child->BuildDisplayListForStackingContext(aBuilder, &content); + nsRect dirtyRect = child->GetVisualOverflowRectRelativeToSelf(); + child->BuildDisplayListForStackingContext(aBuilder, dirtyRect, &content); // We may need to paint out-of-flow frames whose placeholders are // on other pages. Add those pages to our display list. Note that @@ -571,19 +569,15 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // following placeholders to their out-of-flows) end up on the list. nsIFrame* page = child; while ((page = GetNextPage(page)) != nullptr) { - nsRect childVisible = visibleRect + child->GetOffsetTo(page); - - nsDisplayListBuilder::AutoBuildingDisplayList - buildingForChild(aBuilder, page, childVisible, childVisible, - aBuilder->IsAtRootOfPseudoStackingContext()); - BuildDisplayListForExtraPage(aBuilder, this, page, &content); + BuildDisplayListForExtraPage(aBuilder, this, page, + dirtyRect + child->GetOffsetTo(page), &content); } - // Invoke AutoBuildingDisplayList to ensure that the correct visibleRect + // Invoke AutoBuildingDisplayList to ensure that the correct dirtyRect // is used to compute the visible rect if AddCanvasBackgroundColorItem // creates a display item. nsDisplayListBuilder::AutoBuildingDisplayList - building(aBuilder, child, visibleRect, visibleRect, true); + building(aBuilder, child, dirtyRect, true); // Add the canvas background color to the bottom of the list. This // happens after we've built the list so that AddCanvasBackgroundColorItem diff --git a/layout/generic/nsPageFrame.h b/layout/generic/nsPageFrame.h index 86516fe73..aab2ac7b8 100644 --- a/layout/generic/nsPageFrame.h +++ b/layout/generic/nsPageFrame.h @@ -29,6 +29,7 @@ public: nsReflowStatus& aStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; /** diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp index f234b2f2d..bd380a2d9 100644 --- a/layout/generic/nsPlaceholderFrame.cpp +++ b/layout/generic/nsPlaceholderFrame.cpp @@ -240,6 +240,7 @@ PaintDebugPlaceholder(nsIFrame* aFrame, DrawTarget* aDrawTarget, void nsPlaceholderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DO_GLOBAL_REFLOW_COUNT_DSP("nsPlaceholderFrame"); diff --git a/layout/generic/nsPlaceholderFrame.h b/layout/generic/nsPlaceholderFrame.h index 11cb98592..0c23a4f75 100644 --- a/layout/generic/nsPlaceholderFrame.h +++ b/layout/generic/nsPlaceholderFrame.h @@ -107,6 +107,7 @@ public: #if defined(DEBUG) || (defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)) virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; #endif // DEBUG || (MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF) diff --git a/layout/generic/nsPluginFrame.cpp b/layout/generic/nsPluginFrame.cpp index 6e9e072e7..34ed12d44 100644 --- a/layout/generic/nsPluginFrame.cpp +++ b/layout/generic/nsPluginFrame.cpp @@ -1182,6 +1182,7 @@ nsPluginFrame::IsTransparentMode() const void nsPluginFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // XXX why are we painting collapsed object frames? diff --git a/layout/generic/nsPluginFrame.h b/layout/generic/nsPluginFrame.h index 57db78acc..5d9f9f475 100644 --- a/layout/generic/nsPluginFrame.h +++ b/layout/generic/nsPluginFrame.h @@ -81,6 +81,7 @@ public: const ReflowInput* aReflowInput, nsDidReflowStatus aStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsresult HandleEvent(nsPresContext* aPresContext, diff --git a/layout/generic/nsRubyTextFrame.cpp b/layout/generic/nsRubyTextFrame.cpp index 2848cb6fc..b4a26ff33 100644 --- a/layout/generic/nsRubyTextFrame.cpp +++ b/layout/generic/nsRubyTextFrame.cpp @@ -63,13 +63,14 @@ nsRubyTextFrame::GetFrameName(nsAString& aResult) const /* virtual */ void nsRubyTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (IsAutoHidden()) { return; } - nsRubyContentFrame::BuildDisplayList(aBuilder, aLists); + nsRubyContentFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); } /* virtual */ void diff --git a/layout/generic/nsRubyTextFrame.h b/layout/generic/nsRubyTextFrame.h index 83c24d49d..841b5081f 100644 --- a/layout/generic/nsRubyTextFrame.h +++ b/layout/generic/nsRubyTextFrame.h @@ -34,6 +34,7 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Reflow(nsPresContext* aPresContext, diff --git a/layout/generic/nsSimplePageSequenceFrame.cpp b/layout/generic/nsSimplePageSequenceFrame.cpp index 6dcb6ccc1..2e74afc3b 100644 --- a/layout/generic/nsSimplePageSequenceFrame.cpp +++ b/layout/generic/nsSimplePageSequenceFrame.cpp @@ -808,6 +808,7 @@ ComputePageSequenceTransform(nsIFrame* aFrame, float aAppUnitsPerPixel) void nsSimplePageSequenceFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DisplayBorderBackgroundOutline(aBuilder, aLists); @@ -821,17 +822,13 @@ nsSimplePageSequenceFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, clipState.Clear(); nsIFrame* child = PrincipalChildList().FirstChild(); - nsRect visible = aBuilder->GetVisibleRect(); - visible.ScaleInverseRoundOut(PresContext()->GetPrintPreviewScale()); + nsRect dirty = aDirtyRect; + dirty.ScaleInverseRoundOut(PresContext()->GetPrintPreviewScale()); while (child) { - if (child->GetVisualOverflowRectRelativeToParent().Intersects(visible)) { - nsDisplayListBuilder::AutoBuildingDisplayList - buildingForChild(aBuilder, child, - visible - child->GetPosition(), - visible - child->GetPosition(), - aBuilder->IsAtRootOfPseudoStackingContext()); - child->BuildDisplayListForStackingContext(aBuilder, &content); + if (child->GetVisualOverflowRectRelativeToParent().Intersects(dirty)) { + child->BuildDisplayListForStackingContext(aBuilder, + dirty - child->GetPosition(), &content); aBuilder->ResetMarkedFramesForDisplayList(); } child = child->GetNextSibling(); diff --git a/layout/generic/nsSimplePageSequenceFrame.h b/layout/generic/nsSimplePageSequenceFrame.h index 4981c67a8..c4e1e84b6 100644 --- a/layout/generic/nsSimplePageSequenceFrame.h +++ b/layout/generic/nsSimplePageSequenceFrame.h @@ -69,6 +69,7 @@ public: nsReflowStatus& aStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; // nsIPageSequenceFrame diff --git a/layout/generic/nsSubDocumentFrame.cpp b/layout/generic/nsSubDocumentFrame.cpp index 1c5ade583..47026b73c 100644 --- a/layout/generic/nsSubDocumentFrame.cpp +++ b/layout/generic/nsSubDocumentFrame.cpp @@ -327,6 +327,7 @@ WrapBackgroundColorInOwnLayer(nsDisplayListBuilder* aBuilder, void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) @@ -342,7 +343,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, bool pointerEventsNone = StyleUserInterface()->mPointerEvents == NS_STYLE_POINTER_EVENTS_NONE; if (!aBuilder->IsForEventDelivery() || !pointerEventsNone) { - nsDisplayListCollection decorations(aBuilder); + nsDisplayListCollection decorations; DisplayBorderBackgroundOutline(aBuilder, decorations); if (rfp) { // Wrap background colors of <iframe>s with remote subdocuments in their @@ -367,7 +368,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } if (rfp) { - rfp->BuildDisplayList(aBuilder, this, aLists); + rfp->BuildDisplayList(aBuilder, this, aDirtyRect, aLists); return; } @@ -386,28 +387,23 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, int32_t parentAPD = PresContext()->AppUnitsPerDevPixel(); int32_t subdocAPD = presContext->AppUnitsPerDevPixel(); - nsRect visible; nsRect dirty; bool haveDisplayPort = false; bool ignoreViewportScrolling = false; nsIFrame* savedIgnoreScrollFrame = nullptr; if (subdocRootFrame) { // get the dirty rect relative to the root frame of the subdoc - visible = aBuilder->GetVisibleRect() + GetOffsetToCrossDoc(subdocRootFrame); - dirty = aBuilder->GetDirtyRect() + GetOffsetToCrossDoc(subdocRootFrame); + dirty = aDirtyRect + GetOffsetToCrossDoc(subdocRootFrame); // and convert into the appunits of the subdoc - visible = visible.ScaleToOtherAppUnitsRoundOut(parentAPD, subdocAPD); dirty = dirty.ScaleToOtherAppUnitsRoundOut(parentAPD, subdocAPD); if (nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame()) { nsIScrollableFrame* rootScrollableFrame = presShell->GetRootScrollFrameAsScrollable(); MOZ_ASSERT(rootScrollableFrame); - // Use a copy, so the rects don't get modified. - nsRect copyOfDirty = dirty; - nsRect copyOfVisible = visible; + // Use a copy, so the dirty rect doesn't get modified to the display port. + nsRect copy = dirty; haveDisplayPort = rootScrollableFrame->DecideScrollableLayer(aBuilder, - ©OfVisible, ©OfDirty, - /* aAllowCreateDisplayPort = */ true); + ©, /* aAllowCreateDisplayPort = */ true); if (!gfxPrefs::LayoutUseContainersForRootFrames()) { haveDisplayPort = false; } @@ -421,8 +417,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, aBuilder->EnterPresShell(subdocRootFrame, pointerEventsNone); } else { - visible = aBuilder->GetVisibleRect(); - dirty = aBuilder->GetDirtyRect(); + dirty = aDirtyRect; } DisplayListClipState::AutoSaveRestore clipState(aBuilder); @@ -461,13 +456,6 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, nestedClipState.EnterStackingContextContents(true); } - // Invoke AutoBuildingDisplayList to ensure that the correct dirty rect - // is used to compute the visible rect if AddCanvasBackgroundColorItem - // creates a display item. - nsIFrame* frame = subdocRootFrame ? subdocRootFrame : this; - nsDisplayListBuilder::AutoBuildingDisplayList - building(aBuilder, frame, visible, dirty, true); - if (subdocRootFrame) { nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame(); nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter( @@ -478,7 +466,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, aBuilder->SetAncestorHasApzAwareEventHandler(false); subdocRootFrame-> - BuildDisplayListForStackingContext(aBuilder, &childItems); + BuildDisplayListForStackingContext(aBuilder, dirty, &childItems); } if (!aBuilder->IsForEventDelivery()) { @@ -497,8 +485,15 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // painted on the page itself. if (nsLayoutUtils::NeedsPrintPreviewBackground(presContext)) { presShell->AddPrintPreviewBackgroundItem( - *aBuilder, childItems, frame, bounds); + *aBuilder, childItems, subdocRootFrame ? subdocRootFrame : this, + bounds); } else { + // Invoke AutoBuildingDisplayList to ensure that the correct dirty rect + // is used to compute the visible rect if AddCanvasBackgroundColorItem + // creates a display item. + nsIFrame* frame = subdocRootFrame ? subdocRootFrame : this; + nsDisplayListBuilder::AutoBuildingDisplayList + building(aBuilder, frame, dirty, true); // Add the canvas background color to the bottom of the list. This // happens after we've built the list so that AddCanvasBackgroundColorItem // can monkey with the contents if necessary. diff --git a/layout/generic/nsSubDocumentFrame.h b/layout/generic/nsSubDocumentFrame.h index 93d908dcc..54f08d4fe 100644 --- a/layout/generic/nsSubDocumentFrame.h +++ b/layout/generic/nsSubDocumentFrame.h @@ -79,6 +79,7 @@ public: nsReflowStatus& aStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsresult AttributeChanged(int32_t aNameSpaceID, diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 4bc542626..59ef020ce 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -4998,6 +4998,7 @@ nsDisplayText::Paint(nsDisplayListBuilder* aBuilder, void nsTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index 43a4f5f1c..425dbb737 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -65,6 +65,7 @@ public: // nsIFrame virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Init(nsIContent* aContent, diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp index 43383044b..9f27684a7 100644 --- a/layout/generic/nsVideoFrame.cpp +++ b/layout/generic/nsVideoFrame.cpp @@ -446,6 +446,7 @@ public: void nsVideoFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) @@ -481,16 +482,14 @@ nsVideoFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // but only want to draw mPosterImage conditionally. Others we // always add to the display list. for (nsIFrame* child : mFrames) { - if (child->GetContent() != mPosterImage || shouldDisplayPoster || - child->GetType() == nsGkAtoms::boxFrame) { - - nsDisplayListBuilder::AutoBuildingDisplayList - buildingForChild(aBuilder, child, - aBuilder->GetVisibleRect() - child->GetOffsetTo(this), - aBuilder->GetDirtyRect() - child->GetOffsetTo(this), - aBuilder->IsAtRootOfPseudoStackingContext()); - - child->BuildDisplayListForStackingContext(aBuilder, aLists.Content()); + if (child->GetContent() != mPosterImage || shouldDisplayPoster) { + child->BuildDisplayListForStackingContext(aBuilder, + aDirtyRect - child->GetOffsetTo(this), + aLists.Content()); + } else if (child->GetType() == nsGkAtoms::boxFrame) { + child->BuildDisplayListForStackingContext(aBuilder, + aDirtyRect - child->GetOffsetTo(this), + aLists.Content()); } } } diff --git a/layout/generic/nsVideoFrame.h b/layout/generic/nsVideoFrame.h index d624ae6b9..36e9f9ac3 100644 --- a/layout/generic/nsVideoFrame.h +++ b/layout/generic/nsVideoFrame.h @@ -45,6 +45,7 @@ public: NS_DECL_FRAMEARENA_HELPERS virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsresult AttributeChanged(int32_t aNameSpaceID, diff --git a/layout/generic/nsViewportFrame.cpp b/layout/generic/nsViewportFrame.cpp index a7a8cd50c..39491a0ed 100644 --- a/layout/generic/nsViewportFrame.cpp +++ b/layout/generic/nsViewportFrame.cpp @@ -48,6 +48,7 @@ ViewportFrame::Init(nsIContent* aContent, void ViewportFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { PROFILER_LABEL("ViewportFrame", "BuildDisplayList", @@ -57,7 +58,7 @@ ViewportFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // make the kid's BorderBackground our own. This ensures that the canvas // frame's background becomes our own background and therefore appears // below negative z-index elements. - BuildDisplayListForChild(aBuilder, kid, aLists); + BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); } nsDisplayList topLayerList; @@ -97,25 +98,19 @@ BuildDisplayListForTopLayerFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList) { - nsRect visible; nsRect dirty; DisplayListClipState::AutoClipMultiple clipState(aBuilder); nsDisplayListBuilder::OutOfFlowDisplayData* savedOutOfFlowData = nsDisplayListBuilder::GetOutOfFlowData(aFrame); if (savedOutOfFlowData) { - visible = savedOutOfFlowData->mVisibleRect; dirty = savedOutOfFlowData->mDirtyRect; clipState.SetClipForContainingBlockDescendants( &savedOutOfFlowData->mContainingBlockClip); clipState.SetScrollClipForContainingBlockDescendants( aBuilder, savedOutOfFlowData->mContainingBlockScrollClip); } - nsDisplayListBuilder::AutoBuildingDisplayList - buildingForChild(aBuilder, aFrame, visible, dirty, - aBuilder->IsAtRootOfPseudoStackingContext()); - nsDisplayList list; - aFrame->BuildDisplayListForStackingContext(aBuilder, &list); + aFrame->BuildDisplayListForStackingContext(aBuilder, dirty, &list); aList->AppendToTop(&list); } diff --git a/layout/generic/nsViewportFrame.h b/layout/generic/nsViewportFrame.h index 3e5263093..062de4054 100644 --- a/layout/generic/nsViewportFrame.h +++ b/layout/generic/nsViewportFrame.h @@ -56,6 +56,7 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; void BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder, diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 0f4aa11bb..8162d02d7 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -266,6 +266,7 @@ RenderFrameParent::GetLayerTreeId() const void RenderFrameParent::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsSubDocumentFrame* aFrame, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // We're the subdoc for <browser remote="true"> and it has diff --git a/layout/ipc/RenderFrameParent.h b/layout/ipc/RenderFrameParent.h index f91cfe614..274f8ff6d 100644 --- a/layout/ipc/RenderFrameParent.h +++ b/layout/ipc/RenderFrameParent.h @@ -64,6 +64,7 @@ public: void BuildDisplayList(nsDisplayListBuilder* aBuilder, nsSubDocumentFrame* aFrame, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists); already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp index 4b02a52d8..507e32b22 100644 --- a/layout/mathml/nsMathMLChar.cpp +++ b/layout/mathml/nsMathMLChar.cpp @@ -1992,8 +1992,7 @@ nsMathMLChar::Display(nsDisplayListBuilder* aBuilder, if (styleContext != parentContext && NS_GET_A(backg->mBackgroundColor) > 0) { nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, aForFrame, mRect + aBuilder->ToReferenceFrame(aForFrame), - aLists.BorderBackground(), + aBuilder, aForFrame, mRect, aLists.BorderBackground(), /* aAllowWillPaintBorderOptimization */ true, styleContext); } //else diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp index 8e22ba204..93b631c9d 100644 --- a/layout/mathml/nsMathMLContainerFrame.cpp +++ b/layout/mathml/nsMathMLContainerFrame.cpp @@ -618,6 +618,7 @@ nsMathMLContainerFrame::PropagatePresentationDataFromChildAt(nsIFrame* aPa void nsMathMLContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // report an error if something wrong was found in this frame @@ -632,7 +633,8 @@ nsMathMLContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, DisplayBorderBackgroundOutline(aBuilder, aLists); - BuildDisplayListForNonBlockChildren(aBuilder, aLists, DISPLAY_CHILD_INLINE); + BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists, + DISPLAY_CHILD_INLINE); #if defined(DEBUG) && defined(SHOW_BOUNDING_BOX) // for visual debug diff --git a/layout/mathml/nsMathMLContainerFrame.h b/layout/mathml/nsMathMLContainerFrame.h index 61c59a4fe..94ccf70d2 100644 --- a/layout/mathml/nsMathMLContainerFrame.h +++ b/layout/mathml/nsMathMLContainerFrame.h @@ -126,6 +126,7 @@ public: } virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override; diff --git a/layout/mathml/nsMathMLSelectedFrame.cpp b/layout/mathml/nsMathMLSelectedFrame.cpp index 11eb14d83..2378d0763 100644 --- a/layout/mathml/nsMathMLSelectedFrame.cpp +++ b/layout/mathml/nsMathMLSelectedFrame.cpp @@ -71,13 +71,14 @@ nsMathMLSelectedFrame::SetInitialChildList(ChildListID aListID, // Only paint the selected child... void nsMathMLSelectedFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // Report an error if something wrong was found in this frame. // We can't call nsDisplayMathMLError from here, // so ask nsMathMLContainerFrame to do the work for us. if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) { - nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists); + nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); return; } @@ -88,7 +89,7 @@ nsMathMLSelectedFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // Put the child's background directly onto the content list nsDisplayListSet set(aLists, aLists.Content()); // The children should be in content order - BuildDisplayListForChild(aBuilder, childFrame, set); + BuildDisplayListForChild(aBuilder, childFrame, aDirtyRect, set); } #if defined(DEBUG) && defined(SHOW_BOUNDING_BOX) diff --git a/layout/mathml/nsMathMLSelectedFrame.h b/layout/mathml/nsMathMLSelectedFrame.h index 872351829..ad523a594 100644 --- a/layout/mathml/nsMathMLSelectedFrame.h +++ b/layout/mathml/nsMathMLSelectedFrame.h @@ -26,6 +26,7 @@ public: ChildListChanged(int32_t aModType) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsresult diff --git a/layout/mathml/nsMathMLmencloseFrame.cpp b/layout/mathml/nsMathMLmencloseFrame.cpp index 236a5ab07..64277a92e 100644 --- a/layout/mathml/nsMathMLmencloseFrame.cpp +++ b/layout/mathml/nsMathMLmencloseFrame.cpp @@ -201,11 +201,12 @@ nsMathMLmencloseFrame::TransmitAutomaticData() void nsMathMLmencloseFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { ///////////// // paint the menclosed content - nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists); + nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) return; diff --git a/layout/mathml/nsMathMLmencloseFrame.h b/layout/mathml/nsMathMLmencloseFrame.h index e9e7a2b0a..82d73b2cf 100644 --- a/layout/mathml/nsMathMLmencloseFrame.h +++ b/layout/mathml/nsMathMLmencloseFrame.h @@ -70,6 +70,7 @@ public: GetAdditionalStyleContext(int32_t aIndex) const override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; NS_IMETHOD diff --git a/layout/mathml/nsMathMLmfencedFrame.cpp b/layout/mathml/nsMathMLmfencedFrame.cpp index 5d66e541b..ca780e649 100644 --- a/layout/mathml/nsMathMLmfencedFrame.cpp +++ b/layout/mathml/nsMathMLmfencedFrame.cpp @@ -161,11 +161,12 @@ nsMathMLmfencedFrame::CreateFencesAndSeparators(nsPresContext* aPresContext) void nsMathMLmfencedFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { ///////////// // display the content - nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists); + nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); //////////// // display fences and separators diff --git a/layout/mathml/nsMathMLmfencedFrame.h b/layout/mathml/nsMathMLmfencedFrame.h index 472e5aed9..2d7535d0c 100644 --- a/layout/mathml/nsMathMLmfencedFrame.h +++ b/layout/mathml/nsMathMLmfencedFrame.h @@ -41,6 +41,7 @@ public: nsReflowStatus& aStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void diff --git a/layout/mathml/nsMathMLmfracFrame.cpp b/layout/mathml/nsMathMLmfracFrame.cpp index 731cca7d0..4e74faea2 100644 --- a/layout/mathml/nsMathMLmfracFrame.cpp +++ b/layout/mathml/nsMathMLmfracFrame.cpp @@ -149,11 +149,12 @@ nsMathMLmfracFrame::CalcLineThickness(nsPresContext* aPresContext, void nsMathMLmfracFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { ///////////// // paint the numerator and denominator - nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists); + nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); ///////////// // paint the fraction line diff --git a/layout/mathml/nsMathMLmfracFrame.h b/layout/mathml/nsMathMLmfracFrame.h index 8ced03694..330a31180 100644 --- a/layout/mathml/nsMathMLmfracFrame.h +++ b/layout/mathml/nsMathMLmfracFrame.h @@ -67,6 +67,7 @@ public: ReflowOutput& aDesiredSize) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsresult diff --git a/layout/mathml/nsMathMLmoFrame.cpp b/layout/mathml/nsMathMLmoFrame.cpp index 3ef7b88d0..591b46309 100644 --- a/layout/mathml/nsMathMLmoFrame.cpp +++ b/layout/mathml/nsMathMLmoFrame.cpp @@ -78,13 +78,14 @@ nsMathMLmoFrame::UseMathMLChar() void nsMathMLmoFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { bool useMathMLChar = UseMathMLChar(); if (!useMathMLChar) { // let the base class do everything - nsMathMLTokenFrame::BuildDisplayList(aBuilder, aLists); + nsMathMLTokenFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); } else { DisplayBorderBackgroundOutline(aBuilder, aLists); diff --git a/layout/mathml/nsMathMLmoFrame.h b/layout/mathml/nsMathMLmoFrame.h index 15df62ac2..f25107a20 100644 --- a/layout/mathml/nsMathMLmoFrame.h +++ b/layout/mathml/nsMathMLmoFrame.h @@ -29,6 +29,7 @@ public: GetAdditionalStyleContext(int32_t aIndex) const override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; NS_IMETHOD diff --git a/layout/mathml/nsMathMLmrootFrame.cpp b/layout/mathml/nsMathMLmrootFrame.cpp index 300adcb91..4c81bde3d 100644 --- a/layout/mathml/nsMathMLmrootFrame.cpp +++ b/layout/mathml/nsMathMLmrootFrame.cpp @@ -77,11 +77,12 @@ nsMathMLmrootFrame::TransmitAutomaticData() void nsMathMLmrootFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { ///////////// // paint the content we are square-rooting - nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists); + nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); ///////////// // paint the sqrt symbol diff --git a/layout/mathml/nsMathMLmrootFrame.h b/layout/mathml/nsMathMLmrootFrame.h index ddf6f89a6..0996af26b 100644 --- a/layout/mathml/nsMathMLmrootFrame.h +++ b/layout/mathml/nsMathMLmrootFrame.h @@ -51,6 +51,7 @@ public: ReflowOutput& aDesiredSize) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; uint8_t diff --git a/layout/reftests/position-relative/1409114-1-ref.html b/layout/reftests/position-relative/1409114-1-ref.html deleted file mode 100644 index a2bd3213d..000000000 --- a/layout/reftests/position-relative/1409114-1-ref.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> -<body> -<table> - <col style="background:green"> - <tr> - <td style="width:20px; height:20px"></td> - </tr> -</table> -</body> - -</html> diff --git a/layout/reftests/position-relative/1409114-1.html b/layout/reftests/position-relative/1409114-1.html deleted file mode 100644 index 988ecab1e..000000000 --- a/layout/reftests/position-relative/1409114-1.html +++ /dev/null @@ -1,11 +0,0 @@ -<!DOCTYPE html> -<html> -<body> -<table> - <col style="background:green"> - <tr> - <td style="position:relative; left:-100px; width:20px; height:20px"></td> - </tr> -</table> -</body> -</html> diff --git a/layout/reftests/position-relative/1409114-2.html b/layout/reftests/position-relative/1409114-2.html deleted file mode 100644 index 6d5e3c617..000000000 --- a/layout/reftests/position-relative/1409114-2.html +++ /dev/null @@ -1,13 +0,0 @@ -<!DOCTYPE html> -<html> -<body style="overflow:hidden"> -<table style="position:relative; top:-50px"> - <col style="background:green; width: 40px;"> - <tr style="position:relative; left:-100px; height: 40px"> - <td rowspan=2></td> - </tr> - <tr style="height: 40px"></tr> -</table> -</body> - -</html> diff --git a/layout/reftests/position-relative/1409114-3.html b/layout/reftests/position-relative/1409114-3.html deleted file mode 100644 index cfd01561d..000000000 --- a/layout/reftests/position-relative/1409114-3.html +++ /dev/null @@ -1,13 +0,0 @@ -<!DOCTYPE html> -<html> -<body style="overflow:hidden"> -<table style="position:relative; top:-50px"> - <tbody style="background:green"> - <tr style="position:relative; left:-100px; height: 40px"> - <td rowspan=2 style="width: 40px;"></td> - </tr> - <tr style="height: 40px"></tr> - </tbody> -</table> -</body> -</html> diff --git a/layout/reftests/position-relative/reftest.list b/layout/reftests/position-relative/reftest.list index 495588ab7..880a38e8d 100644 --- a/layout/reftests/position-relative/reftest.list +++ b/layout/reftests/position-relative/reftest.list @@ -7,6 +7,3 @@ == table-separate-3.html table-separate-3-ref.html == table-separate-4.html table-separate-4-ref.html == 1115999-1.html 1115999-1-ref.html -== 1409114-1.html 1409114-1-ref.html -!= 1409114-2.html about:blank -!= 1409114-3.html about:blank diff --git a/layout/reftests/table-background/border-collapse-opacity-table-column-group-ref.html b/layout/reftests/table-background/border-collapse-opacity-table-column-group-ref.html index 9ec969236..bb03f1525 100644 --- a/layout/reftests/table-background/border-collapse-opacity-table-column-group-ref.html +++ b/layout/reftests/table-background/border-collapse-opacity-table-column-group-ref.html @@ -10,6 +10,8 @@ html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } body { padding: 15px; } + .o { opacity: 0.5; } + /* table { margin: 0px 3px 2px 4px; @@ -53,8 +55,8 @@ </head> <body> -<div class="color"></div> -<div class="imagetl"></div> +<div class="color o"></div> +<div class="imagetl o"></div> <div class="imagebr"></div> </body> diff --git a/layout/reftests/table-background/border-collapse-opacity-table-column-ref.html b/layout/reftests/table-background/border-collapse-opacity-table-column-ref.html index 82795ef8b..7b7df902e 100644 --- a/layout/reftests/table-background/border-collapse-opacity-table-column-ref.html +++ b/layout/reftests/table-background/border-collapse-opacity-table-column-ref.html @@ -10,6 +10,8 @@ html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } body { padding: 15px; } + .o { opacity: 0.5; } + /* table { margin: 0px 3px 2px 4px; @@ -53,8 +55,8 @@ </head> <body> -<div class="color"></div> -<div class="imagetl"></div> +<div class="color o"></div> +<div class="imagetl o"></div> <div class="imagebr"></div> </body> diff --git a/layout/reftests/table-background/border-separate-opacity-table-column-group-ref.html b/layout/reftests/table-background/border-separate-opacity-table-column-group-ref.html index 6985dae64..ad6ca2453 100644 --- a/layout/reftests/table-background/border-separate-opacity-table-column-group-ref.html +++ b/layout/reftests/table-background/border-separate-opacity-table-column-group-ref.html @@ -10,6 +10,8 @@ html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } body { padding: 15px; } + .o { opacity: 0.5; } + /* table { margin: 0px 3px 2px 4px; @@ -63,8 +65,8 @@ <body> <div class="color"></div> -<div class="imagetl"></div> -<div class="imagebr"></div> +<div class="imagetl o"></div> +<div class="imagebr o"></div> <div class="hstripe" style="top: 46px"></div> <div class="hstripe" style="top: 70px"></div> diff --git a/layout/reftests/table-background/border-separate-opacity-table-column-ref.html b/layout/reftests/table-background/border-separate-opacity-table-column-ref.html index a6629347d..e00193dc3 100644 --- a/layout/reftests/table-background/border-separate-opacity-table-column-ref.html +++ b/layout/reftests/table-background/border-separate-opacity-table-column-ref.html @@ -10,6 +10,8 @@ html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } body { padding: 15px; } + .o { opacity: 0.5; } + /* table { margin: 0px 3px 2px 4px; @@ -63,8 +65,8 @@ <body> <div class="color"></div> -<div class="imagetl"></div> -<div class="imagebr"></div> +<div class="imagetl o"></div> +<div class="imagebr o"></div> <div class="hstripe" style="top: 46px"></div> <div class="hstripe" style="top: 70px"></div> diff --git a/layout/reftests/table-background/reftest.list b/layout/reftests/table-background/reftest.list index 727a7de08..68dc43e95 100644 --- a/layout/reftests/table-background/reftest.list +++ b/layout/reftests/table-background/reftest.list @@ -40,30 +40,23 @@ asserts-if(gtkWidget,0-6) != backgr_border-table-quirks.html empty.html == border-collapse-table-row-group.html border-collapse-table-row-group-ref.html == border-collapse-table-row.html border-collapse-table-row-ref.html == border-collapse-table.html border-collapse-table-ref.html -fuzzy-if(d2d,0-1,0-1083) fuzzy-if(skiaContent,0-1,0-2200) == border-collapse-opacity-table-cell.html border-collapse-opacity-table-cell-ref.html -fuzzy-if(d2d,0-1,0-33174) fuzzy-if(skiaContent,0-1,0-16863) == border-collapse-opacity-table-column-group.html border-collapse-opacity-table-column-group-ref.html -fuzzy-if(d2d,0-1,0-11058) fuzzy-if(skiaContent,0-1,0-5625) == border-collapse-opacity-table-column.html border-collapse-opacity-table-column-ref.html -fuzzy-if(d2d,0-1,0-24606) fuzzy-if(skiaContent,0-1,0-17000) == border-collapse-opacity-table-row-group.html border-collapse-opacity-table-row-group-ref.html -fuzzy-if(d2d,0-1,0-11000) fuzzy-if(skiaContent,0-1,0-11000) == border-collapse-opacity-table-row.html border-collapse-opacity-table-row-ref.html -fuzzy-if(d2d||skiaContent,0-1,0-60000) == border-collapse-opacity-table.html border-collapse-opacity-table-ref.html -fuzzy-if(d2d,0-1,0-2478) fuzzy-if(skiaContent,0-1,0-2500) == border-separate-opacity-table-cell.html border-separate-opacity-table-cell-ref.html -fuzzy-if(d2d,0-1,0-38000) == border-separate-opacity-table-column-group.html border-separate-opacity-table-column-group-ref.html -fuzzy-if(d2d,0-1,0-13000) == border-separate-opacity-table-column.html border-separate-opacity-table-column-ref.html -fuzzy-if(d2d,0-1,0-37170) fuzzy-if(skiaContent,0-1,0-38000) == border-separate-opacity-table-row-group.html border-separate-opacity-table-row-group-ref.html -fuzzy-if(d2d,0-1,0-12390) fuzzy-if(skiaContent,0-1,0-13000) == border-separate-opacity-table-row.html border-separate-opacity-table-row-ref.html -fuzzy-if(d2d||skiaContent,0-1,0-95000) == border-separate-opacity-table.html border-separate-opacity-table-ref.html -!= scrollable-rowgroup-collapse-background.html scrollable-rowgroup-collapse-notref.html -!= scrollable-rowgroup-collapse-border.html scrollable-rowgroup-collapse-notref.html +fuzzy-if(d2d,1,1083) fuzzy-if(skiaContent,1,2200) == border-collapse-opacity-table-cell.html border-collapse-opacity-table-cell-ref.html +fails == border-collapse-opacity-table-column-group.html border-collapse-opacity-table-column-group-ref.html # bug 424274 +fails == border-collapse-opacity-table-column.html border-collapse-opacity-table-column-ref.html # bug 424274 +fuzzy-if(d2d,1,16359) fuzzy-if(skiaContent,1,17000) == border-collapse-opacity-table-row-group.html border-collapse-opacity-table-row-group-ref.html +fuzzy-if(d2d,1,11000) fuzzy-if(skiaContent,1,11000) == border-collapse-opacity-table-row.html border-collapse-opacity-table-row-ref.html +fuzzy-if(d2d||skiaContent,1,60000) == border-collapse-opacity-table.html border-collapse-opacity-table-ref.html +fuzzy-if(d2d,1,2478) fuzzy-if(skiaContent,1,2500) == border-separate-opacity-table-cell.html border-separate-opacity-table-cell-ref.html +fuzzy-if(d2d,1,38000) == border-separate-opacity-table-column-group.html border-separate-opacity-table-column-group-ref.html # bug 424274 +fuzzy-if(d2d,1,13000) == border-separate-opacity-table-column.html border-separate-opacity-table-column-ref.html # bug 424274 +fuzzy-if(d2d,1,37170) fuzzy-if(skiaContent,1,38000) == border-separate-opacity-table-row-group.html border-separate-opacity-table-row-group-ref.html +fuzzy-if(d2d,1,12390) fuzzy-if(skiaContent,1,13000) == border-separate-opacity-table-row.html border-separate-opacity-table-row-ref.html +fuzzy-if(d2d||skiaContent,1,95000) == border-separate-opacity-table.html border-separate-opacity-table-ref.html +!= scrollable-rowgroup-collapse-background.html scrollable-rowgroup-collapse-notref.html +!= scrollable-rowgroup-collapse-border.html scrollable-rowgroup-collapse-notref.html != scrollable-rowgroup-separate-background.html scrollable-rowgroup-separate-notref.html == scrollable-rowgroup-separate-border.html scrollable-rowgroup-separate-notref.html # scrolling rowgroups were removed in bug 28800 == empty-cells-default-1.html empty-cells-default-1-ref.html == empty-cells-default-2.html empty-cells-default-2-ref.html -fuzzy-if(OSX,0-1,0-113) fuzzy-if(winWidget,0-1,0-12) fuzzy-if(winWidget&&!layersGPUAccelerated,0-82,0-116) fuzzy-if(skiaContent,0-84,0-5500) fuzzy-if(Android,0-2,0-5957) == table-row-opacity-dynamic-1.html table-row-opacity-dynamic-1-ref.html +fuzzy-if(OSX,1,113) fuzzy-if(winWidget,1,12) fuzzy-if(Android,1,39) fuzzy-if(winWidget&&!layersGPUAccelerated,82,116) fuzzy-if(skiaContent,84,5500) == table-row-opacity-dynamic-1.html table-row-opacity-dynamic-1-ref.html == table-row-opacity-dynamic-2.html table-row-opacity-dynamic-2-ref.html - -== hidden-cells-1.html about:blank -== hidden-cells-2.html about:blank -== hidden-cells-3.html hidden-cells-3-ref.html - -== table-col-overlapping.html table-col-overlapping-ref.html
-== table-col-span-1.html table-col-span-1-ref.html diff --git a/layout/reftests/table-background/table-col-overlapping-ref.html b/layout/reftests/table-background/table-col-overlapping-ref.html deleted file mode 100644 index 06b6c3e06..000000000 --- a/layout/reftests/table-background/table-col-overlapping-ref.html +++ /dev/null @@ -1,28 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<style> - td { - width: 20px; - height: 20px; - background-color: green; - } - table { - border-collapse:separate; - border-spacing: 0px; - } -</style> -</head> -<body> -<table> - <tr> - <td></td> - <td style="background-color: blue"></td> - <tr> - <td></td> - <td></td> - </tr> -</table> -</body> - -</html> diff --git a/layout/reftests/table-background/table-col-overlapping.html b/layout/reftests/table-background/table-col-overlapping.html deleted file mode 100644 index c50f1654f..000000000 --- a/layout/reftests/table-background/table-col-overlapping.html +++ /dev/null @@ -1,28 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<style> - td { - width: 20px; - height: 20px; - } - table { - border-collapse:separate; - border-spacing: 0px; - } -</style> -</head> -<body> -<table> - <col style="background: green"></col> - <col style="background: blue"></col> - <tr> - <td></td> - <td rowspan=2></td> - <tr> - <td colspan=2></td> - </tr> -</table> -</body> - -</html> diff --git a/layout/reftests/table-background/table-col-span-1-ref.html b/layout/reftests/table-background/table-col-span-1-ref.html deleted file mode 100644 index 12a7bc45f..000000000 --- a/layout/reftests/table-background/table-col-span-1-ref.html +++ /dev/null @@ -1,15 +0,0 @@ -<!DOCTYPE html> -<html> -<body> - <table border> - <col style="background:purple"></col> - <col style="background:purple"></col> - <col style="background:blue"></col> - <tr> - <td>x</td> - <td>y</td> - <td>z</td> - </tr> - </table> -</body> -</html> diff --git a/layout/reftests/table-background/table-col-span-1.html b/layout/reftests/table-background/table-col-span-1.html deleted file mode 100644 index 7fd21ce06..000000000 --- a/layout/reftests/table-background/table-col-span-1.html +++ /dev/null @@ -1,15 +0,0 @@ -<!DOCTYPE html> -<html> -<body> - <table border> - <col span=2 style="background:purple"></col> - <col style="background:blue"></col> - <tr> - <td>x</td> - <td>y</td> - <td>z</td> - </tr> - </table> -</body> - -</html> diff --git a/layout/svg/SVGFEUnstyledLeafFrame.cpp b/layout/svg/SVGFEUnstyledLeafFrame.cpp index bc9258527..083c0f27d 100644 --- a/layout/svg/SVGFEUnstyledLeafFrame.cpp +++ b/layout/svg/SVGFEUnstyledLeafFrame.cpp @@ -25,6 +25,7 @@ public: NS_DECL_FRAMEARENA_HELPERS virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override {} virtual bool IsFrameOfType(uint32_t aFlags) const override diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index bfe7333ee..6ba267ee8 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -3161,6 +3161,7 @@ SVGTextFrame::Init(nsIContent* aContent, void SVGTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (NS_SUBTREE_DIRTY(this)) { diff --git a/layout/svg/SVGTextFrame.h b/layout/svg/SVGTextFrame.h index 508ed1724..9c672c6a5 100644 --- a/layout/svg/SVGTextFrame.h +++ b/layout/svg/SVGTextFrame.h @@ -224,6 +224,7 @@ public: } virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; /** diff --git a/layout/svg/nsSVGClipPathFrame.h b/layout/svg/nsSVGClipPathFrame.h index 046ebb169..42a8d16ff 100644 --- a/layout/svg/nsSVGClipPathFrame.h +++ b/layout/svg/nsSVGClipPathFrame.h @@ -37,6 +37,7 @@ public: // nsIFrame methods: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override {} // nsSVGClipPathFrame methods: diff --git a/layout/svg/nsSVGContainerFrame.cpp b/layout/svg/nsSVGContainerFrame.cpp index acb726f7a..750dcc9da 100644 --- a/layout/svg/nsSVGContainerFrame.cpp +++ b/layout/svg/nsSVGContainerFrame.cpp @@ -140,6 +140,7 @@ nsSVGDisplayContainerFrame::Init(nsIContent* aContent, void nsSVGDisplayContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // mContent could be a XUL element so check for an SVG element before casting @@ -148,7 +149,7 @@ nsSVGDisplayContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, return; } DisplayOutline(aBuilder, aLists); - return BuildDisplayListForNonBlockChildren(aBuilder, aLists); + return BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists); } void diff --git a/layout/svg/nsSVGContainerFrame.h b/layout/svg/nsSVGContainerFrame.h index 8a6cdd7ce..f4a01e155 100644 --- a/layout/svg/nsSVGContainerFrame.h +++ b/layout/svg/nsSVGContainerFrame.h @@ -83,6 +83,7 @@ public: } virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override {} virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override; @@ -132,6 +133,7 @@ public: nsIFrame* aPrevInFlow) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual bool IsSVGTransformed(Matrix *aOwnTransform = nullptr, diff --git a/layout/svg/nsSVGFilterFrame.h b/layout/svg/nsSVGFilterFrame.h index f2f321522..223c787f6 100644 --- a/layout/svg/nsSVGFilterFrame.h +++ b/layout/svg/nsSVGFilterFrame.h @@ -45,6 +45,7 @@ public: // nsIFrame methods: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override {} virtual nsresult AttributeChanged(int32_t aNameSpaceID, diff --git a/layout/svg/nsSVGForeignObjectFrame.cpp b/layout/svg/nsSVGForeignObjectFrame.cpp index f8584a4f1..afa5912d2 100644 --- a/layout/svg/nsSVGForeignObjectFrame.cpp +++ b/layout/svg/nsSVGForeignObjectFrame.cpp @@ -163,13 +163,14 @@ nsSVGForeignObjectFrame::Reflow(nsPresContext* aPresContext, void nsSVGForeignObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!static_cast<const nsSVGElement*>(mContent)->HasValidDimensions()) { return; } DisplayOutline(aBuilder, aLists); - BuildDisplayListForNonBlockChildren(aBuilder, aLists); + BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists); } bool diff --git a/layout/svg/nsSVGForeignObjectFrame.h b/layout/svg/nsSVGForeignObjectFrame.h index 4bb94bdab..57df6d5b5 100644 --- a/layout/svg/nsSVGForeignObjectFrame.h +++ b/layout/svg/nsSVGForeignObjectFrame.h @@ -47,6 +47,7 @@ public: nsReflowStatus& aStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; /** diff --git a/layout/svg/nsSVGMarkerFrame.h b/layout/svg/nsSVGMarkerFrame.h index 187aed140..22ac01709 100644 --- a/layout/svg/nsSVGMarkerFrame.h +++ b/layout/svg/nsSVGMarkerFrame.h @@ -52,6 +52,7 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override {} virtual nsresult AttributeChanged(int32_t aNameSpaceID, diff --git a/layout/svg/nsSVGMaskFrame.h b/layout/svg/nsSVGMaskFrame.h index 2a9486fa5..380306a48 100644 --- a/layout/svg/nsSVGMaskFrame.h +++ b/layout/svg/nsSVGMaskFrame.h @@ -73,6 +73,7 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override {} /** diff --git a/layout/svg/nsSVGOuterSVGFrame.cpp b/layout/svg/nsSVGOuterSVGFrame.cpp index 7efdec5e5..b1ee54eb9 100644 --- a/layout/svg/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/nsSVGOuterSVGFrame.cpp @@ -731,6 +731,7 @@ nsSVGOuterSVGFrame::AttributeChanged(int32_t aNameSpaceID, void nsSVGOuterSVGFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (GetStateBits() & NS_FRAME_IS_NONDISPLAY) { @@ -754,7 +755,7 @@ nsSVGOuterSVGFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsDisplayList *contentList = aLists.Content(); nsDisplayListSet set(contentList, contentList, contentList, contentList, contentList, contentList); - BuildDisplayListForNonBlockChildren(aBuilder, set); + BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, set); } else if (IsVisibleForPainting(aBuilder) || !aBuilder->IsForPainting()) { aLists.Content()->AppendNewToTop( new (aBuilder) nsDisplayOuterSVG(aBuilder, this)); diff --git a/layout/svg/nsSVGOuterSVGFrame.h b/layout/svg/nsSVGOuterSVGFrame.h index ee59b7d1c..6d29234ac 100644 --- a/layout/svg/nsSVGOuterSVGFrame.h +++ b/layout/svg/nsSVGOuterSVGFrame.h @@ -66,6 +66,7 @@ public: virtual void UnionChildOverflow(nsOverflowAreas& aOverflowAreas) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Init(nsIContent* aContent, diff --git a/layout/svg/nsSVGPaintServerFrame.h b/layout/svg/nsSVGPaintServerFrame.h index ff2c6f8b4..6b568f872 100644 --- a/layout/svg/nsSVGPaintServerFrame.h +++ b/layout/svg/nsSVGPaintServerFrame.h @@ -58,6 +58,7 @@ public: // nsIFrame methods: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override {} virtual bool IsFrameOfType(uint32_t aFlags) const override diff --git a/layout/svg/nsSVGPathGeometryFrame.cpp b/layout/svg/nsSVGPathGeometryFrame.cpp index 50eec2b92..32cd0e496 100644 --- a/layout/svg/nsSVGPathGeometryFrame.cpp +++ b/layout/svg/nsSVGPathGeometryFrame.cpp @@ -259,6 +259,7 @@ nsSVGPathGeometryFrame::IsSVGTransformed(gfx::Matrix *aOwnTransform, void nsSVGPathGeometryFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!static_cast<const nsSVGElement*>(mContent)->HasValidDimensions() || diff --git a/layout/svg/nsSVGPathGeometryFrame.h b/layout/svg/nsSVGPathGeometryFrame.h index d2d63f043..6b7c75d97 100644 --- a/layout/svg/nsSVGPathGeometryFrame.h +++ b/layout/svg/nsSVGPathGeometryFrame.h @@ -88,6 +88,7 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; // nsSVGPathGeometryFrame methods diff --git a/layout/svg/nsSVGStopFrame.cpp b/layout/svg/nsSVGStopFrame.cpp index 28875ad25..1b75fa102 100644 --- a/layout/svg/nsSVGStopFrame.cpp +++ b/layout/svg/nsSVGStopFrame.cpp @@ -36,6 +36,7 @@ public: #endif void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override {} virtual nsresult AttributeChanged(int32_t aNameSpaceID, diff --git a/layout/svg/nsSVGSwitchFrame.cpp b/layout/svg/nsSVGSwitchFrame.cpp index 1eef37eb0..26e77071b 100644 --- a/layout/svg/nsSVGSwitchFrame.cpp +++ b/layout/svg/nsSVGSwitchFrame.cpp @@ -44,6 +44,7 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; // nsISVGChildFrame interface: @@ -92,11 +93,12 @@ nsSVGSwitchFrame::GetType() const void nsSVGSwitchFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { nsIFrame* kid = GetActiveChildFrame(); if (kid) { - BuildDisplayListForChild(aBuilder, kid, aLists); + BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); } } diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 9c715d999..8b811df1e 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -450,6 +450,7 @@ nsTableCellFrame::ShouldPaintBackground(nsDisplayListBuilder* aBuilder) void nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DO_GLOBAL_REFLOW_COUNT_DSP("nsTableCellFrame"); @@ -461,14 +462,14 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, this)); } - nsRect bgRect = GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(this); - // display background if we need to. if (aBuilder->IsForEventDelivery() || !StyleBackground()->IsTransparent() || StyleDisplay()->mAppearance) { - nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, this, bgRect, aLists.BorderBackground()); + nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, + this, + GetRectRelativeToSelf(), + aLists.BorderBackground()); } // display inset box-shadows if we need to. @@ -487,49 +488,16 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, "TableCellSelection", nsDisplayItem::TYPE_TABLE_CELL_SELECTION)); } - - // This can be null if display list building initiated in the middle - // of the table, which can happen with background-clip:text and - // -moz-element. - nsDisplayTableBackgroundSet* backgrounds = - aBuilder->GetTableBackgroundSet(); - if (backgrounds) { - // Compute bgRect relative to reference frame, but using the - // normal (without position:relative offsets) positions for the - // cell, row and row group. - bgRect = GetRectRelativeToSelf() + GetNormalPosition(); - - nsTableRowFrame* row = GetTableRowFrame(); - bgRect += row->GetNormalPosition(); - - nsTableRowGroupFrame* rowGroup = row->GetTableRowGroupFrame(); - bgRect += rowGroup->GetNormalPosition(); - - bgRect += backgrounds->TableToReferenceFrame(); - - // Create backgrounds items as needed for the column and column - // group that this cell occupies. - nsTableColFrame* col = backgrounds->GetColForIndex(ColIndex()); - nsTableColGroupFrame* colGroup = col->GetTableColGroupFrame(); - - Maybe<nsDisplayListBuilder::AutoBuildingDisplayList> buildingForColGroup; - nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, colGroup, bgRect, backgrounds->ColGroupBackgrounds(), false, - nullptr, colGroup->GetRect() + backgrounds->TableToReferenceFrame(), - this, &buildingForColGroup); - - Maybe<nsDisplayListBuilder::AutoBuildingDisplayList> buildingForCol; - nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, col, bgRect, backgrounds->ColBackgrounds(), false, nullptr, - col->GetRect() + colGroup->GetPosition() + - backgrounds->TableToReferenceFrame(), - this, &buildingForCol); - } } // the 'empty-cells' property has no effect on 'outline' DisplayOutline(aBuilder, aLists); + // Push a null 'current table item' so that descendant tables can't + // accidentally mess with our table + nsAutoPushCurrentTableItem pushTableItem; + pushTableItem.Push(aBuilder, nullptr); + nsIFrame* kid = mFrames.FirstChild(); NS_ASSERTION(kid && !kid->GetNextSibling(), "Table cells should have just one child"); // The child's background will go in our BorderBackground() list. @@ -538,7 +506,7 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // because that/ would put the child's background in the Content() list // which isn't right (e.g., would end up on top of our child floats for // event handling). - BuildDisplayListForChild(aBuilder, kid, aLists); + BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); } nsIFrame::LogicalSides diff --git a/layout/tables/nsTableCellFrame.h b/layout/tables/nsTableCellFrame.h index a822e309d..f626a45b0 100644 --- a/layout/tables/nsTableCellFrame.h +++ b/layout/tables/nsTableCellFrame.h @@ -104,6 +104,7 @@ public: virtual bool NeedsToObserve(const ReflowInput& aReflowInput) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsresult ProcessBorders(nsTableFrame* aFrame, diff --git a/layout/tables/nsTableColFrame.cpp b/layout/tables/nsTableColFrame.cpp index 6723f4701..54b03522b 100644 --- a/layout/tables/nsTableColFrame.cpp +++ b/layout/tables/nsTableColFrame.cpp @@ -110,15 +110,10 @@ nsTableColFrame::Reflow(nsPresContext* aPresContext, void nsTableColFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - // Per https://drafts.csswg.org/css-tables-3/#global-style-overrides: - // "All css properties of table-column and table-column-group boxes are - // ignored, except when explicitly specified by this specification." - // CSS outlines and box-shadows fall into this category, so we skip them - // on these boxes. - - MOZ_ASSERT_UNREACHABLE("Cols don't paint themselves"); + nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists); } int32_t nsTableColFrame::GetSpan() diff --git a/layout/tables/nsTableColFrame.h b/layout/tables/nsTableColFrame.h index ed6a843b6..fb989061f 100644 --- a/layout/tables/nsTableColFrame.h +++ b/layout/tables/nsTableColFrame.h @@ -60,6 +60,7 @@ public: nsReflowStatus& aStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; /** diff --git a/layout/tables/nsTableColGroupFrame.cpp b/layout/tables/nsTableColGroupFrame.cpp index be5b71bb2..6ee7f0b24 100644 --- a/layout/tables/nsTableColGroupFrame.cpp +++ b/layout/tables/nsTableColGroupFrame.cpp @@ -385,15 +385,10 @@ nsTableColGroupFrame::Reflow(nsPresContext* aPresContext, void nsTableColGroupFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - // Per https://drafts.csswg.org/css-tables-3/#global-style-overrides: - // "All css properties of table-column and table-column-group boxes are - // ignored, except when explicitly specified by this specification." - // CSS outlines and box-shadows fall into this category, so we skip them - // on these boxes. - - MOZ_ASSERT_UNREACHABLE("Colgroups don't paint themselves"); + nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists); } nsTableColFrame * nsTableColGroupFrame::GetFirstColumn() diff --git a/layout/tables/nsTableColGroupFrame.h b/layout/tables/nsTableColGroupFrame.h index 88ed67c2a..b3dfb94e7 100644 --- a/layout/tables/nsTableColGroupFrame.h +++ b/layout/tables/nsTableColGroupFrame.h @@ -44,6 +44,7 @@ public: } virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; /** A colgroup can be caused by three things: diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 32fe38b05..4257c9c57 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1161,127 +1161,242 @@ nsDisplayTableBorderCollapse::Paint(nsDisplayListBuilder* aBuilder, static_cast<nsTableFrame*>(mFrame)->PaintBCBorders(*drawTarget, mVisibleRect - pt); } -static inline bool FrameHasBorder(nsIFrame* f) { - if (!f->StyleVisibility()->IsVisible()) { - return false; +/* static */ void +nsTableFrame::GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) +{ + // This is similar to what nsContainerFrame::BuildDisplayListForNonBlockChildren + // does, except that we allow the children's background and borders to go + // in our BorderBackground list. This doesn't really affect background + // painting --- the children won't actually draw their own backgrounds + // because the nsTableFrame already drew them, unless a child has its own + // stacking context, in which case the child won't use its passed-in + // BorderBackground list anyway. It does affect cell borders though; this + // lets us get cell borders into the nsTableFrame's BorderBackground list. + for (nsIFrame* kid : aFrame->GetChildList(kColGroupList)) { + aFrame->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); } - if (f->StyleBorder()->HasBorder()) { - return true; + for (nsIFrame* kid : aFrame->PrincipalChildList()) { + aFrame->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); } +} - return false; +static void +PaintRowBackground(nsTableRowFrame* aRow, + nsIFrame* aFrame, + nsDisplayListBuilder* aBuilder, + const nsDisplayListSet& aLists, + const nsRect& aDirtyRect, + const nsPoint& aOffset = nsPoint()) +{ + // Compute background rect by iterating over all cell frames. + for (nsTableCellFrame* cell = aRow->GetFirstCell(); cell; cell = cell->GetNextCell()) { + if (!cell->ShouldPaintBackground(aBuilder)) { + continue; + } + + auto cellRect = cell->GetRectRelativeToSelf() + cell->GetNormalPosition() + aOffset; + if (!aDirtyRect.Intersects(cellRect)) { + continue; + } + nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, cellRect, + aLists.BorderBackground(), + true, nullptr, + aFrame->GetRectRelativeToSelf(), + cell); + } } -void nsTableFrame::CalcHasBCBorders() { - if (!IsBorderCollapse()) { - SetHasBCBorders(false); - return; +static void +PaintRowGroupBackground(nsTableRowGroupFrame* aRowGroup, + nsIFrame* aFrame, + nsDisplayListBuilder* aBuilder, + const nsDisplayListSet& aLists, + const nsRect& aDirtyRect) +{ + for (nsTableRowFrame* row = aRowGroup->GetFirstRow(); row; row = row->GetNextRow()) { + if (!aDirtyRect.Intersects(nsRect(row->GetNormalPosition(), row->GetSize()))) { + continue; + } + PaintRowBackground(row, aFrame, aBuilder, aLists, aDirtyRect, row->GetNormalPosition()); } +} - if (FrameHasBorder(this)) { - SetHasBCBorders(true); - return; +static void +PaintRowGroupBackgroundByColIdx(nsTableRowGroupFrame* aRowGroup, + nsIFrame* aFrame, + nsDisplayListBuilder* aBuilder, + const nsDisplayListSet& aLists, + const nsRect& aDirtyRect, + const nsTArray<uint32_t>& aColIdx, + const nsPoint& aOffset) +{ + MOZ_DIAGNOSTIC_ASSERT(!aColIdx.IsEmpty(), + "Must be painting backgrounds for something"); + for (nsTableRowFrame* row = aRowGroup->GetFirstRow(); row; row = row->GetNextRow()) { + auto rowPos = row->GetNormalPosition() + aOffset; + if (!aDirtyRect.Intersects(nsRect(rowPos, row->GetSize()))) { + continue; + } + for (nsTableCellFrame* cell = row->GetFirstCell(); cell; cell = cell->GetNextCell()) { + + uint32_t curColIdx = cell->ColIndex(); + if (!aColIdx.Contains(curColIdx)) { + if (curColIdx > aColIdx.LastElement()) { + // We can just stop looking at this row. + break; + } + continue; + } + + if (!cell->ShouldPaintBackground(aBuilder)) { + continue; + } + + auto cellPos = cell->GetNormalPosition() + rowPos; + auto cellRect = nsRect(cellPos, cell->GetSize()); + if (!aDirtyRect.Intersects(cellRect)) { + continue; + } + nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, cellRect, + aLists.BorderBackground(), + true, nullptr, + aFrame->GetRectRelativeToSelf(), + cell); + } } +} - // Check col and col group has borders. - for (nsIFrame* f : this->GetChildList(kColGroupList)) { - if (FrameHasBorder(f)) { - SetHasBCBorders(true); - return; +/* static */ void +nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder, + nsFrame* aFrame, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists, + DisplayGenericTablePartTraversal aTraversal) +{ + bool isVisible = aFrame->IsVisibleForPainting(aBuilder); + bool isTable = (aFrame->GetType() == nsGkAtoms::tableFrame); + + if (isVisible || !isTable) { + nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem(); + // currentItem may be null, when none of the table parts have a + // background or border + if (currentItem) { + currentItem->UpdateForFrameBackground(aFrame); + } + } + + if (isVisible) { + // XXX: should box-shadow for rows/rowgroups/columns/colgroups get painted + // just because we're visible? Or should it depend on the cell visibility + // when we're not the whole table? + + // Paint the outset box-shadows for the table frames + if (aFrame->StyleEffects()->mBoxShadow) { + aLists.BorderBackground()->AppendNewToTop( + new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, aFrame)); + } + } + + // Background visibility for rows, rowgroups, columns, colgroups depends on + // the visibility of the _cell_, not of the row/col(group). + // See spec at https://drafts.csswg.org/css-tables-3/#drawing-cell-backgrounds + if (aFrame->GetType() == nsGkAtoms::tableRowGroupFrame) { + nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame); + PaintRowGroupBackground(rowGroup, aFrame, aBuilder, aLists, aDirtyRect); + } else if (aFrame->GetType() == nsGkAtoms::tableRowFrame) { + nsTableRowFrame* row = static_cast<nsTableRowFrame*>(aFrame); + PaintRowBackground(row, aFrame, aBuilder, aLists, aDirtyRect); + } else if (aFrame->GetType() == nsGkAtoms::tableColGroupFrame) { + // Compute background rect by iterating all cell frame. + nsTableColGroupFrame* colGroup = static_cast<nsTableColGroupFrame*>(aFrame); + // Collecting column index. + AutoTArray<uint32_t, 1> colIdx; + for (nsTableColFrame* col = colGroup->GetFirstColumn(); col; col = col->GetNextCol()) { + MOZ_ASSERT(colIdx.IsEmpty() || + static_cast<uint32_t>(col->GetColIndex()) > colIdx.LastElement()); + colIdx.AppendElement(col->GetColIndex()); + } + + if (!colIdx.IsEmpty()) { + // We have some actual cells that live inside this rowgroup. + nsTableFrame* table = colGroup->GetTableFrame(); + RowGroupArray rowGroups; + table->OrderRowGroups(rowGroups); + for (nsTableRowGroupFrame* rowGroup : rowGroups) { + auto offset = rowGroup->GetNormalPosition() - colGroup->GetNormalPosition(); + if (!aDirtyRect.Intersects(nsRect(offset, rowGroup->GetSize()))) { + continue; + } + PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, aDirtyRect, colIdx, offset); + } } + } else if (aFrame->GetType() == nsGkAtoms::tableColFrame) { + // Compute background rect by iterating all cell frame. + nsTableColFrame* col = static_cast<nsTableColFrame*>(aFrame); + AutoTArray<uint32_t, 1> colIdx; + colIdx.AppendElement(col->GetColIndex()); - nsTableColGroupFrame* colGroup = static_cast<nsTableColGroupFrame*>(f); - for (nsTableColFrame* col = colGroup->GetFirstColumn(); col; - col = col->GetNextCol()) { - if (FrameHasBorder(col)) { - SetHasBCBorders(true); - return; + nsTableFrame* table = col->GetTableFrame(); + RowGroupArray rowGroups; + table->OrderRowGroups(rowGroups); + for (nsTableRowGroupFrame* rowGroup : rowGroups) { + auto offset = rowGroup->GetNormalPosition() - + col->GetNormalPosition() - + col->GetTableColGroupFrame()->GetNormalPosition(); + if (!aDirtyRect.Intersects(nsRect(offset, rowGroup->GetSize()))) { + continue; } + PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, aDirtyRect, colIdx, offset); } + } else if (isVisible) { + nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, + aFrame->GetRectRelativeToSelf(), + aLists.BorderBackground()); } - // check row group, row and cell has borders. - RowGroupArray rowGroups; - OrderRowGroups(rowGroups); - for (nsTableRowGroupFrame* rowGroup : rowGroups) { - if (FrameHasBorder(rowGroup)) { - SetHasBCBorders(true); - return; + if (isVisible) { + // XXX: should box-shadow for rows/rowgroups/columns/colgroups get painted + // just because we're visible? Or should it depend on the cell visibility + // when we're not the whole table? + + // Paint the inset box-shadows for the table frames + if (aFrame->StyleEffects()->mBoxShadow) { + aLists.BorderBackground()->AppendNewToTop( + new (aBuilder) nsDisplayBoxShadowInner(aBuilder, aFrame)); } + } - for (nsTableRowFrame* row = rowGroup->GetFirstRow(); row; - row = row->GetNextRow()) { - if (FrameHasBorder(row)) { - SetHasBCBorders(true); - return; - } + aTraversal(aBuilder, aFrame, aDirtyRect, aLists); - for (nsTableCellFrame* cell = row->GetFirstCell(); cell; - cell = cell->GetNextCell()) { - if (FrameHasBorder(cell)) { - SetHasBCBorders(true); - return; - } + if (isVisible) { + if (isTable) { + nsTableFrame* table = static_cast<nsTableFrame*>(aFrame); + // In the collapsed border model, overlay all collapsed borders. + if (table->IsBorderCollapse()) { + aLists.BorderBackground()->AppendNewToTop( + new (aBuilder) nsDisplayTableBorderCollapse(aBuilder, table)); + } else { + aLists.BorderBackground()->AppendNewToTop( + new (aBuilder) nsDisplayBorder(aBuilder, table)); } } } - SetHasBCBorders(false); + aFrame->DisplayOutline(aBuilder, aLists); } // table paint code is concerned primarily with borders and bg color // SEC: TODO: adjust the rect for captions void nsTableFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DO_GLOBAL_REFLOW_COUNT_DSP_COLOR("nsTableFrame", NS_RGB(255,128,255)); - DisplayBorderBackgroundOutline(aBuilder, aLists); - - nsDisplayTableBackgroundSet tableBGs(aBuilder, this); - nsDisplayListCollection lists(aBuilder); - -// This is similar to what - // nsContainerFrame::BuildDisplayListForNonBlockChildren does, except that we - // allow the children's background and borders to go in our BorderBackground - // list. This doesn't really affect background painting --- the children won't - // actually draw their own backgrounds because the nsTableFrame already drew - // them, unless a child has its own stacking context, in which case the child - // won't use its passed-in BorderBackground list anyway. It does affect cell - // borders though; this lets us get cell borders into the nsTableFrame's - // BorderBackground list. - for (nsIFrame* colGroup : FirstContinuation()->GetChildList(kColGroupList)) { - for (nsIFrame* col : colGroup->PrincipalChildList()) { - tableBGs.AddColumn((nsTableColFrame*)col); - } - } - - for (nsIFrame* kid : PrincipalChildList()) { - BuildDisplayListForChild(aBuilder, kid, lists); - } - - tableBGs.MoveTo(aLists); - lists.MoveTo(aLists); - - if (IsVisibleForPainting(aBuilder)) { - // In the collapsed border model, overlay all collapsed borders. - if (IsBorderCollapse()) { - if (HasBCBorders()) { - aLists.BorderBackground()->AppendNewToTop( - new (aBuilder) nsDisplayTableBorderCollapse - (aBuilder, this)); - } - } else { - const nsStyleBorder* borderStyle = StyleBorder(); - if (borderStyle->HasBorder()) { - aLists.BorderBackground()->AppendNewToTop( - new (aBuilder) nsDisplayBorder - (aBuilder, this)); - } - } - } + DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists); } nsMargin @@ -3986,7 +4101,6 @@ nsTableFrame::AddBCDamageArea(const TableArea& aValue) #endif SetNeedToCalcBCBorders(true); - SetNeedToCalcHasBCBorders(true); // Get the property BCPropertyData* value = GetOrCreateBCProperty(); if (value) { @@ -4027,7 +4141,6 @@ nsTableFrame::SetFullBCDamageArea() NS_ASSERTION(IsBorderCollapse(), "invalid SetFullBCDamageArea call"); SetNeedToCalcBCBorders(true); - SetNeedToCalcHasBCBorders(true); BCPropertyData* value = GetOrCreateBCProperty(); if (value) { diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index 7fcdcb9d8..a6b786402 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -72,59 +72,36 @@ private: bool mDrawsBackground; }; -class nsDisplayTableBackgroundSet { - public: - nsDisplayList* ColGroupBackgrounds() { return &mColGroupBackgrounds; } - - nsDisplayList* ColBackgrounds() { return &mColBackgrounds; } - - nsDisplayTableBackgroundSet(nsDisplayListBuilder* aBuilder, nsIFrame* aTable) - : mBuilder(aBuilder) { - mPrevTableBackgroundSet = mBuilder->SetTableBackgroundSet(this); - mozilla::DebugOnly<const nsIFrame*> reference = - mBuilder->FindReferenceFrameFor(aTable, &mToReferenceFrame); - MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(reference, aTable)); - mDirtyRect = mBuilder->GetDirtyRect(); - } +class nsAutoPushCurrentTableItem +{ +public: + nsAutoPushCurrentTableItem() : mBuilder(nullptr) {} - ~nsDisplayTableBackgroundSet() { - mozilla::DebugOnly<nsDisplayTableBackgroundSet*> result = - mBuilder->SetTableBackgroundSet(mPrevTableBackgroundSet); - MOZ_ASSERT(result == this); + void Push(nsDisplayListBuilder* aBuilder, nsDisplayTableItem* aPushItem) + { + mBuilder = aBuilder; + mOldCurrentItem = aBuilder->GetCurrentTableItem(); + aBuilder->SetCurrentTableItem(aPushItem); +#ifdef DEBUG + mPushedItem = aPushItem; +#endif } - - /** - * Move all display items in our lists to top of the corresponding lists in - * the destination. - */ - void MoveTo(const nsDisplayListSet& aDestination) { - aDestination.BorderBackground()->AppendToTop(ColGroupBackgrounds()); - aDestination.BorderBackground()->AppendToTop(ColBackgrounds()); + ~nsAutoPushCurrentTableItem() { + if (!mBuilder) + return; +#ifdef DEBUG + NS_ASSERTION(mBuilder->GetCurrentTableItem() == mPushedItem, + "Someone messed with the current table item behind our back!"); +#endif + mBuilder->SetCurrentTableItem(mOldCurrentItem); } - void AddColumn(nsTableColFrame* aFrame) { mColumns.AppendElement(aFrame); } - - nsTableColFrame* GetColForIndex(int32_t aIndex) { return mColumns[aIndex]; } - - const nsPoint& TableToReferenceFrame() { return mToReferenceFrame; } - - const nsRect& GetDirtyRect() { return mDirtyRect; } - - private: - // This class is only used on stack, so we don't have to worry about leaking - // it. Don't let us be heap-allocated! - void* operator new(size_t sz) CPP_THROW_NEW; - - protected: +private: nsDisplayListBuilder* mBuilder; - nsDisplayTableBackgroundSet* mPrevTableBackgroundSet; - - nsDisplayList mColGroupBackgrounds; - nsDisplayList mColBackgrounds; - - nsTArray<nsTableColFrame*> mColumns; - nsPoint mToReferenceFrame; - nsRect mDirtyRect; + nsDisplayTableItem* mOldCurrentItem; +#ifdef DEBUG + nsDisplayTableItem* mPushedItem; +#endif }; /* ============================================================================ */ @@ -252,6 +229,29 @@ public: nsIFrame* aSourceFrame, bool* aDidPassThrough); + typedef void (* DisplayGenericTablePartTraversal) + (nsDisplayListBuilder* aBuilder, nsFrame* aFrame, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists); + static void GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists); + + /** + * Helper method to handle display common to table frames, rowgroup frames + * and row frames. It creates a background display item for handling events + * if necessary, an outline display item if necessary, and displays + * all the the frame's children. + * @param aDisplayItem the display item created for this part, or null + * if this part's border/background painting is delegated to an ancestor + * @param aTraversal a function that gets called to traverse the table + * part's child frames and add their display list items to a + * display list set. + */ + static void DisplayGenericTablePart(nsDisplayListBuilder* aBuilder, + nsFrame* aFrame, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists, + DisplayGenericTablePartTraversal aTraversal = GenericTraversal); + // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame) // of type aChildType. static nsIFrame* GetFrameAtOrBefore(nsIFrame* aParentFrame, @@ -268,6 +268,7 @@ public: virtual void GetChildLists(nsTArray<ChildList>* aLists) const override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; /** Get the outer half (i.e., the part outside the height and width of @@ -760,13 +761,6 @@ public: bool NeedToCollapse() const; void SetNeedToCollapse(bool aValue); - bool NeedToCalcHasBCBorders() const; - void SetNeedToCalcHasBCBorders(bool aValue); - - void CalcHasBCBorders(); - bool HasBCBorders(); - void SetHasBCBorders(bool aValue); - /** The GeometryDirty bit is similar to the NS_FRAME_IS_DIRTY frame * state bit, which implies that all descendants are dirty. The * GeometryDirty still implies that all the parts of the table are @@ -876,8 +870,6 @@ protected: uint32_t mIStartContBCBorder:8; uint32_t mNeedToCollapse:1; // rows, cols that have visibility:collapse need to be collapsed uint32_t mResizedColumns:1; // have we resized columns since last reflow? - uint32_t mNeedToCalcHasBCBorders:1; - uint32_t mHasBCBorders:1; } mBits; nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells @@ -973,30 +965,6 @@ inline void nsTableFrame::SetNeedToCalcBCBorders(bool aValue) mBits.mNeedToCalcBCBorders = (unsigned)aValue; } -inline bool nsTableFrame::NeedToCalcHasBCBorders() const -{ - return (bool)mBits.mNeedToCalcHasBCBorders; -} - -inline void nsTableFrame::SetNeedToCalcHasBCBorders(bool aValue) -{ - mBits.mNeedToCalcHasBCBorders = (unsigned)aValue; -} - -inline bool nsTableFrame::HasBCBorders() -{ - if (NeedToCalcHasBCBorders()) { - CalcHasBCBorders(); - SetNeedToCalcHasBCBorders(false); - } - return (bool)mBits.mHasBCBorders; -} - -inline void nsTableFrame::SetHasBCBorders(bool aValue) -{ - mBits.mHasBCBorders = (unsigned)aValue; -} - inline nscoord nsTableFrame::GetContinuousIStartBCBorderWidth() const { diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index 18f11f876..02b85a141 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -549,66 +549,12 @@ nsTableRowFrame::CalcBSize(const ReflowInput& aReflowInput) return GetInitialBSize(); } -void nsTableRowFrame::PaintCellBackgroundsForFrame( - nsIFrame* aFrame, nsDisplayListBuilder* aBuilder, - const nsDisplayListSet& aLists, const nsPoint& aOffset) { - // Compute background rect by iterating all cell frame. - const nsPoint toReferenceFrame = aBuilder->ToReferenceFrame(aFrame); - for (nsTableCellFrame* cell = GetFirstCell(); cell; - cell = cell->GetNextCell()) { - if (!cell->ShouldPaintBackground(aBuilder)) { - continue; - } - - auto cellRect = - cell->GetRectRelativeToSelf() + cell->GetNormalPosition() + aOffset; - if (!aBuilder->GetDirtyRect().Intersects(cellRect)) { - continue; - } - cellRect += toReferenceFrame; - nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, aFrame, cellRect, aLists.BorderBackground(), true, nullptr, - aFrame->GetRectRelativeToSelf() + toReferenceFrame, cell); - } -} - void nsTableRowFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - if (IsVisibleForPainting(aBuilder)) { - // XXXbz should box-shadow for rows/rowgroups/columns/colgroups get painted - // just because we're visible? Or should it depend on the cell visibility - // when we're not the whole table? - - // Paint the outset box-shadows for the table frames - if (StyleEffects()->mBoxShadow) { - aLists.BorderBackground()->AppendNewToTop( - new (aBuilder) nsDisplayBoxShadowOuter - (aBuilder, this)); - } - } - - PaintCellBackgroundsForFrame(this, aBuilder, aLists); - - if (IsVisibleForPainting(aBuilder)) { - // XXXbz should box-shadow for rows/rowgroups/columns/colgroups get painted - // just because we're visible? Or should it depend on the cell visibility - // when we're not the whole table? - - // Paint the inset box-shadows for the table frames - if (StyleEffects()->mBoxShadow) { - aLists.BorderBackground()->AppendNewToTop( - new (aBuilder) nsDisplayBoxShadowInner - (aBuilder, this)); - } - } - - DisplayOutline(aBuilder, aLists); - - for (nsIFrame* kid : PrincipalChildList()) { - BuildDisplayListForChild(aBuilder, kid, aLists); - } + nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists); } nsIFrame::LogicalSides diff --git a/layout/tables/nsTableRowFrame.h b/layout/tables/nsTableRowFrame.h index 4b6dd2628..c53c81ff1 100644 --- a/layout/tables/nsTableRowFrame.h +++ b/layout/tables/nsTableRowFrame.h @@ -79,13 +79,9 @@ public: virtual nsMargin GetUsedPadding() const override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; - void PaintCellBackgroundsForFrame(nsIFrame* aFrame, - nsDisplayListBuilder* aBuilder, - const nsDisplayListSet& aLists, - const nsPoint& aOffset = nsPoint()); - // Implemented in nsTableCellFrame.h, because it needs to know about the // nsTableCellFrame class, but we can't include nsTableCellFrame.h here. inline nsTableCellFrame* GetFirstCell() const; diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 56ca394de..37f577f5c 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -156,7 +156,7 @@ nsTableRowGroupFrame::InitRepeatedFrame(nsTableRowGroupFrame* aHeaderFooterFrame // Handle the child-traversal part of DisplayGenericTablePart static void DisplayRows(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, - const nsDisplayListSet& aLists) + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { nscoord overflowAbove; nsTableRowGroupFrame* f = static_cast<nsTableRowGroupFrame*>(aFrame); @@ -168,16 +168,16 @@ DisplayRows(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, // the rows in |f|, but that's exactly what we're trying to avoid, so we // approximate it by checking it for |f|: if it's true for any row // in |f| then it's true for |f| itself. - nsIFrame* kid = aBuilder->ShouldDescendIntoFrame(f, true) ? - nullptr : f->GetFirstRowContaining(aBuilder->GetVisibleRect().y, &overflowAbove); + nsIFrame* kid = aBuilder->ShouldDescendIntoFrame(f) ? + nullptr : f->GetFirstRowContaining(aDirtyRect.y, &overflowAbove); if (kid) { // If we have a cursor, use it while (kid) { - if (kid->GetRect().y - overflowAbove >= aBuilder->GetDirtyRect().YMost()) { + if (kid->GetRect().y - overflowAbove >= aDirtyRect.YMost()) { break; } - f->BuildDisplayListForChild(aBuilder, kid, aLists); + f->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); kid = kid->GetNextSibling(); } return; @@ -187,7 +187,7 @@ DisplayRows(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, nsTableRowGroupFrame::FrameCursorData* cursor = f->SetupRowCursor(); kid = f->PrincipalChildList().FirstChild(); while (kid) { - f->BuildDisplayListForChild(aBuilder, kid, aLists); + f->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); if (cursor) { if (!cursor->AppendFrame(kid)) { @@ -205,45 +205,11 @@ DisplayRows(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, void nsTableRowGroupFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - if (IsVisibleForPainting(aBuilder)) { - // XXXbz should box-shadow for rows/rowgroups/columns/colgroups get painted - // just because we're visible? Or should it depend on the cell visibility - // when we're not the whole table? - - // Paint the outset box-shadows for the table frames - if (StyleEffects()->mBoxShadow) { - aLists.BorderBackground()->AppendNewToTop( - new (aBuilder) nsDisplayBoxShadowOuter - (aBuilder, this)); - } - } - - for (nsTableRowFrame* row = GetFirstRow(); row; row = row->GetNextRow()) { - if (!aBuilder->GetDirtyRect().Intersects(row->GetVisualOverflowRect() + row->GetNormalPosition())) { - continue; - } - row->PaintCellBackgroundsForFrame(this, aBuilder, aLists, - row->GetNormalPosition()); - } - - if (IsVisibleForPainting(aBuilder)) { - // XXXbz should box-shadow for rows/rowgroups/columns/colgroups get painted - // just because we're visible? Or should it depend on the cell visibility - // when we're not the whole table? - - // Paint the inset box-shadows for the table frames - if (StyleEffects()->mBoxShadow) { - aLists.BorderBackground()->AppendNewToTop( - new (aBuilder) nsDisplayBoxShadowInner - (aBuilder, this)); - } - } - - DisplayOutline(aBuilder, aLists); - - DisplayRows(aBuilder, this, aLists); + nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, + aLists, DisplayRows); } nsIFrame::LogicalSides diff --git a/layout/tables/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h index eb9f6205e..721d91046 100644 --- a/layout/tables/nsTableRowGroupFrame.h +++ b/layout/tables/nsTableRowGroupFrame.h @@ -75,6 +75,7 @@ public: virtual nsMargin GetUsedPadding() const override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; /** calls Reflow for all of its child rows. diff --git a/layout/tables/nsTableWrapperFrame.cpp b/layout/tables/nsTableWrapperFrame.cpp index 476024e96..da71375d5 100644 --- a/layout/tables/nsTableWrapperFrame.cpp +++ b/layout/tables/nsTableWrapperFrame.cpp @@ -168,6 +168,7 @@ nsTableWrapperFrame::RemoveFrame(ChildListID aListID, void nsTableWrapperFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // No border, background or outline are painted because they all belong @@ -176,15 +177,16 @@ nsTableWrapperFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // If there's no caption, take a short cut to avoid having to create // the special display list set and then sort it. if (mCaptionFrames.IsEmpty()) { - BuildDisplayListForInnerTable(aBuilder, aLists); + BuildDisplayListForInnerTable(aBuilder, aDirtyRect, aLists); return; } - nsDisplayListCollection set(aBuilder); - BuildDisplayListForInnerTable(aBuilder, set); + nsDisplayListCollection set; + BuildDisplayListForInnerTable(aBuilder, aDirtyRect, set); nsDisplayListSet captionSet(set, set.BlockBorderBackgrounds()); - BuildDisplayListForChild(aBuilder, mCaptionFrames.FirstChild(), captionSet); + BuildDisplayListForChild(aBuilder, mCaptionFrames.FirstChild(), + aDirtyRect, captionSet); // Now we have to sort everything by content order, since the caption // may be somewhere inside the table @@ -198,6 +200,7 @@ nsTableWrapperFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, void nsTableWrapperFrame::BuildDisplayListForInnerTable(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // Just paint the regular children, but the children's background is our @@ -205,7 +208,7 @@ nsTableWrapperFrame::BuildDisplayListForInnerTable(nsDisplayListBuilder* aBuil nsIFrame* kid = mFrames.FirstChild(); // The children should be in content order while (kid) { - BuildDisplayListForChild(aBuilder, kid, aLists); + BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); kid = kid->GetNextSibling(); } } diff --git a/layout/tables/nsTableWrapperFrame.h b/layout/tables/nsTableWrapperFrame.h index 8095c7fc4..45d7c33e4 100644 --- a/layout/tables/nsTableWrapperFrame.h +++ b/layout/tables/nsTableWrapperFrame.h @@ -59,9 +59,11 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; void BuildDisplayListForInnerTable(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists); virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override; diff --git a/layout/xul/nsBoxFrame.cpp b/layout/xul/nsBoxFrame.cpp index 9982a39f7..9ca351d94 100644 --- a/layout/xul/nsBoxFrame.cpp +++ b/layout/xul/nsBoxFrame.cpp @@ -1310,6 +1310,7 @@ PaintXULDebugBackground(nsIFrame* aFrame, DrawTarget* aDrawTarget, void nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { bool forceLayer = false; @@ -1328,7 +1329,7 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } } - nsDisplayListCollection tempLists (aBuilder); + nsDisplayListCollection tempLists; const nsDisplayListSet& destination = forceLayer ? tempLists : aLists; DisplayBorderBackgroundOutline(aBuilder, destination); @@ -1343,7 +1344,7 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } #endif - BuildDisplayListForChildren(aBuilder, destination); + BuildDisplayListForChildren(aBuilder, aDirtyRect, destination); // see if we have to draw a selection frame around this container DisplaySelectionOverlay(aBuilder, destination.Content()); @@ -1369,6 +1370,7 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, void nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { nsIFrame* kid = mFrames.FirstChild(); @@ -1377,7 +1379,7 @@ nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds()); // The children should be in the right order while (kid) { - BuildDisplayListForChild(aBuilder, kid, set); + BuildDisplayListForChild(aBuilder, kid, aDirtyRect, set); kid = kid->GetNextSibling(); } } diff --git a/layout/xul/nsBoxFrame.h b/layout/xul/nsBoxFrame.h index 7b15f4f5e..ad405222f 100644 --- a/layout/xul/nsBoxFrame.h +++ b/layout/xul/nsBoxFrame.h @@ -148,9 +148,11 @@ public: // virtual so nsStackFrame, nsButtonBoxFrame, nsSliderFrame and nsMenuFrame // can override it virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists); virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; #ifdef DEBUG_LAYOUT diff --git a/layout/xul/nsButtonBoxFrame.cpp b/layout/xul/nsButtonBoxFrame.cpp index 4f2a7cbe1..45d934516 100644 --- a/layout/xul/nsButtonBoxFrame.cpp +++ b/layout/xul/nsButtonBoxFrame.cpp @@ -91,12 +91,13 @@ nsButtonBoxFrame::DestroyFrom(nsIFrame* aDestructRoot) void nsButtonBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // override, since we don't want children to get events if (aBuilder->IsForEventDelivery()) return; - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); } nsresult diff --git a/layout/xul/nsButtonBoxFrame.h b/layout/xul/nsButtonBoxFrame.h index 0dc8b517f..e9bfd99a5 100644 --- a/layout/xul/nsButtonBoxFrame.h +++ b/layout/xul/nsButtonBoxFrame.h @@ -23,6 +23,7 @@ public: nsIFrame* aPrevInFlow) override; virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void DestroyFrom(nsIFrame* aDestructRoot) override; diff --git a/layout/xul/nsDeckFrame.cpp b/layout/xul/nsDeckFrame.cpp index 91359c177..b0c0296b2 100644 --- a/layout/xul/nsDeckFrame.cpp +++ b/layout/xul/nsDeckFrame.cpp @@ -145,13 +145,14 @@ nsDeckFrame::GetSelectedBox() void nsDeckFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // if a tab is hidden all its children are too. if (!StyleVisibility()->mVisible) return; - nsBoxFrame::BuildDisplayList(aBuilder, aLists); + nsBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); } void @@ -184,6 +185,7 @@ nsDeckFrame::RemoveFrame(ChildListID aListID, void nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // only paint the selected box @@ -194,7 +196,7 @@ nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, // Putting the child in the background list. This is a little weird but // it matches what we were doing before. nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds()); - BuildDisplayListForChild(aBuilder, box, set); + BuildDisplayListForChild(aBuilder, box, aDirtyRect, set); } NS_IMETHODIMP diff --git a/layout/xul/nsDeckFrame.h b/layout/xul/nsDeckFrame.h index 143745236..2c7ae1445 100644 --- a/layout/xul/nsDeckFrame.h +++ b/layout/xul/nsDeckFrame.h @@ -34,12 +34,14 @@ public: NS_IMETHOD DoXULLayout(nsBoxLayoutState& aState) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override; virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Init(nsIContent* aContent, diff --git a/layout/xul/nsGroupBoxFrame.cpp b/layout/xul/nsGroupBoxFrame.cpp index df3955cf3..514287a24 100644 --- a/layout/xul/nsGroupBoxFrame.cpp +++ b/layout/xul/nsGroupBoxFrame.cpp @@ -28,6 +28,7 @@ public: virtual nsresult GetXULBorderAndPadding(nsMargin& aBorderAndPadding) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; #ifdef DEBUG_FRAME_DUMP @@ -144,13 +145,13 @@ nsDisplayXULGroupBorder::Paint(nsDisplayListBuilder* aBuilder, void nsGroupBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // Paint our background and border if (IsVisibleForPainting(aBuilder)) { nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, this, - GetBackgroundRectRelativeToSelf() + aBuilder->ToReferenceFrame(this), + aBuilder, this, GetBackgroundRectRelativeToSelf(), aLists.BorderBackground()); aLists.BorderBackground()->AppendNewToTop(new (aBuilder) nsDisplayXULGroupBorder(aBuilder, this)); @@ -158,7 +159,7 @@ nsGroupBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, DisplayOutline(aBuilder, aLists); } - BuildDisplayListForChildren(aBuilder, aLists); + BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); } nsRect diff --git a/layout/xul/nsImageBoxFrame.cpp b/layout/xul/nsImageBoxFrame.cpp index e88b502ab..fd7c7becf 100644 --- a/layout/xul/nsImageBoxFrame.cpp +++ b/layout/xul/nsImageBoxFrame.cpp @@ -320,9 +320,10 @@ nsImageBoxFrame::UpdateLoadFlags() void nsImageBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsLeafBoxFrame::BuildDisplayList(aBuilder, aLists); + nsLeafBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); if ((0 == mRect.width) || (0 == mRect.height)) { // Do not render when given a zero area. This avoids some useless diff --git a/layout/xul/nsImageBoxFrame.h b/layout/xul/nsImageBoxFrame.h index 46c8d5614..7faccccae 100644 --- a/layout/xul/nsImageBoxFrame.h +++ b/layout/xul/nsImageBoxFrame.h @@ -87,6 +87,7 @@ public: void UpdateLoadFlags(); virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual ~nsImageBoxFrame(); diff --git a/layout/xul/nsLeafBoxFrame.cpp b/layout/xul/nsLeafBoxFrame.cpp index 8342b7485..6d1783c11 100644 --- a/layout/xul/nsLeafBoxFrame.cpp +++ b/layout/xul/nsLeafBoxFrame.cpp @@ -106,6 +106,7 @@ void nsLeafBoxFrame::UpdateMouseThrough() void nsLeafBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // REVIEW: GetFrameForPoint used to not report events for the background diff --git a/layout/xul/nsLeafBoxFrame.h b/layout/xul/nsLeafBoxFrame.h index 7a63d9a79..8aea598c8 100644 --- a/layout/xul/nsLeafBoxFrame.h +++ b/layout/xul/nsLeafBoxFrame.h @@ -64,6 +64,7 @@ public: nsIFrame* asPrevInFlow) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsresult AttributeChanged(int32_t aNameSpaceID, diff --git a/layout/xul/nsListItemFrame.cpp b/layout/xul/nsListItemFrame.cpp index 720df3827..1776f1b6c 100644 --- a/layout/xul/nsListItemFrame.cpp +++ b/layout/xul/nsListItemFrame.cpp @@ -39,6 +39,7 @@ nsListItemFrame::GetXULPrefSize(nsBoxLayoutState& aState) void nsListItemFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (aBuilder->IsForEventDelivery()) { @@ -47,7 +48,7 @@ nsListItemFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, return; } - nsGridRowLeafFrame::BuildDisplayListForChildren(aBuilder, aLists); + nsGridRowLeafFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); } // Creation Routine /////////////////////////////////////////////////////////////////////// diff --git a/layout/xul/nsListItemFrame.h b/layout/xul/nsListItemFrame.h index aa41dbbbf..40e731efa 100644 --- a/layout/xul/nsListItemFrame.h +++ b/layout/xul/nsListItemFrame.h @@ -20,6 +20,7 @@ public: // overridden so that children of listitems don't handle mouse events, // unless allowevents="true" is specified on the listitem virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsSize GetXULPrefSize(nsBoxLayoutState& aState) override; diff --git a/layout/xul/nsMenuFrame.cpp b/layout/xul/nsMenuFrame.cpp index 6bd5b44ff..67fcdbe43 100644 --- a/layout/xul/nsMenuFrame.cpp +++ b/layout/xul/nsMenuFrame.cpp @@ -356,15 +356,16 @@ nsMenuFrame::DestroyFrom(nsIFrame* aDestructRoot) void nsMenuFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!aBuilder->IsForEventDelivery()) { - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); return; } - nsDisplayListCollection set (aBuilder); - nsBoxFrame::BuildDisplayListForChildren(aBuilder, set); + nsDisplayListCollection set; + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, set); WrapListsInRedirector(aBuilder, set, aLists); } diff --git a/layout/xul/nsMenuFrame.h b/layout/xul/nsMenuFrame.h index 43cbd0a04..1941ec69e 100644 --- a/layout/xul/nsMenuFrame.h +++ b/layout/xul/nsMenuFrame.h @@ -101,6 +101,7 @@ public: // Overridden to prevent events from going to children of the menu. virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; // this method can destroy the frame diff --git a/layout/xul/nsRootBoxFrame.cpp b/layout/xul/nsRootBoxFrame.cpp index 26e94faea..fe41dce52 100644 --- a/layout/xul/nsRootBoxFrame.cpp +++ b/layout/xul/nsRootBoxFrame.cpp @@ -75,6 +75,7 @@ public: nsEventStatus* aEventStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; /** @@ -175,14 +176,14 @@ nsRootBoxFrame::Reflow(nsPresContext* aPresContext, void nsRootBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (mContent && mContent->GetProperty(nsGkAtoms::DisplayPortMargins)) { // The XUL document's root element may have displayport margins set in // ChromeProcessController::InitializeRoot, and we should to supply the // base rect. - nsRect displayPortBase = - aBuilder->GetVisibleRect().Intersect(nsRect(nsPoint(0, 0), GetSize())); + nsRect displayPortBase = aDirtyRect.Intersect(nsRect(nsPoint(0, 0), GetSize())); nsLayoutUtils::SetDisplayPortBase(mContent, displayPortBase); } @@ -191,7 +192,7 @@ nsRootBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // of a background display list element. DisplayBorderBackgroundOutline(aBuilder, aLists, true); - BuildDisplayListForChildren(aBuilder, aLists); + BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); } nsresult diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index db2218944..3c1f9ef91 100644 --- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -311,6 +311,7 @@ nsSliderFrame::AttributeChanged(int32_t aNameSpaceID, void nsSliderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (aBuilder->IsForEventDelivery() && isDraggingThumb()) { @@ -321,11 +322,12 @@ nsSliderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, return; } - nsBoxFrame::BuildDisplayList(aBuilder, aLists); + nsBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); } void nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // if we are too small to have a thumb don't paint it. @@ -358,8 +360,8 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, nsLayoutUtils::SetScrollbarThumbLayerization(thumb, thumbGetsLayer); if (thumbGetsLayer) { - nsDisplayListCollection tempLists (aBuilder); - nsBoxFrame::BuildDisplayListForChildren(aBuilder, tempLists); + nsDisplayListCollection tempLists; + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, tempLists); // This is a bit of a hack. Collect up all descendant display items // and merge them into a single Content() list. @@ -380,7 +382,7 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, } } - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); } NS_IMETHODIMP diff --git a/layout/xul/nsSliderFrame.h b/layout/xul/nsSliderFrame.h index e4b68fc01..832065a21 100644 --- a/layout/xul/nsSliderFrame.h +++ b/layout/xul/nsSliderFrame.h @@ -64,9 +64,11 @@ public: virtual void DestroyFrom(nsIFrame* aDestructRoot) override; virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsresult AttributeChanged(int32_t aNameSpaceID, diff --git a/layout/xul/nsSplitterFrame.cpp b/layout/xul/nsSplitterFrame.cpp index 468ccc682..7879a176d 100644 --- a/layout/xul/nsSplitterFrame.cpp +++ b/layout/xul/nsSplitterFrame.cpp @@ -358,9 +358,10 @@ nsSplitterFrame::HandleRelease(nsPresContext* aPresContext, void nsSplitterFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsBoxFrame::BuildDisplayList(aBuilder, aLists); + nsBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); // if the mouse is captured always return us as the frame. if (mInner->mDragging) diff --git a/layout/xul/nsSplitterFrame.h b/layout/xul/nsSplitterFrame.h index fa1c7525f..df8872255 100644 --- a/layout/xul/nsSplitterFrame.h +++ b/layout/xul/nsSplitterFrame.h @@ -68,6 +68,7 @@ public: nsEventStatus* aEventStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void GetInitialOrientation(bool& aIsHorizontal) override; diff --git a/layout/xul/nsStackFrame.cpp b/layout/xul/nsStackFrame.cpp index a2ec57adc..437d558f9 100644 --- a/layout/xul/nsStackFrame.cpp +++ b/layout/xul/nsStackFrame.cpp @@ -45,6 +45,7 @@ nsStackFrame::nsStackFrame(nsStyleContext* aContext): // a bit more. void nsStackFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // BuildDisplayListForChild puts stacking contexts into the PositionedDescendants @@ -55,7 +56,8 @@ nsStackFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, nsIFrame* kid = mFrames.FirstChild(); while (kid) { // Force each child into its own true stacking context. - BuildDisplayListForChild(aBuilder, kid, kidLists, DISPLAY_CHILD_FORCE_STACKING_CONTEXT); + BuildDisplayListForChild(aBuilder, kid, aDirtyRect, kidLists, + DISPLAY_CHILD_FORCE_STACKING_CONTEXT); kid = kid->GetNextSibling(); } } diff --git a/layout/xul/nsStackFrame.h b/layout/xul/nsStackFrame.h index a81a62281..b90a16b21 100644 --- a/layout/xul/nsStackFrame.h +++ b/layout/xul/nsStackFrame.h @@ -33,6 +33,7 @@ public: #endif virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; protected: diff --git a/layout/xul/nsTextBoxFrame.cpp b/layout/xul/nsTextBoxFrame.cpp index e1650e0d0..c82d3d6b9 100644 --- a/layout/xul/nsTextBoxFrame.cpp +++ b/layout/xul/nsTextBoxFrame.cpp @@ -364,12 +364,13 @@ nsDisplayXULTextBox::GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) void nsTextBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) return; - nsLeafBoxFrame::BuildDisplayList(aBuilder, aLists); + nsLeafBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); aLists.Content()->AppendNewToTop(new (aBuilder) nsDisplayXULTextBox(aBuilder, this)); diff --git a/layout/xul/nsTextBoxFrame.h b/layout/xul/nsTextBoxFrame.h index e12b97b32..ca1b88748 100644 --- a/layout/xul/nsTextBoxFrame.h +++ b/layout/xul/nsTextBoxFrame.h @@ -48,6 +48,7 @@ public: bool& aRedraw); virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual ~nsTextBoxFrame(); diff --git a/layout/xul/nsTitleBarFrame.cpp b/layout/xul/nsTitleBarFrame.cpp index 2f58abecb..2792403dc 100644 --- a/layout/xul/nsTitleBarFrame.cpp +++ b/layout/xul/nsTitleBarFrame.cpp @@ -42,6 +42,7 @@ nsTitleBarFrame::nsTitleBarFrame(nsStyleContext* aContext) void nsTitleBarFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // override, since we don't want children to get events @@ -50,7 +51,7 @@ nsTitleBarFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, nsGkAtoms::_true, eCaseMatters)) return; } - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); } nsresult diff --git a/layout/xul/nsTitleBarFrame.h b/layout/xul/nsTitleBarFrame.h index 594d0978b..17279c578 100644 --- a/layout/xul/nsTitleBarFrame.h +++ b/layout/xul/nsTitleBarFrame.h @@ -19,6 +19,7 @@ public: explicit nsTitleBarFrame(nsStyleContext* aContext); virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsresult HandleEvent(nsPresContext* aPresContext, diff --git a/layout/xul/tree/nsTreeBodyFrame.cpp b/layout/xul/tree/nsTreeBodyFrame.cpp index 608d802ea..deba04a36 100644 --- a/layout/xul/tree/nsTreeBodyFrame.cpp +++ b/layout/xul/tree/nsTreeBodyFrame.cpp @@ -2824,6 +2824,7 @@ public: // Painting routines void nsTreeBodyFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // REVIEW: why did we paint if we were collapsed? that makes no sense! @@ -2831,7 +2832,7 @@ nsTreeBodyFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, return; // We're invisible. Don't paint. // Handles painting our background, border, and outline. - nsLeafBoxFrame::BuildDisplayList(aBuilder, aLists); + nsLeafBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); // Bail out now if there's no view or we can't run script because the // document is a zombie diff --git a/layout/xul/tree/nsTreeBodyFrame.h b/layout/xul/tree/nsTreeBodyFrame.h index 6838b0157..9620c8ccb 100644 --- a/layout/xul/tree/nsTreeBodyFrame.h +++ b/layout/xul/tree/nsTreeBodyFrame.h @@ -177,6 +177,7 @@ public: nsEventStatus* aEventStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override; diff --git a/layout/xul/tree/nsTreeColFrame.cpp b/layout/xul/tree/nsTreeColFrame.cpp index 0bedec086..649c0b0b4 100644 --- a/layout/xul/tree/nsTreeColFrame.cpp +++ b/layout/xul/tree/nsTreeColFrame.cpp @@ -110,15 +110,16 @@ nsDisplayXULTreeColSplitterTarget::HitTest(nsDisplayListBuilder* aBuilder, const void nsTreeColFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!aBuilder->IsForEventDelivery()) { - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); return; } - nsDisplayListCollection set (aBuilder); - nsBoxFrame::BuildDisplayListForChildren(aBuilder, set); + nsDisplayListCollection set; + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, set); WrapListsInRedirector(aBuilder, set, aLists); diff --git a/layout/xul/tree/nsTreeColFrame.h b/layout/xul/tree/nsTreeColFrame.h index ebd16fa52..8fc3219d5 100644 --- a/layout/xul/tree/nsTreeColFrame.h +++ b/layout/xul/tree/nsTreeColFrame.h @@ -26,6 +26,7 @@ public: virtual void DestroyFrom(nsIFrame* aDestructRoot) override; virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nsresult AttributeChanged(int32_t aNameSpaceID, |