diff options
author | win7-7 <win7-7@users.noreply.github.com> | 2020-02-25 00:17:54 +0200 |
---|---|---|
committer | win7-7 <win7-7@users.noreply.github.com> | 2020-02-25 00:17:54 +0200 |
commit | 44c47c50388f526c2d134e16d5debebe94a0faf8 (patch) | |
tree | 5c46b943a3463f67e379eebdbcc8e364eeca9a7c /layout | |
parent | 81089ff09437ca99eba3dacf901fdef0de533024 (diff) | |
download | uxp-44c47c50388f526c2d134e16d5debebe94a0faf8.tar.gz |
Issue #1355 - Better way to create display items for column backgrounds
Part 1: Remove current table item, as it's never set.
Part 2: Get rid of generic table painting code, and handle each class separately.
Part 4: Hoist outline skipping into col(group) frame code.
Part 5: Skip box-shadow for table column and column groups.
Part 6: Store column and column group backgrounds separately, and then append them before the rest of the table contents.
Part 7: Pass rects in display list coordinates to AppendBackgroundItemsToTop.
Part 8: Create column and column group background display items as part of the cell's BuildDisplayList.
Part 9: Used cached values instead of calling nsDisplayListBuilder::ToReferenceFrame when possible, since it can be expensive when the requested frame isn't the builder's current frame.
Part 10: Make sure we build display items for table parts where only the normal position is visible, since we may need to create background items for ancestors at that position.
Part 11: Create an AutoBuildingDisplayList when we create background items for table columns and column groups, so that we initialize the invalidation state correctly.
Diffstat (limited to 'layout')
171 files changed, 1054 insertions, 830 deletions
diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 8a34d108f1..f870c6d971 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -721,7 +721,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, : mReferenceFrame(aReferenceFrame), mIgnoreScrollFrame(nullptr), mLayerEventRegions(nullptr), - mCurrentTableItem(nullptr), mCurrentFrame(aReferenceFrame), mCurrentReferenceFrame(aReferenceFrame), mCurrentAGR(&mRootAGR), @@ -731,6 +730,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, mGlassDisplayItem(nullptr), mScrollInfoItemsForHoisting(nullptr), mMode(aMode), + mTableBackgroundSet(nullptr), mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID), mCurrentScrollbarTarget(FrameMetrics::NULL_SCROLL_ID), mCurrentScrollbarFlags(0), @@ -783,7 +783,10 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, "Check nsDisplayItem::TYPE_MAX should not overflow"); } -static void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) { +void +nsDisplayListBuilder::MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) +{ + mFramesMarkedForDisplay.AppendElement(aFrame); for (nsIFrame* f = aFrame; f; f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) { if (f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) @@ -796,6 +799,22 @@ static void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) { } } +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(); @@ -864,10 +883,10 @@ nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsDisplayItem* aItem) void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, - nsIFrame* aFrame, - const nsRect& aDirtyRect) + nsIFrame* aFrame) { - nsRect dirtyRectRelativeToDirtyFrame = aDirtyRect; + nsRect visible = GetVisibleRect(); + nsRect dirtyRectRelativeToDirtyFrame = GetDirtyRect(); if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) && IsPaintingToWindow()) { NS_ASSERTION(aDirtyFrame == aFrame->GetParent(), "Dirty frame should be viewport frame"); @@ -881,8 +900,14 @@ 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; } - nsRect dirty = dirtyRectRelativeToDirtyFrame - aFrame->GetOffsetTo(aDirtyFrame); + + nsPoint offset = aFrame->GetOffsetTo(aDirtyFrame); + visible -= offset; + nsRect dirty = dirtyRectRelativeToDirtyFrame - offset; nsRect overflowRect = aFrame->GetVisualOverflowRect(); if (aFrame->IsTransformed() && @@ -895,15 +920,18 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, */ overflowRect.Inflate(nsPresContext::CSSPixelsToAppUnits(32)); } - - if (!dirty.IntersectRect(dirty, overflowRect) && - !(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) { + visible.IntersectRect(visible, overflowRect); + dirty.IntersectRect(dirty, overflowRect); + if (!(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) && + dirty.IsEmpty() && + (!aFrame->ForceDescendIntoIfVisible() || + visible.IsEmpty())) { return; } const DisplayItemClip* oldClip = mClipState.GetClipForContainingBlockDescendants(); const DisplayItemScrollClip* sc = mClipState.GetCurrentInnermostScrollClip(); - OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, dirty); + OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, visible, dirty); aFrame->SetProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data); MarkFrameForDisplay(aFrame, aDirtyFrame); @@ -914,9 +942,11 @@ static void UnmarkFrameForDisplay(nsIFrame* aFrame) { for (nsIFrame* f = aFrame; f; f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) { - if (!(f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) + if (!(f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) && + !f->ForceDescendIntoIfVisible()) return; f->RemoveStateBits(NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO); + f->SetForceDescendIntoIfVisible(false); } } @@ -925,7 +955,6 @@ nsDisplayListBuilder::~nsDisplayListBuilder() { "All frames should have been unmarked"); NS_ASSERTION(mPresShellStates.Length() == 0, "All presshells should have been exited"); - NS_ASSERTION(!mCurrentTableItem, "No table item should be active"); nsCSSRendering::EndFrameTreesLocked(); @@ -1008,22 +1037,27 @@ 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. @@ -1094,8 +1128,7 @@ nsDisplayListBuilder::ResetMarkedFramesForDisplayList() void nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame, - const nsFrameList& aFrames, - const nsRect& aDirtyRect) { + const nsFrameList& aFrames) { for (nsIFrame* e : aFrames) { // Skip the AccessibleCaret frame when building no caret. if (!IsBuildingCaret()) { @@ -1108,8 +1141,7 @@ nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame, } } - mFramesMarkedForDisplay.AppendElement(e); - MarkOutOfFlowFrameForDisplay(aDirtyFrame, e, aDirtyRect); + MarkOutOfFlowFrameForDisplay(aDirtyFrame, e); } } @@ -1132,7 +1164,6 @@ nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame) for (; !childFrames.AtEnd(); childFrames.Next()) { nsIFrame *child = childFrames.get(); if (child->Combines3DTransformWithAncestors()) { - mFramesMarkedForDisplay.AppendElement(child); MarkFrameForDisplay(child, aDirtyFrame); } } @@ -2318,11 +2349,11 @@ nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(aFrame); MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(), *mAnimatedGeometryRoot), "Bad"); - NS_ASSERTION(aBuilder->GetDirtyRect().width >= 0 || - !aBuilder->IsForPainting(), "dirty rect not set"); - // The dirty rect is for mCurrentFrame, so we have to use + NS_ASSERTION(aBuilder->GetVisibleRect().width >= 0 || + !aBuilder->IsForPainting(), "visible rect not set"); + // The visible rect is for mCurrentFrame, so we have to use // mCurrentOffsetToReferenceFrame - mVisibleRect = aBuilder->GetDirtyRect() + + mVisibleRect = aBuilder->GetVisibleRect() + aBuilder->GetCurrentFrameOffsetToReferenceFrame(); } @@ -2573,8 +2604,7 @@ static nsStyleContext* GetBackgroundStyleContext(nsIFrame* aFrame) /* static */ void SetBackgroundClipRegion(DisplayListClipState::AutoSaveRestore& aClipState, - nsIFrame* aFrame, const nsPoint& aToReferenceFrame, - const nsStyleImageLayers::Layer& aLayer, + nsIFrame* aFrame, const nsStyleImageLayers::Layer& aLayer, const nsRect& aBackgroundRect, bool aWillPaintBorder) { @@ -2626,7 +2656,6 @@ SpecialCutoutRegionCase(nsDisplayListBuilder* aBuilder, return true; } - /*static*/ bool nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, @@ -2635,14 +2664,16 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil bool aAllowWillPaintBorderOptimization, nsStyleContext* aStyleContext, const nsRect& aBackgroundOriginRect, - nsIFrame* aSecondaryReferenceFrame) + nsIFrame* aSecondaryReferenceFrame, + Maybe<nsDisplayListBuilder::AutoBuildingDisplayList>* + aAutoBuildingDisplayList) { nsStyleContext* bgSC = aStyleContext; const nsStyleBackground* bg = nullptr; - nsRect bgRect = aBackgroundRect + aBuilder->ToReferenceFrame(aFrame); + nsRect bgRect = aBackgroundRect; nsRect bgOriginRect = bgRect; if (!aBackgroundOriginRect.IsEmpty()) { - bgOriginRect = aBackgroundOriginRect + aBuilder->ToReferenceFrame(aFrame); + bgOriginRect = aBackgroundOriginRect; } nsPresContext* presContext = aFrame->PresContext(); bool isThemed = aFrame->IsThemed(); @@ -2678,8 +2709,6 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil !isThemed && !hasInsetShadow && borderStyle->HasBorder(); - nsPoint toRef = aBuilder->ToReferenceFrame(aFrame); - // An auxiliary list is necessary in case we have background blending; if that // is the case, background items need to be wrapped by a blend container to // isolate blending to the background @@ -2688,6 +2717,9 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil // to create an item for hit testing. if ((drawBackgroundColor && color != NS_RGBA(0,0,0,0)) || aBuilder->IsForEventDelivery()) { + if (aAutoBuildingDisplayList && !*aAutoBuildingDisplayList) { + aAutoBuildingDisplayList->emplace(aBuilder, aFrame); + } DisplayListClipState::AutoSaveRestore clipState(aBuilder); if (bg && !aBuilder->IsForEventDelivery()) { // Disable the will-paint-border optimization for background @@ -2699,7 +2731,7 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil // artifacts along the rounded corners. bool useWillPaintBorderOptimization = willPaintBorder && nsLayoutUtils::HasNonZeroCorner(borderStyle->mBorderRadius); - SetBackgroundClipRegion(clipState, aFrame, toRef, + SetBackgroundClipRegion(clipState, aFrame, bg->BottomLayer(), bgRect, useWillPaintBorderOptimization); } @@ -2752,6 +2784,10 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil continue; } + if (aAutoBuildingDisplayList && !*aAutoBuildingDisplayList) { + aAutoBuildingDisplayList->emplace(aBuilder, aFrame); + } + if (bg->mImage.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) { needBlendContainer = true; } @@ -2759,8 +2795,8 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil DisplayListClipState::AutoSaveRestore clipState(aBuilder); if (!aBuilder->IsForEventDelivery()) { const nsStyleImageLayers::Layer& layer = bg->mImage.mLayers[i]; - SetBackgroundClipRegion(clipState, aFrame, toRef, - layer, bgRect, willPaintBorder); + SetBackgroundClipRegion(clipState, aFrame, layer, bgRect, + willPaintBorder); } nsDisplayList thisItemList; @@ -4342,7 +4378,7 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, mReferenceFrame = i->ReferenceFrame(); mToReferenceFrame = i->ToReferenceFrame(); } - mVisibleRect = aBuilder->GetDirtyRect() + + mVisibleRect = aBuilder->GetVisibleRect() + aBuilder->GetCurrentFrameOffsetToReferenceFrame(); } @@ -4368,7 +4404,7 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, mReferenceFrame = aItem->ReferenceFrame(); mToReferenceFrame = aItem->ToReferenceFrame(); } - mVisibleRect = aBuilder->GetDirtyRect() + + mVisibleRect = aBuilder->GetVisibleRect() + aBuilder->GetCurrentFrameOffsetToReferenceFrame(); } diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 9cee7b517d..9ae76e2ac5 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -48,6 +48,7 @@ class nsISelection; class nsIScrollableFrame; class nsDisplayLayerEventRegions; class nsDisplayScrollInfoLayer; +class nsDisplayTableBackgroundSet; class nsCaret; namespace mozilla { @@ -202,6 +203,7 @@ class nsDisplayListBuilder { : mAccumulatedTransform() , mAccumulatedRect() , mAccumulatedRectLevels(0) + , mVisibleRect(aOther.mVisibleRect) , mDirtyRect(aOther.mDirtyRect) {} // Accmulate transforms of ancestors on the preserves-3d chain. @@ -210,6 +212,7 @@ class nsDisplayListBuilder { nsRect mAccumulatedRect; // How far this frame is from the root of the current 3d context. int mAccumulatedRectLevels; + nsRect mVisibleRect; nsRect mDirtyRect; }; @@ -443,7 +446,14 @@ 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; } @@ -493,11 +503,10 @@ public: /** * Display the caret if needed. */ - void DisplayCaret(nsIFrame* aFrame, const nsRect& aDirtyRect, - nsDisplayList* aList) { + void DisplayCaret(nsIFrame* aFrame, nsDisplayList* aList) { nsIFrame* frame = GetCaretFrame(); if (aFrame == frame) { - frame->DisplayCaret(this, aDirtyRect, aList); + frame->DisplayCaret(this, aList); } } /** @@ -517,6 +526,15 @@ public: * Get the caret associated with the current presshell. */ nsCaret* GetCaret(); + + /** + * Returns the root scroll frame for the current PresShell, if the PresShell + * is ignoring viewport scrolling. + */ + nsIFrame* GetPresShellIgnoreScrollFrame() { + return CurrentPresShellState()->mPresShellIgnoreScrollFrame; + } + /** * Notify the display list builder that we're entering a presshell. * aReferenceFrame should be a frame in the new presshell. @@ -577,6 +595,16 @@ public: mSyncDecodeImages = aSyncDecodeImages; } + nsDisplayTableBackgroundSet* SetTableBackgroundSet( + nsDisplayTableBackgroundSet* aTableSet) { + nsDisplayTableBackgroundSet* old = mTableBackgroundSet; + mTableBackgroundSet = aTableSet; + return old; + } + nsDisplayTableBackgroundSet* GetTableBackgroundSet() const { + return mTableBackgroundSet; + } + /** * Helper method to generate background painting flags based on the * information available in the display list builder. Currently only @@ -602,8 +630,9 @@ public: * destroyed. */ void MarkFramesForDisplayList(nsIFrame* aDirtyFrame, - const nsFrameList& aFrames, - const nsRect& aDirtyRect); + const nsFrameList& aFrames); + void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame = nullptr); + void MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* aStopAtFrame = nullptr); /** * Mark all child frames that Preserve3D() as needing display. * Because these frames include transforms set on their parent, dirty rects @@ -618,9 +647,10 @@ 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) const { + bool ShouldDescendIntoFrame(nsIFrame* aFrame, bool aVisible) const { return (aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) || + (aVisible && aFrame->ForceDescendIntoIfVisible()) || GetIncludeAllOutOfFlows(); } @@ -700,14 +730,20 @@ public: friend class AutoBuildingDisplayList; class AutoBuildingDisplayList { public: - AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, - nsIFrame* aForChild, + AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* aForChild) + : AutoBuildingDisplayList( + aBuilder, aForChild, aBuilder->GetVisibleRect(), + aBuilder->GetDirtyRect(), aForChild->IsTransformed()){} + + AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* aForChild, + const nsRect& aVisibleRect, 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), @@ -733,12 +769,10 @@ 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; @@ -760,6 +794,7 @@ public: mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame; mBuilder->mLayerEventRegions = mPrevLayerEventRegions; mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset; + mBuilder->mVisibleRect = mPrevVisibleRect; mBuilder->mDirtyRect = mPrevDirtyRect; mBuilder->mCurrentAGR = mPrevAGR; mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext; @@ -773,6 +808,7 @@ public: nsIFrame* mPrevAnimatedGeometryRoot; nsDisplayLayerEventRegions* mPrevLayerEventRegions; nsPoint mPrevOffset; + nsRect mPrevVisibleRect; nsRect mPrevDirtyRect; AnimatedGeometryRoot* mPrevAGR; bool mPrevIsAtRootOfPseudoStackingContext; @@ -981,20 +1017,19 @@ 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; }; @@ -1120,11 +1155,13 @@ public: Preserves3DContext mSavedCtx; }; - const nsRect GetPreserves3DDirtyRect(const nsIFrame *aFrame) const { + const nsRect GetPreserves3DRects(nsRect* aOutVisibleRect) const { + *aOutVisibleRect = mPreserves3DCtx.mVisibleRect; return mPreserves3DCtx.mDirtyRect; } - void SetPreserves3DDirtyRect(const nsRect &aDirtyRect) { - mPreserves3DCtx.mDirtyRect = aDirtyRect; + void SavePreserves3DRects() { + mPreserves3DCtx.mVisibleRect = mVisibleRect; + mPreserves3DCtx.mDirtyRect = mDirtyRect; } bool IsBuildingInvisibleItems() const { return mBuildingInvisibleItems; } @@ -1133,8 +1170,7 @@ public: } private: - void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame, - const nsRect& aDirtyRect); + void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame); /** * Returns whether a frame acts as an animated geometry root, optionally @@ -1174,6 +1210,7 @@ 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. @@ -1202,7 +1239,6 @@ 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. @@ -1229,6 +1265,7 @@ private: nsTHashtable<nsPtrHashKey<nsIFrame> > mAGRBudgetSet; // Relative to mCurrentFrame. + nsRect mVisibleRect; nsRect mDirtyRect; nsRegion mWindowExcludeGlassRegion; nsRegion mWindowOpaqueRegion; @@ -1245,6 +1282,7 @@ private: nsTArray<DisplayItemScrollClip*> mScrollClipsToDestroy; nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy; nsDisplayListBuilderMode mMode; + nsDisplayTableBackgroundSet* mTableBackgroundSet; ViewID mCurrentScrollParentId; ViewID mCurrentScrollbarTarget; uint32_t mCurrentScrollbarFlags; @@ -2287,12 +2325,13 @@ protected: * to the object, and all distinct. */ struct nsDisplayListCollection : public nsDisplayListSet { - nsDisplayListCollection() : - nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4], - &mLists[5]) {} - explicit nsDisplayListCollection(nsDisplayList* aBorderBackground) : - nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4], + explicit nsDisplayListCollection(nsDisplayListBuilder* aBuilder) + : nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4], &mLists[5]) {} + explicit nsDisplayListCollection(nsDisplayListBuilder* aBuilder, + nsDisplayList* aBorderBackground) + : nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4], + &mLists[5]) {} /** * Sort all lists by content order. @@ -2739,7 +2778,9 @@ public: bool aAllowWillPaintBorderOptimization = true, nsStyleContext* aStyleContext = nullptr, const nsRect& aBackgroundOriginRect = nsRect(), - nsIFrame* aSecondaryReferenceFrame = nullptr); + nsIFrame* aSecondaryReferenceFrame = nullptr, + mozilla::Maybe<nsDisplayListBuilder::AutoBuildingDisplayList>* + aAutoBuildingDisplayList = nullptr); virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 21d20c69fa..39bef4d561 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -3189,7 +3189,9 @@ nsLayoutUtils::GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect, } builder.EnterPresShell(aFrame); - aFrame->BuildDisplayListForStackingContext(&builder, aRect, &list); + builder.SetVisibleRect(aRect); + builder.SetDirtyRect(aRect); + aFrame->BuildDisplayListForStackingContext(&builder, &list); builder.LeavePresShell(aFrame, nullptr); #ifdef MOZ_DUMP_PAINTING @@ -3448,7 +3450,8 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram nsIScrollableFrame* rootScrollableFrame = presShell->GetRootScrollFrameAsScrollable(); MOZ_ASSERT(rootScrollableFrame); nsRect displayPortBase = aFrame->GetVisualOverflowRectRelativeToSelf(); - Unused << rootScrollableFrame->DecideScrollableLayer(&builder, &displayPortBase, + nsRect temp = displayPortBase; + Unused << rootScrollableFrame->DecideScrollableLayer(&builder, &displayPortBase, &temp, /* aAllowCreateDisplayPort = */ true); } @@ -3538,7 +3541,9 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram PROFILER_LABEL("nsLayoutUtils", "PaintFrame::BuildDisplayList", js::ProfileEntry::Category::GRAPHICS); - aFrame->BuildDisplayListForStackingContext(&builder, dirtyRect, &list); + builder.SetDirtyRect(dirtyRect); + builder.SetVisibleRect(dirtyRect); + aFrame->BuildDisplayListForStackingContext(&builder, &list); } nsIAtom* frameType = aFrame->GetType(); @@ -3550,7 +3555,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram nsRect bounds = nsRect(builder.ToReferenceFrame(aFrame), aFrame->GetSize()); nsDisplayListBuilder::AutoBuildingDisplayList - buildingDisplayList(&builder, aFrame, bounds, false); + buildingDisplayList(&builder, aFrame, bounds, bounds, false); presShell->AddPrintPreviewBackgroundItem(builder, list, aFrame, bounds); } else if (frameType != nsGkAtoms::pageFrame) { // For printing, this function is first called on an nsPageFrame, which @@ -3564,7 +3569,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, false); + buildingDisplayList(&builder, aFrame, canvasArea, canvasArea, false); presShell->AddCanvasBackgroundColorItem( builder, list, aFrame, canvasArea, aBackstop); } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 264b52b18d..222428a891 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -4894,8 +4894,9 @@ PresShell::CreateRangePaintInfo(nsIDOMRange* aRange, nsIFrame* frame = aNode->AsContent()->GetPrimaryFrame(); // XXX deal with frame being null due to display:contents for (; frame; frame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(frame)) { - frame->BuildDisplayListForStackingContext(&info->mBuilder, - frame->GetVisualOverflowRect(), &info->mList); + info->mBuilder.SetVisibleRect(frame->GetVisualOverflowRect()); + info->mBuilder.SetDirtyRect(frame->GetVisualOverflowRect()); + frame->BuildDisplayListForStackingContext(&info->mBuilder, &info->mList); } }; if (startParent->NodeType() == nsIDOMNode::TEXT_NODE) { diff --git a/layout/forms/nsButtonFrameRenderer.cpp b/layout/forms/nsButtonFrameRenderer.cpp index 096031385b..5372acb7fb 100644 --- a/layout/forms/nsButtonFrameRenderer.cpp +++ b/layout/forms/nsButtonFrameRenderer.cpp @@ -263,8 +263,8 @@ nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder, nsDisplayButtonBoxShadowOuter(aBuilder, this)); } - nsRect buttonRect; - GetButtonRect(mFrame->GetRectRelativeToSelf(), buttonRect); + nsRect buttonRect = + mFrame->GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(mFrame); nsDisplayBackgroundImage::AppendBackgroundItemsToTop( aBuilder, mFrame, buttonRect, aBackground); diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 78185616ff..eb8de8e947 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1294,7 +1294,6 @@ public: nsReflowStatus& aStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; protected: @@ -1335,11 +1334,10 @@ nsComboboxDisplayFrame::Reflow(nsPresContext* aPresContext, void nsComboboxDisplayFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsDisplayListCollection set; - nsBlockFrame::BuildDisplayList(aBuilder, aDirtyRect, set); + nsDisplayListCollection set (aBuilder); + nsBlockFrame::BuildDisplayList(aBuilder, set); // remove background items if parent frame is themed if (mComboBox->IsThemed()) { @@ -1547,13 +1545,8 @@ void nsDisplayComboboxFocus::Paint(nsDisplayListBuilder* aBuilder, void nsComboboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { -#ifdef NOISY - printf("%p paint at (%d, %d, %d, %d)\n", this, - aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); -#endif if (aBuilder->IsForEventDelivery()) { // Don't allow children to receive events. @@ -1562,7 +1555,7 @@ nsComboboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } else { // REVIEW: Our in-flow child frames are inline-level so they will paint in our // content list, so we don't need to mess with layers. - nsBlockFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsBlockFrame::BuildDisplayList(aBuilder, aLists); } // draw a focus indicator only when focus rings should be drawn diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index 22849e8d14..d83726d815 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -89,7 +89,6 @@ public: nsEventStatus* aEventStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; void PaintFocus(DrawTarget& aDrawTarget, nsPoint aPt); diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index fc9f0571b7..a5177560de 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -153,7 +153,6 @@ nsDisplayFieldSetBorderBackground::ComputeInvalidationRegion(nsDisplayListBuilde void nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // Paint our background and border in a special way. // REVIEW: We don't really need to check frame emptiness here; if it's empty, @@ -166,9 +165,11 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsDisplayBoxShadowOuter(aBuilder, this)); } + const nsRect rect = + VisualBorderRectRelativeToSelf() + aBuilder->ToReferenceFrame(this); + nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, this, VisualBorderRectRelativeToSelf(), - aLists.BorderBackground(), + aBuilder, this, rect, aLists.BorderBackground(), /* aAllowWillPaintBorderOptimization = */ false); aLists.BorderBackground()->AppendNewToTop(new (aBuilder) @@ -180,10 +181,10 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } if (GetPrevInFlow()) { - DisplayOverflowContainers(aBuilder, aDirtyRect, aLists); + DisplayOverflowContainers(aBuilder, aLists); } - nsDisplayListCollection contentDisplayItems; + nsDisplayListCollection contentDisplayItems(aBuilder); if (nsIFrame* inner = GetInner()) { // Collect the inner frame's display items into their own collection. // We need to be calling BuildDisplayList on it before the legend in @@ -191,13 +192,13 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // legend. However, we want the inner frame's display items to be // after the legend's display items in z-order, so we need to save them // and append them later. - BuildDisplayListForChild(aBuilder, inner, aDirtyRect, contentDisplayItems); + BuildDisplayListForChild(aBuilder, inner, contentDisplayItems); } if (nsIFrame* legend = GetLegend()) { // The legend's background goes on our BlockBorderBackgrounds list because // it's a block child. nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds()); - BuildDisplayListForChild(aBuilder, legend, aDirtyRect, set); + BuildDisplayListForChild(aBuilder, legend, set); } // Put the inner frame's display items on the master list. Note that this // moves its border/background display items to our BorderBackground() list, diff --git a/layout/forms/nsFieldSetFrame.h b/layout/forms/nsFieldSetFrame.h index 5eb67c3209..7c162515ed 100644 --- a/layout/forms/nsFieldSetFrame.h +++ b/layout/forms/nsFieldSetFrame.h @@ -53,7 +53,6 @@ public: nscoord* aBaseline) const override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; DrawResult PaintBorder(nsDisplayListBuilder* aBuilder, diff --git a/layout/forms/nsFileControlFrame.cpp b/layout/forms/nsFileControlFrame.cpp index 6593716151..d60e4fb468 100644 --- a/layout/forms/nsFileControlFrame.cpp +++ b/layout/forms/nsFileControlFrame.cpp @@ -485,10 +485,9 @@ nsFileControlFrame::SetFormProperty(nsIAtom* aName, void nsFileControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); + BuildDisplayListForInline(aBuilder, aLists); } #ifdef ACCESSIBILITY diff --git a/layout/forms/nsFileControlFrame.h b/layout/forms/nsFileControlFrame.h index 55c51d426c..4f975af299 100644 --- a/layout/forms/nsFileControlFrame.h +++ b/layout/forms/nsFileControlFrame.h @@ -33,7 +33,6 @@ public: nsIFrame* aPrevInFlow) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; NS_DECL_QUERYFRAME diff --git a/layout/forms/nsFormControlFrame.h b/layout/forms/nsFormControlFrame.h index fd3e95d936..41bb1d9e8f 100644 --- a/layout/forms/nsFormControlFrame.h +++ b/layout/forms/nsFormControlFrame.h @@ -40,7 +40,6 @@ public: // nsIFrame replacements virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override { DO_GLOBAL_REFLOW_COUNT_DSP("nsFormControlFrame"); DisplayBorderBackgroundOutline(aBuilder, aLists); diff --git a/layout/forms/nsGfxCheckboxControlFrame.cpp b/layout/forms/nsGfxCheckboxControlFrame.cpp index 061c92349f..80009eff2c 100644 --- a/layout/forms/nsGfxCheckboxControlFrame.cpp +++ b/layout/forms/nsGfxCheckboxControlFrame.cpp @@ -107,10 +107,9 @@ nsGfxCheckboxControlFrame::AccessibleType() //------------------------------------------------------------ void nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsFormControlFrame::BuildDisplayList(aBuilder, aLists); // Get current checked state through content model. if ((!IsChecked() && !IsIndeterminate()) || !IsVisibleForPainting(aBuilder)) diff --git a/layout/forms/nsGfxCheckboxControlFrame.h b/layout/forms/nsGfxCheckboxControlFrame.h index 70b8d8d6a7..9234b50577 100644 --- a/layout/forms/nsGfxCheckboxControlFrame.h +++ b/layout/forms/nsGfxCheckboxControlFrame.h @@ -23,7 +23,6 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; #ifdef ACCESSIBILITY diff --git a/layout/forms/nsGfxRadioControlFrame.cpp b/layout/forms/nsGfxRadioControlFrame.cpp index e4a35a998a..9c1ec070b4 100644 --- a/layout/forms/nsGfxRadioControlFrame.cpp +++ b/layout/forms/nsGfxRadioControlFrame.cpp @@ -70,10 +70,9 @@ PaintCheckedRadioButton(nsIFrame* aFrame, void nsGfxRadioControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsFormControlFrame::BuildDisplayList(aBuilder, aLists); if (!IsVisibleForPainting(aBuilder)) return; diff --git a/layout/forms/nsGfxRadioControlFrame.h b/layout/forms/nsGfxRadioControlFrame.h index f91e6b94cc..dd268dec18 100644 --- a/layout/forms/nsGfxRadioControlFrame.h +++ b/layout/forms/nsGfxRadioControlFrame.h @@ -25,7 +25,6 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; }; diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp index 2e4fa9f67a..3289456f2c 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -97,7 +97,6 @@ nsHTMLButtonControlFrame::ShouldClipPaintingToBorderBox() void nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // Clip to our border area for event hit testing. @@ -116,7 +115,7 @@ nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, mRenderer.DisplayButton(aBuilder, aLists.BorderBackground(), &onTop); } - nsDisplayListCollection set; + nsDisplayListCollection set (aBuilder); // Do not allow the child subtree to receive events. if (!isForEventDelivery) { @@ -131,7 +130,7 @@ nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, clipState.ClipContainingBlockDescendants(rect, hasRadii ? radii : nullptr); } - BuildDisplayListForChild(aBuilder, mFrames.FirstChild(), aDirtyRect, set, + BuildDisplayListForChild(aBuilder, mFrames.FirstChild(), set, DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT); // That should put the display items in set.Content() } diff --git a/layout/forms/nsHTMLButtonControlFrame.h b/layout/forms/nsHTMLButtonControlFrame.h index 432afa12c0..8837daf74b 100644 --- a/layout/forms/nsHTMLButtonControlFrame.h +++ b/layout/forms/nsHTMLButtonControlFrame.h @@ -27,7 +27,6 @@ public: NS_DECL_FRAMEARENA_HELPERS virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override; diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index 58e81039f8..2233c59963 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -155,7 +155,6 @@ nsListControlFrame::DestroyFrom(nsIFrame* aDestructRoot) void nsListControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // We allow visibility:hidden <select>s to contain visible options. @@ -180,7 +179,7 @@ nsListControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, mLastDropdownBackstopColor)); } - nsHTMLScrollFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsHTMLScrollFrame::BuildDisplayList(aBuilder, aLists); } /** diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h index 47f033a9bf..d8df9ebd67 100644 --- a/layout/forms/nsListControlFrame.h +++ b/layout/forms/nsListControlFrame.h @@ -81,7 +81,6 @@ 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 2445defd35..1e3519f0e7 100644 --- a/layout/forms/nsProgressFrame.cpp +++ b/layout/forms/nsProgressFrame.cpp @@ -101,10 +101,9 @@ NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) void nsProgressFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); + BuildDisplayListForInline(aBuilder, aLists); } void diff --git a/layout/forms/nsProgressFrame.h b/layout/forms/nsProgressFrame.h index 01465ff7c9..9cc72612f5 100644 --- a/layout/forms/nsProgressFrame.h +++ b/layout/forms/nsProgressFrame.h @@ -32,7 +32,6 @@ 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 7590da066e..9370acb87b 100644 --- a/layout/forms/nsRangeFrame.cpp +++ b/layout/forms/nsRangeFrame.cpp @@ -259,7 +259,6 @@ nsDisplayRangeFocusRing::Paint(nsDisplayListBuilder* aBuilder, void nsRangeFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (IsThemed()) { @@ -274,10 +273,10 @@ nsRangeFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* thumb = mThumbDiv->GetPrimaryFrame(); if (thumb) { nsDisplayListSet set(aLists, aLists.Content()); - BuildDisplayListForChild(aBuilder, thumb, aDirtyRect, set, DISPLAY_CHILD_INLINE); + BuildDisplayListForChild(aBuilder, thumb, set, DISPLAY_CHILD_INLINE); } } else { - BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); + BuildDisplayListForInline(aBuilder, aLists); } // Draw a focus outline if appropriate: diff --git a/layout/forms/nsRangeFrame.h b/layout/forms/nsRangeFrame.h index 8a2d34a40e..b913b30021 100644 --- a/layout/forms/nsRangeFrame.h +++ b/layout/forms/nsRangeFrame.h @@ -43,7 +43,6 @@ 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 dd613ae9fd..167a0d98b9 100644 --- a/layout/forms/nsSelectsAreaFrame.cpp +++ b/layout/forms/nsSelectsAreaFrame.cpp @@ -126,16 +126,15 @@ public: void nsSelectsAreaFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!aBuilder->IsForEventDelivery()) { - BuildDisplayListInternal(aBuilder, aDirtyRect, aLists); + BuildDisplayListInternal(aBuilder, aLists); return; } - nsDisplayListCollection set; - BuildDisplayListInternal(aBuilder, aDirtyRect, set); + nsDisplayListCollection set (aBuilder); + BuildDisplayListInternal(aBuilder, set); nsOptionEventGrabberWrapper wrapper; wrapper.WrapLists(aBuilder, this, set, aLists); @@ -143,10 +142,9 @@ nsSelectsAreaFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, void nsSelectsAreaFrame::BuildDisplayListInternal(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsBlockFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsBlockFrame::BuildDisplayList(aBuilder, aLists); nsListControlFrame* listFrame = GetEnclosingListFrame(this); if (listFrame && listFrame->IsFocused()) { diff --git a/layout/forms/nsSelectsAreaFrame.h b/layout/forms/nsSelectsAreaFrame.h index 3aac8a837d..9b0a5b7235 100644 --- a/layout/forms/nsSelectsAreaFrame.h +++ b/layout/forms/nsSelectsAreaFrame.h @@ -18,11 +18,9 @@ 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 f8fdf3420a..0f35e02e99 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -1433,7 +1433,6 @@ nsTextControlFrame::PeekOffset(nsPeekOffsetStruct *aPos) void nsTextControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { /* @@ -1461,7 +1460,7 @@ nsTextControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // placeholder has to be visible. if (kid->GetContent() != txtCtrl->GetPlaceholderNode() || txtCtrl->GetPlaceholderVisibility()) { - BuildDisplayListForChild(aBuilder, kid, aDirtyRect, set, 0); + BuildDisplayListForChild(aBuilder, kid, set, 0); } kid = kid->GetNextSibling(); } diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index 7fa39c5fb9..620cc92b98 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -127,7 +127,6 @@ 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 687c5b2e36..ae847f460c 100644 --- a/layout/generic/nsBackdropFrame.cpp +++ b/layout/generic/nsBackdropFrame.cpp @@ -39,7 +39,6 @@ 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 74d366befe..f3159da31a 100644 --- a/layout/generic/nsBackdropFrame.h +++ b/layout/generic/nsBackdropFrame.h @@ -27,7 +27,6 @@ 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 a37bfc06bd..93de79cef8 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -6527,13 +6527,14 @@ static void DebugOutputDrawLine(int32_t aDepth, nsLineBox* aLine, bool aDrawn) { static void DisplayLine(nsDisplayListBuilder* aBuilder, const nsRect& aLineArea, - const nsRect& aDirtyRect, nsBlockFrame::LineIterator& aLine, + 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(aDirtyRect); + bool intersect = aLineArea.Intersects(aBuilder->GetDirtyRect()); + bool visible = aLineArea.Intersects(aBuilder->GetVisibleRect()); #ifdef DEBUG if (nsBlockFrame::gLamePaintMetrics) { aDrawnLines++; @@ -6549,14 +6550,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) && + if (!intersect && !aBuilder->ShouldDescendIntoFrame(aFrame, visible) && !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; + nsDisplayListCollection collection(aBuilder); // Block-level child backgrounds go on the blockBorderBackgrounds list ... // Inline-level child backgrounds go on the regular child content list. @@ -6568,8 +6569,7 @@ DisplayLine(nsDisplayListBuilder* aBuilder, const nsRect& aLineArea, nsIFrame* kid = aLine->mFirstChild; int32_t n = aLine->GetChildCount(); while (--n >= 0) { - aFrame->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, - childLists, flags); + aFrame->BuildDisplayListForChild(aBuilder, kid, 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, - aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height, + dirty.x, dirty.y, dirty.width, dirty.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, aDirtyRect, aLists); + DisplayOverflowContainers(aBuilder, aLists); for (nsIFrame* f : mFloats) { if (f->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT) - BuildDisplayListForChild(aBuilder, f, aDirtyRect, aLists); + BuildDisplayListForChild(aBuilder, f, aLists); } } - aBuilder->MarkFramesForDisplayList(this, mFloats, aDirtyRect); + aBuilder->MarkFramesForDisplayList(this, mFloats); // 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; + nsDisplayListCollection linesDisplayListCollection(aBuilder); // 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) ? - nullptr : GetFirstLineContaining(aDirtyRect.y); + nsLineBox* cursor = (aBuilder->ShouldDescendIntoFrame(this, true)) ? + nullptr : GetFirstLineContaining(aBuilder->GetDirtyRect().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 >= aDirtyRect.YMost()) { + if (lineArea.y >= aBuilder->GetDirtyRect().YMost()) { break; } - DisplayLine(aBuilder, lineArea, aDirtyRect, line, depth, drawnLines, + DisplayLine(aBuilder, lineArea, 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, aDirtyRect, line, depth, drawnLines, + DisplayLine(aBuilder, lineArea, 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, aDirtyRect, aLists); + BuildDisplayListForChild(aBuilder, bullet, aLists); } #ifdef DEBUG diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index f515cc26f3..4775fa6264 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -139,7 +139,6 @@ 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 f6595e8f6d..db9a70aff6 100644 --- a/layout/generic/nsBulletFrame.cpp +++ b/layout/generic/nsBulletFrame.cpp @@ -274,7 +274,6 @@ 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 e35ed09237..30f4e23cd4 100644 --- a/layout/generic/nsBulletFrame.h +++ b/layout/generic/nsBulletFrame.h @@ -68,7 +68,6 @@ 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 1a8812fb75..31baa040c1 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -410,11 +410,10 @@ public: void nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (GetPrevInFlow()) { - DisplayOverflowContainers(aBuilder, aDirtyRect, aLists); + DisplayOverflowContainers(aBuilder, aLists); } // Force a background to be shown. We may have a background propagated to us, @@ -488,7 +487,7 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, for (nsIFrame* kid : PrincipalChildList()) { // Put our child into its own pseudo-stack. - BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); + BuildDisplayListForChild(aBuilder, kid, aLists); } #ifdef DEBUG_CANVAS_FOCUS @@ -504,7 +503,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, - aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); + dirty.x, dirty.y, dirty.width, dirty.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 8bd9dbf79e..8c59f18c0a 100644 --- a/layout/generic/nsCanvasFrame.h +++ b/layout/generic/nsCanvasFrame.h @@ -107,7 +107,6 @@ 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 6ea15d4d2f..90d425ccf4 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -1115,7 +1115,6 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext, void nsColumnSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DisplayBorderBackgroundOutline(aBuilder, aLists); @@ -1128,7 +1127,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(), aDirtyRect, aLists); + BuildDisplayListForChild(aBuilder, e.get(), aLists); } } diff --git a/layout/generic/nsColumnSetFrame.h b/layout/generic/nsColumnSetFrame.h index db44183d62..4195742c26 100644 --- a/layout/generic/nsColumnSetFrame.h +++ b/layout/generic/nsColumnSetFrame.h @@ -67,7 +67,6 @@ 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 afc4ed96f4..594dc4a8b7 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -329,17 +329,15 @@ nsContainerFrame::GetChildLists(nsTArray<ChildList>* aLists) const void nsContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DisplayBorderBackgroundOutline(aBuilder, aLists); - BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists); + BuildDisplayListForNonBlockChildren(aBuilder, aLists); } void nsContainerFrame::BuildDisplayListForNonBlockChildren(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists, uint32_t aFlags) { @@ -348,7 +346,7 @@ nsContainerFrame::BuildDisplayListForNonBlockChildren(nsDisplayListBuilder* aB nsDisplayListSet set(aLists, aLists.Content()); // The children should be in content order while (kid) { - BuildDisplayListForChild(aBuilder, kid, aDirtyRect, set, aFlags); + BuildDisplayListForChild(aBuilder, kid, set, aFlags); kid = kid->GetNextSibling(); } } @@ -1336,13 +1334,12 @@ 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, aDirtyRect, aLists); + BuildDisplayListForChild(aBuilder, frame, aLists); } } } diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h index ddf993d91c..e3cc54b0b0 100644 --- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -437,7 +437,6 @@ public: * Add overflow containers to the display list */ void DisplayOverflowContainers(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists); /** @@ -450,7 +449,6 @@ public: * to emulate what nsContainerFrame::Paint did. */ virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; static void PlaceFrameView(nsIFrame* aFrame) @@ -576,7 +574,6 @@ protected: * display items) go into the Content() list. */ void BuildDisplayListForNonBlockChildren(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists, uint32_t aFlags = 0); @@ -585,11 +582,9 @@ protected: * Intended as a convenience for derived classes. */ void BuildDisplayListForInline(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DisplayBorderBackgroundOutline(aBuilder, aLists); - BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists, - DISPLAY_CHILD_INLINE); + BuildDisplayListForNonBlockChildren(aBuilder, aLists, DISPLAY_CHILD_INLINE); } diff --git a/layout/generic/nsFirstLetterFrame.cpp b/layout/generic/nsFirstLetterFrame.cpp index 980e1e9bed..426e3caa7b 100644 --- a/layout/generic/nsFirstLetterFrame.cpp +++ b/layout/generic/nsFirstLetterFrame.cpp @@ -50,10 +50,9 @@ nsFirstLetterFrame::GetType() const void nsFirstLetterFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); + BuildDisplayListForInline(aBuilder, aLists); } void diff --git a/layout/generic/nsFirstLetterFrame.h b/layout/generic/nsFirstLetterFrame.h index 40e4ef0cf4..c8d416a850 100644 --- a/layout/generic/nsFirstLetterFrame.h +++ b/layout/generic/nsFirstLetterFrame.h @@ -20,7 +20,6 @@ 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 94bce1e7ac..69200117b0 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -2433,7 +2433,6 @@ 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 @@ -2452,7 +2451,7 @@ nsFlexContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // the BlockBorderBackgrounds list. nsDisplayListSet childLists(aLists, aLists.BlockBorderBackgrounds()); for (nsIFrame* childFrame : mFrames) { - BuildDisplayListForChild(aBuilder, childFrame, aDirtyRect, childLists, + BuildDisplayListForChild(aBuilder, childFrame, childLists, GetDisplayFlagsForFlexItem(childFrame)); } } diff --git a/layout/generic/nsFlexContainerFrame.h b/layout/generic/nsFlexContainerFrame.h index 459ae8e20f..ac2cc72f68 100644 --- a/layout/generic/nsFlexContainerFrame.h +++ b/layout/generic/nsFlexContainerFrame.h @@ -64,7 +64,6 @@ 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 8d4ea87540..ab264dd767 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1794,6 +1794,13 @@ 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; } @@ -1814,7 +1821,7 @@ nsFrame::DisplayOutline(nsDisplayListBuilder* aBuilder, void nsIFrame::DisplayCaret(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, nsDisplayList* aList) + nsDisplayList* aList) { if (!IsVisibleForPainting(aBuilder)) return; @@ -1840,7 +1847,9 @@ nsFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder, if (aBuilder->IsForEventDelivery() || aForceBackground || !StyleBackground()->IsTransparent() || StyleDisplay()->mAppearance) { return nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, this, GetRectRelativeToSelf(), aLists.BorderBackground()); + aBuilder, this, + GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(this), + aLists.BorderBackground()); } return false; } @@ -1873,7 +1882,9 @@ nsFrame::DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder, // If there's a themed background, we should not create a border item. // It won't be rendered. - if (!bgIsThemed && StyleBorder()->HasBorder()) { + // Don't paint borders for tables here, since they paint them in a different + // order. + if (!bgIsThemed && StyleBorder()->HasBorder() && GetType() != nsGkAtoms::tableFrame) { aLists.BorderBackground()->AppendNewToTop(new (aBuilder) nsDisplayBorder(aBuilder, this)); } @@ -2073,13 +2084,12 @@ 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, - aDirtyRect, Matrix4x4(), aIndex); + aBuilder->GetDirtyRect(), Matrix4x4(), aIndex); sepIdItem->SetNoExtendContext(); aTarget->AppendToTop(sepIdItem); } @@ -2087,7 +2097,6 @@ 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; @@ -2131,13 +2140,14 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, autoPreserves3DContext.emplace(aBuilder); // Save dirty rect on the builder to avoid being distorted for // multiple transforms along the chain. - aBuilder->SetPreserves3DDirtyRect(aDirtyRect); + aBuilder->SavePreserves3DRects(); } // For preserves3d, use the dirty rect already installed on the // builder, since aDirtyRect maybe distorted for transforms along // the chain. - nsRect dirtyRect = aDirtyRect; + nsRect visibleRect = aBuilder->GetVisibleRect(); + nsRect dirtyRect = aBuilder->GetDirtyRect(); bool inTransform = aBuilder->IsInTransform(); bool isTransformed = IsTransformed(); @@ -2148,7 +2158,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, AutoSaveRestoreContainsBlendMode autoRestoreBlendMode(*aBuilder); aBuilder->SetContainsBlendMode(false); - nsRect dirtyRectOutsideTransform = dirtyRect; + nsRect visibleRectOutsideTransform = visibleRect; if (isTransformed) { const nsRect overflow = GetVisualOverflowRectRelativeToSelf(); if (nsDisplayTransform::ShouldPrerenderTransformedContent(aBuilder, @@ -2162,17 +2172,19 @@ 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->GetPreserves3DDirtyRect(this); + dirtyRect = aBuilder->GetPreserves3DRects(&visibleRect); } 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; @@ -2181,11 +2193,13 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, bool usingMask = nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(this); bool usingSVGEffects = usingFilter || usingMask; - nsRect dirtyRectOutsideSVGEffects = dirtyRect; + nsRect visibleRectOutsideSVGEffects = visibleRect; nsDisplayList hoistedScrollInfoItemsStorage; if (usingSVGEffects) { dirtyRect = nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, dirtyRect); + visibleRect = + nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, visibleRect); aBuilder->EnterSVGEffectsContents(&hoistedScrollInfoItemsStorage); } @@ -2205,7 +2219,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, bool useFixedPosition = nsLayoutUtils::IsFixedPosFrameInDisplayPort(this); nsDisplayListBuilder::AutoBuildingDisplayList - buildingDisplayList(aBuilder, this, dirtyRect, true); + buildingDisplayList(aBuilder, this, visibleRect, 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. @@ -2270,7 +2284,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, clipState.EnterStackingContextContents(clearClip); - nsDisplayListCollection set; + nsDisplayListCollection set(aBuilder); { DisplayListClipState::AutoSaveRestore nestedClipState(aBuilder); nsDisplayListBuilder::AutoInTransformSetter @@ -2282,7 +2296,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, Maybe<nsRect> clipPropClip = GetClipPropClipRect(disp, effects, GetSize()); if (clipPropClip) { - dirtyRect.IntersectRect(dirtyRect, *clipPropClip); + aBuilder->IntersectDirtyRect(*clipPropClip); + aBuilder->IntersectVisibleRect(*clipPropClip); nestedClipState.ClipContentDescendants( *clipPropClip + aBuilder->ToReferenceFrame(this)); } @@ -2295,7 +2310,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, aBuilder->MarkPreserve3DFramesForDisplayList(this); } - MarkAbsoluteFramesForDisplayList(aBuilder, dirtyRect); + MarkAbsoluteFramesForDisplayList(aBuilder); nsDisplayLayerEventRegions* eventRegions = nullptr; if (aBuilder->IsBuildingLayerEventRegions()) { @@ -2304,7 +2319,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, aBuilder->SetLayerEventRegions(eventRegions); } aBuilder->AdjustWindowDraggingRegion(this); - BuildDisplayList(aBuilder, dirtyRect, set); + BuildDisplayList(aBuilder, set); if (eventRegions) { // If the event regions item ended up empty, throw it away rather than // adding it to the display list. @@ -2410,7 +2425,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, clipState.ExitStackingContextContents(&containerItemScrollClip); } // Revert to the post-filter dirty rect. - buildingDisplayList.SetDirtyRect(dirtyRectOutsideSVGEffects); + aBuilder->SetVisibleRect(visibleRectOutsideSVGEffects); // Skip all filter effects while generating glyph mask. if (usingFilter && !aBuilder->IsForGenerateGlyphMask()) { @@ -2443,7 +2458,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 && !resultList.IsEmpty()) { + if (useOpacity) { // 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. @@ -2465,7 +2480,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, * We also traverse into sublists created by nsDisplayWrapList, so that we find all the * correct children. */ - if (isTransformed && !resultList.IsEmpty() && extend3DContext) { + if (isTransformed && extend3DContext) { // Install dummy nsDisplayTransform as a leaf containing // descendants not participating this 3D rendering context. nsDisplayList nonparticipants; @@ -2475,8 +2490,7 @@ 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, dirtyRect, - &nonparticipants, &participants, index++); + WrapSeparatorTransform(aBuilder, this, &nonparticipants, &participants, index++); participants.AppendToTop(item); } else { // The frame of the item doesn't participate the current @@ -2489,19 +2503,18 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, nonparticipants.AppendToTop(item); } } - WrapSeparatorTransform(aBuilder, this, dirtyRect, - &nonparticipants, &participants, index++); + WrapSeparatorTransform(aBuilder, this, &nonparticipants, &participants, index++); resultList.AppendToTop(&participants); } - if (isTransformed && !resultList.IsEmpty()) { + if (isTransformed) { 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. - buildingDisplayList.SetDirtyRect(dirtyRectOutsideTransform); + aBuilder->SetVisibleRect(visibleRectOutsideTransform); // Revert to the outer reference frame and offset because all display // items we create from now on are outside the transform. nsPoint toOuterReferenceFrame; @@ -2514,10 +2527,10 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, GetOffsetToCrossDoc(outerReferenceFrame)); bool isFullyVisible = - dirtyRectOutsideSVGEffects.Contains(GetVisualOverflowRectRelativeToSelf()); + visibleRectOutsideSVGEffects.Contains(GetVisualOverflowRectRelativeToSelf()); nsDisplayTransform *transformItem = new (aBuilder) nsDisplayTransform(aBuilder, this, - &resultList, dirtyRect, 0, + &resultList, visibleRect, 0, isFullyVisible); resultList.AppendNewToTop(transformItem); @@ -2561,7 +2574,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, * not affected by foreground opacity (only background alpha). */ - if (useBlendMode && !resultList.IsEmpty()) { + if (useBlendMode) { DisplayListClipState::AutoSaveRestore mixBlendClipState(aBuilder); mixBlendClipState.Clear(); resultList.AppendNewToTop( @@ -2602,10 +2615,80 @@ 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, @@ -2638,12 +2721,16 @@ 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); @@ -2673,15 +2760,25 @@ 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"); @@ -2691,36 +2788,6 @@ 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(); @@ -2771,7 +2838,8 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, "Stacking contexts must also be pseudo-stacking-contexts"); nsDisplayListBuilder::AutoBuildingDisplayList - buildingForChild(aBuilder, child, dirty, pseudoStackingContext); + buildingForChild(aBuilder, child, visible, dirty, pseudoStackingContext); + DisplayListClipState::AutoClipMultiple clipState(aBuilder); CheckForApzAwareEventHandlers(aBuilder, child); @@ -2784,7 +2852,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, savedOutOfFlowData->mContainingBlockScrollClip); } else if (GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO && isPlaceholder) { - NS_ASSERTION(dirty.IsEmpty(), "should have empty dirty rect"); + NS_ASSERTION(visible.IsEmpty(), "should have empty visible 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. @@ -2820,18 +2888,19 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, // True stacking context. // For stacking contexts, BuildDisplayListForStackingContext handles // clipping and MarkAbsoluteFramesForDisplayList. - child->BuildDisplayListForStackingContext(aBuilder, dirty, &list); - aBuilder->DisplayCaret(child, dirty, &list); + child->BuildDisplayListForStackingContext(aBuilder, &list); + aBuilder->DisplayCaret(child, &list); } else { Maybe<nsRect> clipPropClip = child->GetClipPropClipRect(disp, effects, child->GetSize()); if (clipPropClip) { - dirty.IntersectRect(dirty, *clipPropClip); + aBuilder->IntersectVisibleRect(*clipPropClip); + aBuilder->IntersectDirtyRect(*clipPropClip); clipState.ClipContentDescendants( *clipPropClip + aBuilder->ToReferenceFrame(child)); } - child->MarkAbsoluteFramesForDisplayList(aBuilder, dirty); + child->MarkAbsoluteFramesForDisplayList(aBuilder); if (aBuilder->IsBuildingLayerEventRegions()) { // If this frame has a different animated geometry root than its parent, @@ -2863,8 +2932,8 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, // return early. aBuilder->AdjustWindowDraggingRegion(child); - child->BuildDisplayList(aBuilder, dirty, aLists); - aBuilder->DisplayCaret(child, dirty, aLists.Content()); + child->BuildDisplayList(aBuilder, aLists); + aBuilder->DisplayCaret(child, aLists.Content()); #ifdef DEBUG DisplayDebugBorders(aBuilder, child, aLists); #endif @@ -2875,10 +2944,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; + nsDisplayListCollection pseudoStack(aBuilder); aBuilder->AdjustWindowDraggingRegion(child); - child->BuildDisplayList(aBuilder, dirty, pseudoStack); - aBuilder->DisplayCaret(child, dirty, pseudoStack.Content()); + child->BuildDisplayList(aBuilder, pseudoStack); + aBuilder->DisplayCaret(child, pseudoStack.Content()); list.AppendToTop(pseudoStack.BorderBackground()); list.AppendToTop(pseudoStack.BlockBorderBackgrounds()); @@ -2928,11 +2997,10 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, } void -nsIFrame::MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect) +nsIFrame::MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder) { if (IsAbsoluteContainer()) { - aBuilder->MarkFramesForDisplayList(this, GetAbsoluteContainingBlock()->GetChildList(), aDirtyRect); + aBuilder->MarkFramesForDisplayList(this, GetAbsoluteContainingBlock()->GetChildList()); } } diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp index 87cb31fd06..4315b9b8af 100644 --- a/layout/generic/nsFrameSetFrame.cpp +++ b/layout/generic/nsFrameSetFrame.cpp @@ -100,7 +100,6 @@ public: nsIFrame::Cursor& aCursor) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Reflow(nsPresContext* aPresContext, @@ -149,7 +148,6 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; virtual void Reflow(nsPresContext* aPresContext, @@ -672,10 +670,9 @@ nsHTMLFramesetFrame::GetCursor(const nsPoint& aPoint, void nsHTMLFramesetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); + BuildDisplayListForInline(aBuilder, aLists); if (mDragger && aBuilder->IsForEventDelivery()) { aLists.Content()->AppendNewToTop( @@ -1429,7 +1426,6 @@ void nsDisplayFramesetBorder::Paint(nsDisplayListBuilder* aBuilder, void nsHTMLFramesetBorderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { aLists.Content()->AppendNewToTop( @@ -1640,7 +1636,6 @@ 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 ac6ab07ce6..b97d10c586 100644 --- a/layout/generic/nsFrameSetFrame.h +++ b/layout/generic/nsFrameSetFrame.h @@ -97,7 +97,6 @@ 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 3ed3b0bb33..fcd365edf6 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -3031,7 +3031,6 @@ struct HoveredStateComparator void ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists, bool aCreateLayer, bool aPositioned) @@ -3091,25 +3090,30 @@ 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() - : aDirtyRect; - nsDisplayListBuilder::AutoBuildingDisplayList - buildingForChild(aBuilder, scrollParts[i], - dirty + mOuter->GetOffsetTo(scrollParts[i]), true); + : aBuilder->GetDirtyRect(); // 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; - nsDisplayListBuilder::AutoCurrentScrollbarInfoSetter - infoSetter(aBuilder, scrollTargetId, flags, createLayer); - nsDisplayListCollection partList; - mOuter->BuildDisplayListForChild( - aBuilder, scrollParts[i], dirty, partList, - nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT); - + 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); + } if (createLayer) { appendToTopFlags |= APPEND_OWN_LAYER; } @@ -3117,11 +3121,19 @@ 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); + } } } @@ -3246,7 +3258,6 @@ ClipListsExceptCaret(nsDisplayListCollection* aLists, void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (aBuilder->IsForFrameVisibility()) { @@ -3283,12 +3294,15 @@ 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 dirtyRect = aDirtyRect; + nsRect visibleRect = aBuilder->GetVisibleRect(); + nsRect dirtyRect = aBuilder->GetDirtyRect(); if (!ignoringThisScrollFrame) { + visibleRect = visibleRect.Intersect(mScrollPort); dirtyRect = dirtyRect.Intersect(mScrollPort); } - Unused << DecideScrollableLayer(aBuilder, &dirtyRect, + bool usingDisplayPortInvalidRect = false; + Unused << DecideScrollableLayer(aBuilder, &visibleRect, &dirtyRect, /* aAllowCreateDisplayPort = */ !mIsRoot); bool usingDisplayPort = aBuilder->IsPaintingToWindow() && @@ -3300,6 +3314,7 @@ 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 @@ -3325,20 +3340,20 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, if (addScrollBars) { // Add classic scrollbars. - AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, - createLayersForScrollbars, false); + AppendScrollPartsTo(aBuilder, 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, - dirtyRect, aLists); + mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, aLists); if (addScrollBars) { // Add overlay scrollbars. - AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, - createLayersForScrollbars, true); + AppendScrollPartsTo(aBuilder, aLists, createLayersForScrollbars, true); } return; @@ -3376,8 +3391,7 @@ 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, aDirtyRect, aLists, - createLayersForScrollbars, false); + AppendScrollPartsTo(aBuilder, aLists, createLayersForScrollbars, false); const nsStyleDisplay* disp = mOuter->StyleDisplay(); if (disp && (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) { @@ -3414,7 +3428,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsIScrollableFrame* sf = do_QueryFrame(mOuter); MOZ_ASSERT(sf); - nsDisplayListCollection scrolledContent; + nsDisplayListCollection scrolledContent(aBuilder); { // 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 @@ -3501,12 +3515,15 @@ 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(dirtyRect); + scrolledRectClip = scrolledRectClip.Intersect(visibleRect); } scrolledRectClipState.ClipContainingBlockDescendants( scrolledRectClip + aBuilder->ToReferenceFrame(mOuter)); - mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, scrolledContent); + nsDisplayListBuilder::AutoBuildingDisplayList + building(aBuilder, mOuter, visibleRect, dirtyRect, aBuilder->IsAtRootOfPseudoStackingContext()); + + mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, scrolledContent); } if (contentBoxClipForNonCaretContent) { @@ -3558,7 +3575,8 @@ 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; - Unused << DecideScrollableLayer(aBuilder, ©OfDirtyRect, + nsRect copyOfVisibleRect = visibleRect; + Unused << DecideScrollableLayer(aBuilder, ©OfVisibleRect, ©OfDirtyRect, /* aAllowCreateDisplayPort = */ false); } } @@ -3593,13 +3611,14 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, } } // Now display overlay scrollbars and the resizer, if we have one. - AppendScrollPartsTo(aBuilder, aDirtyRect, scrolledContent, - createLayersForScrollbars, true); + AppendScrollPartsTo(aBuilder, scrolledContent, createLayersForScrollbars, true); + scrolledContent.MoveTo(aLists); } bool ScrollFrameHelper::DecideScrollableLayer(nsDisplayListBuilder* aBuilder, + nsRect* aVisibleRect, nsRect* aDirtyRect, bool aAllowCreateDisplayPort) { @@ -3615,16 +3634,16 @@ ScrollFrameHelper::DecideScrollableLayer(nsDisplayListBuilder* aBuilder, if (aAllowCreateDisplayPort) { nsLayoutUtils::MaybeCreateDisplayPort(*aBuilder, mOuter); - nsRect displayportBase = *aDirtyRect; + nsRect displayportBase = *aVisibleRect; 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 dirty rect restricted to + // Make the displayport base equal to the visible rect restricted to // the scrollport and the root composition bounds, relative to the // scrollport. - displayportBase = aDirtyRect->Intersect(mScrollPort); + displayportBase = aVisibleRect->Intersect(mScrollPort); // Only restrict to the root composition bounds if necessary, // as the required coordinate transformation is expensive. @@ -3687,12 +3706,15 @@ 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); } @@ -6175,3 +6197,4 @@ ScrollFrameHelper::UsesContainerScrolling() const } return false; } + diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index 81bbb358fc..8ad510d652 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -70,11 +70,9 @@ 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); @@ -404,6 +402,7 @@ public: ScrollSnapInfo GetScrollSnapInfo() const; bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder, + nsRect* aVisibleRect, nsRect* aDirtyRect, bool aAllowCreateDisplayPort); void NotifyApproximateFrameVisibilityUpdate(); @@ -687,9 +686,8 @@ public: } virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override { - mHelper.BuildDisplayList(aBuilder, aDirtyRect, aLists); + mHelper.BuildDisplayList(aBuilder, aLists); } bool TryLayout(ScrollReflowInput* aState, @@ -947,9 +945,10 @@ public: return mHelper.UsesContainerScrolling(); } virtual bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder, + nsRect* aVisibleRect, nsRect* aDirtyRect, bool aAllowCreateDisplayPort) override { - return mHelper.DecideScrollableLayer(aBuilder, aDirtyRect, aAllowCreateDisplayPort); + return mHelper.DecideScrollableLayer(aBuilder, aVisibleRect, aDirtyRect, aAllowCreateDisplayPort); } virtual void NotifyApproximateFrameVisibilityUpdate() override { mHelper.NotifyApproximateFrameVisibilityUpdate(); @@ -1105,9 +1104,8 @@ public: bool aClipAllDescendants); virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override { - mHelper.BuildDisplayList(aBuilder, aDirtyRect, aLists); + mHelper.BuildDisplayList(aBuilder, aLists); } // XXXldb Is this actually used? @@ -1453,9 +1451,10 @@ public: mHelper.SetScrollsClipOnUnscrolledOutOfFlow(); } virtual bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder, + nsRect* aVisibleRect, nsRect* aDirtyRect, bool aAllowCreateDisplayPort) override { - return mHelper.DecideScrollableLayer(aBuilder, aDirtyRect, aAllowCreateDisplayPort); + return mHelper.DecideScrollableLayer(aBuilder, aVisibleRect, aDirtyRect, aAllowCreateDisplayPort); } virtual void NotifyApproximateFrameVisibilityUpdate() override { mHelper.NotifyApproximateFrameVisibilityUpdate(); diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 959061e334..baa5544057 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -6643,12 +6643,11 @@ nsGridContainerFrame::GetType() const void nsGridContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DisplayBorderBackgroundOutline(aBuilder, aLists); if (GetPrevInFlow()) { - DisplayOverflowContainers(aBuilder, aDirtyRect, aLists); + DisplayOverflowContainers(aBuilder, aLists); } // Our children are all grid-level boxes, which behave the same as @@ -6662,8 +6661,7 @@ nsGridContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, GridItemCSSOrderIterator::eIncludeAll, order); for (; !iter.AtEnd(); iter.Next()) { nsIFrame* child = *iter; - BuildDisplayListForChild(aBuilder, child, aDirtyRect, aLists, - ::GetDisplayFlagsForGridItem(child)); + BuildDisplayListForChild(aBuilder, child, aLists, ::GetDisplayFlagsForGridItem(child)); } } diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h index 960558421b..c9163b95c6 100644 --- a/layout/generic/nsGridContainerFrame.h +++ b/layout/generic/nsGridContainerFrame.h @@ -98,7 +98,6 @@ 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 bad3a710f8..f86ec11369 100644 --- a/layout/generic/nsHTMLCanvasFrame.cpp +++ b/layout/generic/nsHTMLCanvasFrame.cpp @@ -367,7 +367,6 @@ 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 e4235deae9..b2d159627f 100644 --- a/layout/generic/nsHTMLCanvasFrame.h +++ b/layout/generic/nsHTMLCanvasFrame.h @@ -45,7 +45,6 @@ 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 93eb95099a..90de72d8db 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -1435,21 +1435,14 @@ 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); /** @@ -1483,11 +1476,8 @@ 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 { @@ -1506,7 +1496,6 @@ public: */ void BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, nsIFrame* aChild, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists, uint32_t aFlags = 0); @@ -3530,13 +3519,23 @@ 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, const nsRect& aDirtyRect); - + void MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder); + public: + bool ForceDescendIntoIfVisible() const { return mForceDescendIntoIfVisible; } + void SetForceDescendIntoIfVisible(bool aForce) { + mForceDescendIntoIfVisible = aForce; + } static void DestroyPaintedPresShellList(nsTArray<nsWeakPtr>* list) { list->Clear(); delete list; diff --git a/layout/generic/nsIScrollableFrame.h b/layout/generic/nsIScrollableFrame.h index b7e3caf46a..20a598452f 100644 --- a/layout/generic/nsIScrollableFrame.h +++ b/layout/generic/nsIScrollableFrame.h @@ -440,13 +440,16 @@ 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 - * displayport if there is one (ie the dirty rect that should be used). + * dirty rect inside the displayport (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 c64520f2ea..3423700505 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1730,7 +1730,6 @@ 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 5bc59c042f..fceecc43d6 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -82,7 +82,6 @@ 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 7e188c247e..fb77422a34 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -243,10 +243,9 @@ nsInlineFrame::StealFrame(nsIFrame* aChild) void nsInlineFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); + BuildDisplayListForInline(aBuilder, 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 36df6be93a..c1e0d7fe32 100644 --- a/layout/generic/nsInlineFrame.h +++ b/layout/generic/nsInlineFrame.h @@ -31,7 +31,6 @@ 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 407f9846d8..7087fb6cf3 100644 --- a/layout/generic/nsLeafFrame.h +++ b/layout/generic/nsLeafFrame.h @@ -24,7 +24,6 @@ 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 ae3af6ef77..7ec90c051b 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, - const nsRect& aDirtyRect, nsDisplayList* aList) + 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, aDirtyRect, &list); + aExtraPage->BuildDisplayListForStackingContext(aBuilder, &list); PruneDisplayListForExtraPage(aBuilder, aPage, aExtraPage, &list); aList->AppendToTop(&list); } @@ -517,10 +517,9 @@ protected: //------------------------------------------------------------------------------ void nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsDisplayListCollection set; + nsDisplayListCollection set(aBuilder); if (PresContext()->IsScreen()) { DisplayBorderBackgroundOutline(aBuilder, aLists); @@ -557,8 +556,11 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, clipState.Clear(); clipState.ClipContainingBlockDescendants(clipRect, nullptr); - nsRect dirtyRect = child->GetVisualOverflowRectRelativeToSelf(); - child->BuildDisplayListForStackingContext(aBuilder, dirtyRect, &content); + nsRect visibleRect = child->GetVisualOverflowRectRelativeToSelf(); + nsDisplayListBuilder::AutoBuildingDisplayList + buildingForChild(aBuilder, child, visibleRect, visibleRect, + aBuilder->IsAtRootOfPseudoStackingContext()); + child->BuildDisplayListForStackingContext(aBuilder, &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 @@ -569,15 +571,19 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // following placeholders to their out-of-flows) end up on the list. nsIFrame* page = child; while ((page = GetNextPage(page)) != nullptr) { - BuildDisplayListForExtraPage(aBuilder, this, page, - dirtyRect + child->GetOffsetTo(page), &content); + nsRect childVisible = visibleRect + child->GetOffsetTo(page); + + nsDisplayListBuilder::AutoBuildingDisplayList + buildingForChild(aBuilder, page, childVisible, childVisible, + aBuilder->IsAtRootOfPseudoStackingContext()); + BuildDisplayListForExtraPage(aBuilder, this, page, &content); } - // Invoke AutoBuildingDisplayList to ensure that the correct dirtyRect + // Invoke AutoBuildingDisplayList to ensure that the correct visibleRect // is used to compute the visible rect if AddCanvasBackgroundColorItem // creates a display item. nsDisplayListBuilder::AutoBuildingDisplayList - building(aBuilder, child, dirtyRect, true); + building(aBuilder, child, visibleRect, visibleRect, 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 aab2ac7b86..86516fe73d 100644 --- a/layout/generic/nsPageFrame.h +++ b/layout/generic/nsPageFrame.h @@ -29,7 +29,6 @@ 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 bd380a2d98..f234b2f2d6 100644 --- a/layout/generic/nsPlaceholderFrame.cpp +++ b/layout/generic/nsPlaceholderFrame.cpp @@ -240,7 +240,6 @@ 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 0c23a4f75c..11cb98592b 100644 --- a/layout/generic/nsPlaceholderFrame.h +++ b/layout/generic/nsPlaceholderFrame.h @@ -107,7 +107,6 @@ 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 34ed12d446..6e9e072e73 100644 --- a/layout/generic/nsPluginFrame.cpp +++ b/layout/generic/nsPluginFrame.cpp @@ -1182,7 +1182,6 @@ 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 5d9f9f4757..57db78acca 100644 --- a/layout/generic/nsPluginFrame.h +++ b/layout/generic/nsPluginFrame.h @@ -81,7 +81,6 @@ 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 b4a26ff333..2848cb6fc7 100644 --- a/layout/generic/nsRubyTextFrame.cpp +++ b/layout/generic/nsRubyTextFrame.cpp @@ -63,14 +63,13 @@ nsRubyTextFrame::GetFrameName(nsAString& aResult) const /* virtual */ void nsRubyTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (IsAutoHidden()) { return; } - nsRubyContentFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsRubyContentFrame::BuildDisplayList(aBuilder, aLists); } /* virtual */ void diff --git a/layout/generic/nsRubyTextFrame.h b/layout/generic/nsRubyTextFrame.h index 841b5081f5..83c24d49d7 100644 --- a/layout/generic/nsRubyTextFrame.h +++ b/layout/generic/nsRubyTextFrame.h @@ -34,7 +34,6 @@ 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 2e74afc3bf..6dcb6ccc1a 100644 --- a/layout/generic/nsSimplePageSequenceFrame.cpp +++ b/layout/generic/nsSimplePageSequenceFrame.cpp @@ -808,7 +808,6 @@ ComputePageSequenceTransform(nsIFrame* aFrame, float aAppUnitsPerPixel) void nsSimplePageSequenceFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DisplayBorderBackgroundOutline(aBuilder, aLists); @@ -822,13 +821,17 @@ nsSimplePageSequenceFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, clipState.Clear(); nsIFrame* child = PrincipalChildList().FirstChild(); - nsRect dirty = aDirtyRect; - dirty.ScaleInverseRoundOut(PresContext()->GetPrintPreviewScale()); + nsRect visible = aBuilder->GetVisibleRect(); + visible.ScaleInverseRoundOut(PresContext()->GetPrintPreviewScale()); while (child) { - if (child->GetVisualOverflowRectRelativeToParent().Intersects(dirty)) { - child->BuildDisplayListForStackingContext(aBuilder, - dirty - child->GetPosition(), &content); + if (child->GetVisualOverflowRectRelativeToParent().Intersects(visible)) { + nsDisplayListBuilder::AutoBuildingDisplayList + buildingForChild(aBuilder, child, + visible - child->GetPosition(), + visible - child->GetPosition(), + aBuilder->IsAtRootOfPseudoStackingContext()); + child->BuildDisplayListForStackingContext(aBuilder, &content); aBuilder->ResetMarkedFramesForDisplayList(); } child = child->GetNextSibling(); diff --git a/layout/generic/nsSimplePageSequenceFrame.h b/layout/generic/nsSimplePageSequenceFrame.h index c4e1e84b63..4981c67a8c 100644 --- a/layout/generic/nsSimplePageSequenceFrame.h +++ b/layout/generic/nsSimplePageSequenceFrame.h @@ -69,7 +69,6 @@ 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 47026b73ce..1c5ade5837 100644 --- a/layout/generic/nsSubDocumentFrame.cpp +++ b/layout/generic/nsSubDocumentFrame.cpp @@ -327,7 +327,6 @@ WrapBackgroundColorInOwnLayer(nsDisplayListBuilder* aBuilder, void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) @@ -343,7 +342,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, bool pointerEventsNone = StyleUserInterface()->mPointerEvents == NS_STYLE_POINTER_EVENTS_NONE; if (!aBuilder->IsForEventDelivery() || !pointerEventsNone) { - nsDisplayListCollection decorations; + nsDisplayListCollection decorations(aBuilder); DisplayBorderBackgroundOutline(aBuilder, decorations); if (rfp) { // Wrap background colors of <iframe>s with remote subdocuments in their @@ -368,7 +367,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } if (rfp) { - rfp->BuildDisplayList(aBuilder, this, aDirtyRect, aLists); + rfp->BuildDisplayList(aBuilder, this, aLists); return; } @@ -387,23 +386,28 @@ 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 - dirty = aDirtyRect + GetOffsetToCrossDoc(subdocRootFrame); + visible = aBuilder->GetVisibleRect() + GetOffsetToCrossDoc(subdocRootFrame); + dirty = aBuilder->GetDirtyRect() + 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 dirty rect doesn't get modified to the display port. - nsRect copy = dirty; + // Use a copy, so the rects don't get modified. + nsRect copyOfDirty = dirty; + nsRect copyOfVisible = visible; haveDisplayPort = rootScrollableFrame->DecideScrollableLayer(aBuilder, - ©, /* aAllowCreateDisplayPort = */ true); + ©OfVisible, ©OfDirty, + /* aAllowCreateDisplayPort = */ true); if (!gfxPrefs::LayoutUseContainersForRootFrames()) { haveDisplayPort = false; } @@ -417,7 +421,8 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, aBuilder->EnterPresShell(subdocRootFrame, pointerEventsNone); } else { - dirty = aDirtyRect; + visible = aBuilder->GetVisibleRect(); + dirty = aBuilder->GetDirtyRect(); } DisplayListClipState::AutoSaveRestore clipState(aBuilder); @@ -456,6 +461,13 @@ 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( @@ -466,7 +478,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, aBuilder->SetAncestorHasApzAwareEventHandler(false); subdocRootFrame-> - BuildDisplayListForStackingContext(aBuilder, dirty, &childItems); + BuildDisplayListForStackingContext(aBuilder, &childItems); } if (!aBuilder->IsForEventDelivery()) { @@ -485,15 +497,8 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // painted on the page itself. if (nsLayoutUtils::NeedsPrintPreviewBackground(presContext)) { presShell->AddPrintPreviewBackgroundItem( - *aBuilder, childItems, subdocRootFrame ? subdocRootFrame : this, - bounds); + *aBuilder, childItems, frame, 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 54f08d4fe6..93d908dcc5 100644 --- a/layout/generic/nsSubDocumentFrame.h +++ b/layout/generic/nsSubDocumentFrame.h @@ -79,7 +79,6 @@ 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 59ef020ce2..4bc5426267 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -4998,7 +4998,6 @@ 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 425dbb737c..43a4f5f1c5 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -65,7 +65,6 @@ 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 9f27684a7e..43383044b4 100644 --- a/layout/generic/nsVideoFrame.cpp +++ b/layout/generic/nsVideoFrame.cpp @@ -446,7 +446,6 @@ public: void nsVideoFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) @@ -482,14 +481,16 @@ 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->BuildDisplayListForStackingContext(aBuilder, - aDirtyRect - child->GetOffsetTo(this), - aLists.Content()); - } else if (child->GetType() == nsGkAtoms::boxFrame) { - child->BuildDisplayListForStackingContext(aBuilder, - aDirtyRect - child->GetOffsetTo(this), - aLists.Content()); + 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()); } } } diff --git a/layout/generic/nsVideoFrame.h b/layout/generic/nsVideoFrame.h index 36e9f9ac31..d624ae6b90 100644 --- a/layout/generic/nsVideoFrame.h +++ b/layout/generic/nsVideoFrame.h @@ -45,7 +45,6 @@ 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 39491a0edc..a7a8cd50c8 100644 --- a/layout/generic/nsViewportFrame.cpp +++ b/layout/generic/nsViewportFrame.cpp @@ -48,7 +48,6 @@ ViewportFrame::Init(nsIContent* aContent, void ViewportFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { PROFILER_LABEL("ViewportFrame", "BuildDisplayList", @@ -58,7 +57,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, aDirtyRect, aLists); + BuildDisplayListForChild(aBuilder, kid, aLists); } nsDisplayList topLayerList; @@ -98,19 +97,25 @@ 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, dirty, &list); + aFrame->BuildDisplayListForStackingContext(aBuilder, &list); aList->AppendToTop(&list); } diff --git a/layout/generic/nsViewportFrame.h b/layout/generic/nsViewportFrame.h index 062de40542..3e52630934 100644 --- a/layout/generic/nsViewportFrame.h +++ b/layout/generic/nsViewportFrame.h @@ -56,7 +56,6 @@ 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 8162d02d79..0f4aa11bb7 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -266,7 +266,6 @@ 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 274f8ff6df..f91cfe614c 100644 --- a/layout/ipc/RenderFrameParent.h +++ b/layout/ipc/RenderFrameParent.h @@ -64,7 +64,6 @@ 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 507e32b22d..4b02a52d8d 100644 --- a/layout/mathml/nsMathMLChar.cpp +++ b/layout/mathml/nsMathMLChar.cpp @@ -1992,7 +1992,8 @@ nsMathMLChar::Display(nsDisplayListBuilder* aBuilder, if (styleContext != parentContext && NS_GET_A(backg->mBackgroundColor) > 0) { nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, aForFrame, mRect, aLists.BorderBackground(), + aBuilder, aForFrame, mRect + aBuilder->ToReferenceFrame(aForFrame), + aLists.BorderBackground(), /* aAllowWillPaintBorderOptimization */ true, styleContext); } //else diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp index 93b631c9d0..8e22ba204d 100644 --- a/layout/mathml/nsMathMLContainerFrame.cpp +++ b/layout/mathml/nsMathMLContainerFrame.cpp @@ -618,7 +618,6 @@ 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 @@ -633,8 +632,7 @@ nsMathMLContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, DisplayBorderBackgroundOutline(aBuilder, aLists); - BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists, - DISPLAY_CHILD_INLINE); + BuildDisplayListForNonBlockChildren(aBuilder, 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 94ccf70d24..61c59a4fed 100644 --- a/layout/mathml/nsMathMLContainerFrame.h +++ b/layout/mathml/nsMathMLContainerFrame.h @@ -126,7 +126,6 @@ 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 2378d07632..11eb14d83f 100644 --- a/layout/mathml/nsMathMLSelectedFrame.cpp +++ b/layout/mathml/nsMathMLSelectedFrame.cpp @@ -71,14 +71,13 @@ 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, aDirtyRect, aLists); + nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists); return; } @@ -89,7 +88,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, aDirtyRect, set); + BuildDisplayListForChild(aBuilder, childFrame, set); } #if defined(DEBUG) && defined(SHOW_BOUNDING_BOX) diff --git a/layout/mathml/nsMathMLSelectedFrame.h b/layout/mathml/nsMathMLSelectedFrame.h index ad523a594d..8723518298 100644 --- a/layout/mathml/nsMathMLSelectedFrame.h +++ b/layout/mathml/nsMathMLSelectedFrame.h @@ -26,7 +26,6 @@ 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 64277a92e9..236a5ab07d 100644 --- a/layout/mathml/nsMathMLmencloseFrame.cpp +++ b/layout/mathml/nsMathMLmencloseFrame.cpp @@ -201,12 +201,11 @@ nsMathMLmencloseFrame::TransmitAutomaticData() void nsMathMLmencloseFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { ///////////// // paint the menclosed content - nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists); if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) return; diff --git a/layout/mathml/nsMathMLmencloseFrame.h b/layout/mathml/nsMathMLmencloseFrame.h index 82d73b2cfc..e9e7a2b0a3 100644 --- a/layout/mathml/nsMathMLmencloseFrame.h +++ b/layout/mathml/nsMathMLmencloseFrame.h @@ -70,7 +70,6 @@ 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 ca780e649b..5d66e541b9 100644 --- a/layout/mathml/nsMathMLmfencedFrame.cpp +++ b/layout/mathml/nsMathMLmfencedFrame.cpp @@ -161,12 +161,11 @@ nsMathMLmfencedFrame::CreateFencesAndSeparators(nsPresContext* aPresContext) void nsMathMLmfencedFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { ///////////// // display the content - nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists); //////////// // display fences and separators diff --git a/layout/mathml/nsMathMLmfencedFrame.h b/layout/mathml/nsMathMLmfencedFrame.h index 2d7535d0c5..472e5aed9b 100644 --- a/layout/mathml/nsMathMLmfencedFrame.h +++ b/layout/mathml/nsMathMLmfencedFrame.h @@ -41,7 +41,6 @@ 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 4e74faea2a..731cca7d0c 100644 --- a/layout/mathml/nsMathMLmfracFrame.cpp +++ b/layout/mathml/nsMathMLmfracFrame.cpp @@ -149,12 +149,11 @@ nsMathMLmfracFrame::CalcLineThickness(nsPresContext* aPresContext, void nsMathMLmfracFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { ///////////// // paint the numerator and denominator - nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists); ///////////// // paint the fraction line diff --git a/layout/mathml/nsMathMLmfracFrame.h b/layout/mathml/nsMathMLmfracFrame.h index 330a311803..8ced03694b 100644 --- a/layout/mathml/nsMathMLmfracFrame.h +++ b/layout/mathml/nsMathMLmfracFrame.h @@ -67,7 +67,6 @@ 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 591b46309a..3ef7b88d00 100644 --- a/layout/mathml/nsMathMLmoFrame.cpp +++ b/layout/mathml/nsMathMLmoFrame.cpp @@ -78,14 +78,13 @@ 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, aDirtyRect, aLists); + nsMathMLTokenFrame::BuildDisplayList(aBuilder, aLists); } else { DisplayBorderBackgroundOutline(aBuilder, aLists); diff --git a/layout/mathml/nsMathMLmoFrame.h b/layout/mathml/nsMathMLmoFrame.h index f25107a20b..15df62ac27 100644 --- a/layout/mathml/nsMathMLmoFrame.h +++ b/layout/mathml/nsMathMLmoFrame.h @@ -29,7 +29,6 @@ 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 4c81bde3d9..300adcb91c 100644 --- a/layout/mathml/nsMathMLmrootFrame.cpp +++ b/layout/mathml/nsMathMLmrootFrame.cpp @@ -77,12 +77,11 @@ nsMathMLmrootFrame::TransmitAutomaticData() void nsMathMLmrootFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { ///////////// // paint the content we are square-rooting - nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists); ///////////// // paint the sqrt symbol diff --git a/layout/mathml/nsMathMLmrootFrame.h b/layout/mathml/nsMathMLmrootFrame.h index 0996af26b8..ddf6f89a6c 100644 --- a/layout/mathml/nsMathMLmrootFrame.h +++ b/layout/mathml/nsMathMLmrootFrame.h @@ -51,7 +51,6 @@ 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 new file mode 100644 index 0000000000..a2bd3213d6 --- /dev/null +++ b/layout/reftests/position-relative/1409114-1-ref.html @@ -0,0 +1,12 @@ +<!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 new file mode 100644 index 0000000000..988ecab1ef --- /dev/null +++ b/layout/reftests/position-relative/1409114-1.html @@ -0,0 +1,11 @@ +<!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 new file mode 100644 index 0000000000..6d5e3c617a --- /dev/null +++ b/layout/reftests/position-relative/1409114-2.html @@ -0,0 +1,13 @@ +<!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 new file mode 100644 index 0000000000..cfd01561d6 --- /dev/null +++ b/layout/reftests/position-relative/1409114-3.html @@ -0,0 +1,13 @@ +<!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 880a38e8d5..495588ab79 100644 --- a/layout/reftests/position-relative/reftest.list +++ b/layout/reftests/position-relative/reftest.list @@ -7,3 +7,6 @@ == 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 bb03f15257..9ec969236a 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,8 +10,6 @@ html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } body { padding: 15px; } - .o { opacity: 0.5; } - /* table { margin: 0px 3px 2px 4px; @@ -55,8 +53,8 @@ </head> <body> -<div class="color o"></div> -<div class="imagetl o"></div> +<div class="color"></div> +<div class="imagetl"></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 7b7df902e5..82795ef8be 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,8 +10,6 @@ html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } body { padding: 15px; } - .o { opacity: 0.5; } - /* table { margin: 0px 3px 2px 4px; @@ -55,8 +53,8 @@ </head> <body> -<div class="color o"></div> -<div class="imagetl o"></div> +<div class="color"></div> +<div class="imagetl"></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 ad6ca24539..6985dae64d 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,8 +10,6 @@ html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } body { padding: 15px; } - .o { opacity: 0.5; } - /* table { margin: 0px 3px 2px 4px; @@ -65,8 +63,8 @@ <body> <div class="color"></div> -<div class="imagetl o"></div> -<div class="imagebr o"></div> +<div class="imagetl"></div> +<div class="imagebr"></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 e00193dc3a..a6629347d2 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,8 +10,6 @@ html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } body { padding: 15px; } - .o { opacity: 0.5; } - /* table { margin: 0px 3px 2px 4px; @@ -65,8 +63,8 @@ <body> <div class="color"></div> -<div class="imagetl o"></div> -<div class="imagebr o"></div> +<div class="imagetl"></div> +<div class="imagebr"></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 68dc43e956..727a7de08d 100644 --- a/layout/reftests/table-background/reftest.list +++ b/layout/reftests/table-background/reftest.list @@ -40,23 +40,30 @@ 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,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 +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 != 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,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 +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 == 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 new file mode 100644 index 0000000000..06b6c3e065 --- /dev/null +++ b/layout/reftests/table-background/table-col-overlapping-ref.html @@ -0,0 +1,28 @@ +<!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 new file mode 100644 index 0000000000..c50f1654fa --- /dev/null +++ b/layout/reftests/table-background/table-col-overlapping.html @@ -0,0 +1,28 @@ +<!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 new file mode 100644 index 0000000000..12a7bc45f6 --- /dev/null +++ b/layout/reftests/table-background/table-col-span-1-ref.html @@ -0,0 +1,15 @@ +<!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 new file mode 100644 index 0000000000..7fd21ce06c --- /dev/null +++ b/layout/reftests/table-background/table-col-span-1.html @@ -0,0 +1,15 @@ +<!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 083c0f27d1..bc92585273 100644 --- a/layout/svg/SVGFEUnstyledLeafFrame.cpp +++ b/layout/svg/SVGFEUnstyledLeafFrame.cpp @@ -25,7 +25,6 @@ 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 6ba267ee89..bfe7333ee9 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -3161,7 +3161,6 @@ 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 9c672c6a53..508ed17245 100644 --- a/layout/svg/SVGTextFrame.h +++ b/layout/svg/SVGTextFrame.h @@ -224,7 +224,6 @@ 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 42a8d16ffd..046ebb169d 100644 --- a/layout/svg/nsSVGClipPathFrame.h +++ b/layout/svg/nsSVGClipPathFrame.h @@ -37,7 +37,6 @@ 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 750dcc9da0..acb726f7a2 100644 --- a/layout/svg/nsSVGContainerFrame.cpp +++ b/layout/svg/nsSVGContainerFrame.cpp @@ -140,7 +140,6 @@ 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 @@ -149,7 +148,7 @@ nsSVGDisplayContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, return; } DisplayOutline(aBuilder, aLists); - return BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists); + return BuildDisplayListForNonBlockChildren(aBuilder, aLists); } void diff --git a/layout/svg/nsSVGContainerFrame.h b/layout/svg/nsSVGContainerFrame.h index f4a01e1559..8a6cdd7ce9 100644 --- a/layout/svg/nsSVGContainerFrame.h +++ b/layout/svg/nsSVGContainerFrame.h @@ -83,7 +83,6 @@ public: } virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override {} virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override; @@ -133,7 +132,6 @@ 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 223c787f6e..f2f3215224 100644 --- a/layout/svg/nsSVGFilterFrame.h +++ b/layout/svg/nsSVGFilterFrame.h @@ -45,7 +45,6 @@ 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 afa5912d2c..f8584a4f1e 100644 --- a/layout/svg/nsSVGForeignObjectFrame.cpp +++ b/layout/svg/nsSVGForeignObjectFrame.cpp @@ -163,14 +163,13 @@ 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, aDirtyRect, aLists); + BuildDisplayListForNonBlockChildren(aBuilder, aLists); } bool diff --git a/layout/svg/nsSVGForeignObjectFrame.h b/layout/svg/nsSVGForeignObjectFrame.h index 57df6d5b5b..4bb94bdab4 100644 --- a/layout/svg/nsSVGForeignObjectFrame.h +++ b/layout/svg/nsSVGForeignObjectFrame.h @@ -47,7 +47,6 @@ 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 22ac017090..187aed1403 100644 --- a/layout/svg/nsSVGMarkerFrame.h +++ b/layout/svg/nsSVGMarkerFrame.h @@ -52,7 +52,6 @@ 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 380306a481..2a9486fa58 100644 --- a/layout/svg/nsSVGMaskFrame.h +++ b/layout/svg/nsSVGMaskFrame.h @@ -73,7 +73,6 @@ 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 b1ee54eb95..7efdec5e53 100644 --- a/layout/svg/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/nsSVGOuterSVGFrame.cpp @@ -731,7 +731,6 @@ nsSVGOuterSVGFrame::AttributeChanged(int32_t aNameSpaceID, void nsSVGOuterSVGFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (GetStateBits() & NS_FRAME_IS_NONDISPLAY) { @@ -755,7 +754,7 @@ nsSVGOuterSVGFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsDisplayList *contentList = aLists.Content(); nsDisplayListSet set(contentList, contentList, contentList, contentList, contentList, contentList); - BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, set); + BuildDisplayListForNonBlockChildren(aBuilder, 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 6d29234acc..ee59b7d1c5 100644 --- a/layout/svg/nsSVGOuterSVGFrame.h +++ b/layout/svg/nsSVGOuterSVGFrame.h @@ -66,7 +66,6 @@ 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 6b568f8727..ff2c6f8b47 100644 --- a/layout/svg/nsSVGPaintServerFrame.h +++ b/layout/svg/nsSVGPaintServerFrame.h @@ -58,7 +58,6 @@ 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 32cd0e4965..50eec2b922 100644 --- a/layout/svg/nsSVGPathGeometryFrame.cpp +++ b/layout/svg/nsSVGPathGeometryFrame.cpp @@ -259,7 +259,6 @@ 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 6b7c75d97c..d2d63f0439 100644 --- a/layout/svg/nsSVGPathGeometryFrame.h +++ b/layout/svg/nsSVGPathGeometryFrame.h @@ -88,7 +88,6 @@ 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 1b75fa1028..28875ad253 100644 --- a/layout/svg/nsSVGStopFrame.cpp +++ b/layout/svg/nsSVGStopFrame.cpp @@ -36,7 +36,6 @@ 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 26e77071b9..1eef37eb09 100644 --- a/layout/svg/nsSVGSwitchFrame.cpp +++ b/layout/svg/nsSVGSwitchFrame.cpp @@ -44,7 +44,6 @@ public: #endif virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; // nsISVGChildFrame interface: @@ -93,12 +92,11 @@ nsSVGSwitchFrame::GetType() const void nsSVGSwitchFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { nsIFrame* kid = GetActiveChildFrame(); if (kid) { - BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); + BuildDisplayListForChild(aBuilder, kid, aLists); } } diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 8b811df1e3..9c715d999b 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -450,7 +450,6 @@ nsTableCellFrame::ShouldPaintBackground(nsDisplayListBuilder* aBuilder) void nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { DO_GLOBAL_REFLOW_COUNT_DSP("nsTableCellFrame"); @@ -462,14 +461,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, - GetRectRelativeToSelf(), - aLists.BorderBackground()); + nsDisplayBackgroundImage::AppendBackgroundItemsToTop( + aBuilder, this, bgRect, aLists.BorderBackground()); } // display inset box-shadows if we need to. @@ -488,16 +487,49 @@ 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. @@ -506,7 +538,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, aDirtyRect, aLists); + BuildDisplayListForChild(aBuilder, kid, aLists); } nsIFrame::LogicalSides diff --git a/layout/tables/nsTableCellFrame.h b/layout/tables/nsTableCellFrame.h index f626a45b0c..a822e309da 100644 --- a/layout/tables/nsTableCellFrame.h +++ b/layout/tables/nsTableCellFrame.h @@ -104,7 +104,6 @@ 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 54b03522b0..6723f4701a 100644 --- a/layout/tables/nsTableColFrame.cpp +++ b/layout/tables/nsTableColFrame.cpp @@ -110,10 +110,15 @@ nsTableColFrame::Reflow(nsPresContext* aPresContext, void nsTableColFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, 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"); } int32_t nsTableColFrame::GetSpan() diff --git a/layout/tables/nsTableColFrame.h b/layout/tables/nsTableColFrame.h index fb989061f7..ed6a843b67 100644 --- a/layout/tables/nsTableColFrame.h +++ b/layout/tables/nsTableColFrame.h @@ -60,7 +60,6 @@ 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 6ee7f0b242..be5b71bb24 100644 --- a/layout/tables/nsTableColGroupFrame.cpp +++ b/layout/tables/nsTableColGroupFrame.cpp @@ -385,10 +385,15 @@ nsTableColGroupFrame::Reflow(nsPresContext* aPresContext, void nsTableColGroupFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, 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"); } nsTableColFrame * nsTableColGroupFrame::GetFirstColumn() diff --git a/layout/tables/nsTableColGroupFrame.h b/layout/tables/nsTableColGroupFrame.h index b3dfb94e77..88ed67c2ad 100644 --- a/layout/tables/nsTableColGroupFrame.h +++ b/layout/tables/nsTableColGroupFrame.h @@ -44,7 +44,6 @@ 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 4257c9c579..32fe38b052 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1161,242 +1161,127 @@ nsDisplayTableBorderCollapse::Paint(nsDisplayListBuilder* aBuilder, static_cast<nsTableFrame*>(mFrame)->PaintBCBorders(*drawTarget, mVisibleRect - pt); } -/* 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); +static inline bool FrameHasBorder(nsIFrame* f) { + if (!f->StyleVisibility()->IsVisible()) { + return false; } - for (nsIFrame* kid : aFrame->PrincipalChildList()) { - aFrame->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); + if (f->StyleBorder()->HasBorder()) { + return true; } -} - -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); - } + return false; } -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()); +void nsTableFrame::CalcHasBCBorders() { + if (!IsBorderCollapse()) { + SetHasBCBorders(false); + 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); - } + if (FrameHasBorder(this)) { + 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); - } + // Check col and col group has borders. + for (nsIFrame* f : this->GetChildList(kColGroupList)) { + if (FrameHasBorder(f)) { + SetHasBCBorders(true); + return; } - } 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()); - 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; + nsTableColGroupFrame* colGroup = static_cast<nsTableColGroupFrame*>(f); + for (nsTableColFrame* col = colGroup->GetFirstColumn(); col; + col = col->GetNextCol()) { + if (FrameHasBorder(col)) { + SetHasBCBorders(true); + return; } - PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, aDirtyRect, colIdx, offset); } - } else if (isVisible) { - nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, - aFrame->GetRectRelativeToSelf(), - aLists.BorderBackground()); } - 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)); + // check row group, row and cell has borders. + RowGroupArray rowGroups; + OrderRowGroups(rowGroups); + for (nsTableRowGroupFrame* rowGroup : rowGroups) { + if (FrameHasBorder(rowGroup)) { + SetHasBCBorders(true); + return; } - } - aTraversal(aBuilder, aFrame, aDirtyRect, aLists); + for (nsTableRowFrame* row = rowGroup->GetFirstRow(); row; + row = row->GetNextRow()) { + if (FrameHasBorder(row)) { + 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)); + for (nsTableCellFrame* cell = row->GetFirstCell(); cell; + cell = cell->GetNextCell()) { + if (FrameHasBorder(cell)) { + SetHasBCBorders(true); + return; + } } } } - aFrame->DisplayOutline(aBuilder, aLists); + SetHasBCBorders(false); } // 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)); - DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists); + 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)); + } + } + } } nsMargin @@ -4101,6 +3986,7 @@ nsTableFrame::AddBCDamageArea(const TableArea& aValue) #endif SetNeedToCalcBCBorders(true); + SetNeedToCalcHasBCBorders(true); // Get the property BCPropertyData* value = GetOrCreateBCProperty(); if (value) { @@ -4141,6 +4027,7 @@ 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 a6b786402d..7fcdcb9d87 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -72,36 +72,59 @@ private: bool mDrawsBackground; }; -class nsAutoPushCurrentTableItem -{ -public: - nsAutoPushCurrentTableItem() : mBuilder(nullptr) {} +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(); + } - void Push(nsDisplayListBuilder* aBuilder, nsDisplayTableItem* aPushItem) - { - mBuilder = aBuilder; - mOldCurrentItem = aBuilder->GetCurrentTableItem(); - aBuilder->SetCurrentTableItem(aPushItem); -#ifdef DEBUG - mPushedItem = aPushItem; -#endif + ~nsDisplayTableBackgroundSet() { + mozilla::DebugOnly<nsDisplayTableBackgroundSet*> result = + mBuilder->SetTableBackgroundSet(mPrevTableBackgroundSet); + MOZ_ASSERT(result == this); } - ~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); + + /** + * 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()); } -private: + 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: nsDisplayListBuilder* mBuilder; - nsDisplayTableItem* mOldCurrentItem; -#ifdef DEBUG - nsDisplayTableItem* mPushedItem; -#endif + nsDisplayTableBackgroundSet* mPrevTableBackgroundSet; + + nsDisplayList mColGroupBackgrounds; + nsDisplayList mColBackgrounds; + + nsTArray<nsTableColFrame*> mColumns; + nsPoint mToReferenceFrame; + nsRect mDirtyRect; }; /* ============================================================================ */ @@ -229,29 +252,6 @@ 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,7 +268,6 @@ 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 @@ -761,6 +760,13 @@ 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 @@ -870,6 +876,8 @@ 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 @@ -965,6 +973,30 @@ 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 02b85a141f..18f11f876b 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -549,12 +549,66 @@ 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) { - nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, 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); + } } nsIFrame::LogicalSides diff --git a/layout/tables/nsTableRowFrame.h b/layout/tables/nsTableRowFrame.h index c53c81ff10..4b6dd2628c 100644 --- a/layout/tables/nsTableRowFrame.h +++ b/layout/tables/nsTableRowFrame.h @@ -79,9 +79,13 @@ 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 37f577f5ca..56ca394ded 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 nsRect& aDirtyRect, const nsDisplayListSet& aLists) + 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) ? - nullptr : f->GetFirstRowContaining(aDirtyRect.y, &overflowAbove); + nsIFrame* kid = aBuilder->ShouldDescendIntoFrame(f, true) ? + nullptr : f->GetFirstRowContaining(aBuilder->GetVisibleRect().y, &overflowAbove); if (kid) { // If we have a cursor, use it while (kid) { - if (kid->GetRect().y - overflowAbove >= aDirtyRect.YMost()) { + if (kid->GetRect().y - overflowAbove >= aBuilder->GetDirtyRect().YMost()) { break; } - f->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); + f->BuildDisplayListForChild(aBuilder, kid, 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, aDirtyRect, aLists); + f->BuildDisplayListForChild(aBuilder, kid, aLists); if (cursor) { if (!cursor->AppendFrame(kid)) { @@ -205,11 +205,45 @@ DisplayRows(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, void nsTableRowGroupFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, - aLists, DisplayRows); + 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); } nsIFrame::LogicalSides diff --git a/layout/tables/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h index 721d910465..eb9f6205e2 100644 --- a/layout/tables/nsTableRowGroupFrame.h +++ b/layout/tables/nsTableRowGroupFrame.h @@ -75,7 +75,6 @@ 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 da71375d5d..476024e96d 100644 --- a/layout/tables/nsTableWrapperFrame.cpp +++ b/layout/tables/nsTableWrapperFrame.cpp @@ -168,7 +168,6 @@ 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 @@ -177,16 +176,15 @@ 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, aDirtyRect, aLists); + BuildDisplayListForInnerTable(aBuilder, aLists); return; } - nsDisplayListCollection set; - BuildDisplayListForInnerTable(aBuilder, aDirtyRect, set); + nsDisplayListCollection set(aBuilder); + BuildDisplayListForInnerTable(aBuilder, set); nsDisplayListSet captionSet(set, set.BlockBorderBackgrounds()); - BuildDisplayListForChild(aBuilder, mCaptionFrames.FirstChild(), - aDirtyRect, captionSet); + BuildDisplayListForChild(aBuilder, mCaptionFrames.FirstChild(), captionSet); // Now we have to sort everything by content order, since the caption // may be somewhere inside the table @@ -200,7 +198,6 @@ 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 @@ -208,7 +205,7 @@ nsTableWrapperFrame::BuildDisplayListForInnerTable(nsDisplayListBuilder* aBuil nsIFrame* kid = mFrames.FirstChild(); // The children should be in content order while (kid) { - BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); + BuildDisplayListForChild(aBuilder, kid, aLists); kid = kid->GetNextSibling(); } } diff --git a/layout/tables/nsTableWrapperFrame.h b/layout/tables/nsTableWrapperFrame.h index 45d7c33e41..8095c7fc45 100644 --- a/layout/tables/nsTableWrapperFrame.h +++ b/layout/tables/nsTableWrapperFrame.h @@ -59,11 +59,9 @@ 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 9ca351d945..9982a39f7b 100644 --- a/layout/xul/nsBoxFrame.cpp +++ b/layout/xul/nsBoxFrame.cpp @@ -1310,7 +1310,6 @@ PaintXULDebugBackground(nsIFrame* aFrame, DrawTarget* aDrawTarget, void nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { bool forceLayer = false; @@ -1329,7 +1328,7 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } } - nsDisplayListCollection tempLists; + nsDisplayListCollection tempLists (aBuilder); const nsDisplayListSet& destination = forceLayer ? tempLists : aLists; DisplayBorderBackgroundOutline(aBuilder, destination); @@ -1344,7 +1343,7 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } #endif - BuildDisplayListForChildren(aBuilder, aDirtyRect, destination); + BuildDisplayListForChildren(aBuilder, destination); // see if we have to draw a selection frame around this container DisplaySelectionOverlay(aBuilder, destination.Content()); @@ -1370,7 +1369,6 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, void nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { nsIFrame* kid = mFrames.FirstChild(); @@ -1379,7 +1377,7 @@ nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds()); // The children should be in the right order while (kid) { - BuildDisplayListForChild(aBuilder, kid, aDirtyRect, set); + BuildDisplayListForChild(aBuilder, kid, set); kid = kid->GetNextSibling(); } } diff --git a/layout/xul/nsBoxFrame.h b/layout/xul/nsBoxFrame.h index ad405222fb..7b15f4f5ea 100644 --- a/layout/xul/nsBoxFrame.h +++ b/layout/xul/nsBoxFrame.h @@ -148,11 +148,9 @@ 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 45d9345168..4f2a7cbe1f 100644 --- a/layout/xul/nsButtonBoxFrame.cpp +++ b/layout/xul/nsButtonBoxFrame.cpp @@ -91,13 +91,12 @@ 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, aDirtyRect, aLists); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists); } nsresult diff --git a/layout/xul/nsButtonBoxFrame.h b/layout/xul/nsButtonBoxFrame.h index e9bfd99a50..0dc8b517f1 100644 --- a/layout/xul/nsButtonBoxFrame.h +++ b/layout/xul/nsButtonBoxFrame.h @@ -23,7 +23,6 @@ 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 b0c0296b2e..91359c177a 100644 --- a/layout/xul/nsDeckFrame.cpp +++ b/layout/xul/nsDeckFrame.cpp @@ -145,14 +145,13 @@ 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, aDirtyRect, aLists); + nsBoxFrame::BuildDisplayList(aBuilder, aLists); } void @@ -185,7 +184,6 @@ nsDeckFrame::RemoveFrame(ChildListID aListID, void nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // only paint the selected box @@ -196,7 +194,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, aDirtyRect, set); + BuildDisplayListForChild(aBuilder, box, set); } NS_IMETHODIMP diff --git a/layout/xul/nsDeckFrame.h b/layout/xul/nsDeckFrame.h index 2c7ae14451..1437452362 100644 --- a/layout/xul/nsDeckFrame.h +++ b/layout/xul/nsDeckFrame.h @@ -34,14 +34,12 @@ 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 514287a24a..df3955cf3e 100644 --- a/layout/xul/nsGroupBoxFrame.cpp +++ b/layout/xul/nsGroupBoxFrame.cpp @@ -28,7 +28,6 @@ public: virtual nsresult GetXULBorderAndPadding(nsMargin& aBorderAndPadding) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; #ifdef DEBUG_FRAME_DUMP @@ -145,13 +144,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, this, + GetBackgroundRectRelativeToSelf() + aBuilder->ToReferenceFrame(this), aLists.BorderBackground()); aLists.BorderBackground()->AppendNewToTop(new (aBuilder) nsDisplayXULGroupBorder(aBuilder, this)); @@ -159,7 +158,7 @@ nsGroupBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, DisplayOutline(aBuilder, aLists); } - BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); + BuildDisplayListForChildren(aBuilder, aLists); } nsRect diff --git a/layout/xul/nsImageBoxFrame.cpp b/layout/xul/nsImageBoxFrame.cpp index fd7c7becf5..e88b502ab7 100644 --- a/layout/xul/nsImageBoxFrame.cpp +++ b/layout/xul/nsImageBoxFrame.cpp @@ -320,10 +320,9 @@ nsImageBoxFrame::UpdateLoadFlags() void nsImageBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsLeafBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsLeafBoxFrame::BuildDisplayList(aBuilder, 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 7faccccaee..46c8d56149 100644 --- a/layout/xul/nsImageBoxFrame.h +++ b/layout/xul/nsImageBoxFrame.h @@ -87,7 +87,6 @@ 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 6d1783c11c..8342b74854 100644 --- a/layout/xul/nsLeafBoxFrame.cpp +++ b/layout/xul/nsLeafBoxFrame.cpp @@ -106,7 +106,6 @@ 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 8aea598c83..7a63d9a796 100644 --- a/layout/xul/nsLeafBoxFrame.h +++ b/layout/xul/nsLeafBoxFrame.h @@ -64,7 +64,6 @@ 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 1776f1b6cb..720df38279 100644 --- a/layout/xul/nsListItemFrame.cpp +++ b/layout/xul/nsListItemFrame.cpp @@ -39,7 +39,6 @@ nsListItemFrame::GetXULPrefSize(nsBoxLayoutState& aState) void nsListItemFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (aBuilder->IsForEventDelivery()) { @@ -48,7 +47,7 @@ nsListItemFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, return; } - nsGridRowLeafFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); + nsGridRowLeafFrame::BuildDisplayListForChildren(aBuilder, aLists); } // Creation Routine /////////////////////////////////////////////////////////////////////// diff --git a/layout/xul/nsListItemFrame.h b/layout/xul/nsListItemFrame.h index 40e731efa5..aa41dbbbfd 100644 --- a/layout/xul/nsListItemFrame.h +++ b/layout/xul/nsListItemFrame.h @@ -20,7 +20,6 @@ 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 67fcdbe431..6bd5b44ff9 100644 --- a/layout/xul/nsMenuFrame.cpp +++ b/layout/xul/nsMenuFrame.cpp @@ -356,16 +356,15 @@ nsMenuFrame::DestroyFrom(nsIFrame* aDestructRoot) void nsMenuFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!aBuilder->IsForEventDelivery()) { - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists); return; } - nsDisplayListCollection set; - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, set); + nsDisplayListCollection set (aBuilder); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, set); WrapListsInRedirector(aBuilder, set, aLists); } diff --git a/layout/xul/nsMenuFrame.h b/layout/xul/nsMenuFrame.h index 1941ec69e6..43cbd0a04c 100644 --- a/layout/xul/nsMenuFrame.h +++ b/layout/xul/nsMenuFrame.h @@ -101,7 +101,6 @@ 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 fe41dce527..26e94faea6 100644 --- a/layout/xul/nsRootBoxFrame.cpp +++ b/layout/xul/nsRootBoxFrame.cpp @@ -75,7 +75,6 @@ public: nsEventStatus* aEventStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; /** @@ -176,14 +175,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 = aDirtyRect.Intersect(nsRect(nsPoint(0, 0), GetSize())); + nsRect displayPortBase = + aBuilder->GetVisibleRect().Intersect(nsRect(nsPoint(0, 0), GetSize())); nsLayoutUtils::SetDisplayPortBase(mContent, displayPortBase); } @@ -192,7 +191,7 @@ nsRootBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // of a background display list element. DisplayBorderBackgroundOutline(aBuilder, aLists, true); - BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); + BuildDisplayListForChildren(aBuilder, aLists); } nsresult diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index 3c1f9ef912..db22189442 100644 --- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -311,7 +311,6 @@ nsSliderFrame::AttributeChanged(int32_t aNameSpaceID, void nsSliderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (aBuilder->IsForEventDelivery() && isDraggingThumb()) { @@ -322,12 +321,11 @@ nsSliderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, return; } - nsBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsBoxFrame::BuildDisplayList(aBuilder, 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. @@ -360,8 +358,8 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, nsLayoutUtils::SetScrollbarThumbLayerization(thumb, thumbGetsLayer); if (thumbGetsLayer) { - nsDisplayListCollection tempLists; - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, tempLists); + nsDisplayListCollection tempLists (aBuilder); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, tempLists); // This is a bit of a hack. Collect up all descendant display items // and merge them into a single Content() list. @@ -382,7 +380,7 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, } } - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists); } NS_IMETHODIMP diff --git a/layout/xul/nsSliderFrame.h b/layout/xul/nsSliderFrame.h index 832065a210..e4b68fc018 100644 --- a/layout/xul/nsSliderFrame.h +++ b/layout/xul/nsSliderFrame.h @@ -64,11 +64,9 @@ 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 7879a176d3..468ccc6826 100644 --- a/layout/xul/nsSplitterFrame.cpp +++ b/layout/xul/nsSplitterFrame.cpp @@ -358,10 +358,9 @@ nsSplitterFrame::HandleRelease(nsPresContext* aPresContext, void nsSplitterFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsBoxFrame::BuildDisplayList(aBuilder, 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 df8872255e..fa1c7525ff 100644 --- a/layout/xul/nsSplitterFrame.h +++ b/layout/xul/nsSplitterFrame.h @@ -68,7 +68,6 @@ 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 437d558f91..a2ec57adc7 100644 --- a/layout/xul/nsStackFrame.cpp +++ b/layout/xul/nsStackFrame.cpp @@ -45,7 +45,6 @@ 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 @@ -56,8 +55,7 @@ nsStackFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, nsIFrame* kid = mFrames.FirstChild(); while (kid) { // Force each child into its own true stacking context. - BuildDisplayListForChild(aBuilder, kid, aDirtyRect, kidLists, - DISPLAY_CHILD_FORCE_STACKING_CONTEXT); + BuildDisplayListForChild(aBuilder, kid, kidLists, DISPLAY_CHILD_FORCE_STACKING_CONTEXT); kid = kid->GetNextSibling(); } } diff --git a/layout/xul/nsStackFrame.h b/layout/xul/nsStackFrame.h index b90a16b213..a81a62281c 100644 --- a/layout/xul/nsStackFrame.h +++ b/layout/xul/nsStackFrame.h @@ -33,7 +33,6 @@ 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 c82d3d6b9b..e1650e0d00 100644 --- a/layout/xul/nsTextBoxFrame.cpp +++ b/layout/xul/nsTextBoxFrame.cpp @@ -364,13 +364,12 @@ nsDisplayXULTextBox::GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) void nsTextBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!IsVisibleForPainting(aBuilder)) return; - nsLeafBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsLeafBoxFrame::BuildDisplayList(aBuilder, aLists); aLists.Content()->AppendNewToTop(new (aBuilder) nsDisplayXULTextBox(aBuilder, this)); diff --git a/layout/xul/nsTextBoxFrame.h b/layout/xul/nsTextBoxFrame.h index ca1b887484..e12b97b32d 100644 --- a/layout/xul/nsTextBoxFrame.h +++ b/layout/xul/nsTextBoxFrame.h @@ -48,7 +48,6 @@ 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 2792403dcc..2f58abecb9 100644 --- a/layout/xul/nsTitleBarFrame.cpp +++ b/layout/xul/nsTitleBarFrame.cpp @@ -42,7 +42,6 @@ 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 @@ -51,7 +50,7 @@ nsTitleBarFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, nsGkAtoms::_true, eCaseMatters)) return; } - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists); } nsresult diff --git a/layout/xul/nsTitleBarFrame.h b/layout/xul/nsTitleBarFrame.h index 17279c578f..594d0978bc 100644 --- a/layout/xul/nsTitleBarFrame.h +++ b/layout/xul/nsTitleBarFrame.h @@ -19,7 +19,6 @@ 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 deba04a36c..608d802ea1 100644 --- a/layout/xul/tree/nsTreeBodyFrame.cpp +++ b/layout/xul/tree/nsTreeBodyFrame.cpp @@ -2824,7 +2824,6 @@ 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! @@ -2832,7 +2831,7 @@ nsTreeBodyFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, return; // We're invisible. Don't paint. // Handles painting our background, border, and outline. - nsLeafBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + nsLeafBoxFrame::BuildDisplayList(aBuilder, 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 9620c8ccb3..6838b01576 100644 --- a/layout/xul/tree/nsTreeBodyFrame.h +++ b/layout/xul/tree/nsTreeBodyFrame.h @@ -177,7 +177,6 @@ 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 649c0b0b4c..0bedec086b 100644 --- a/layout/xul/tree/nsTreeColFrame.cpp +++ b/layout/xul/tree/nsTreeColFrame.cpp @@ -110,16 +110,15 @@ nsDisplayXULTreeColSplitterTarget::HitTest(nsDisplayListBuilder* aBuilder, const void nsTreeColFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { if (!aBuilder->IsForEventDelivery()) { - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists); return; } - nsDisplayListCollection set; - nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, set); + nsDisplayListCollection set (aBuilder); + nsBoxFrame::BuildDisplayListForChildren(aBuilder, set); WrapListsInRedirector(aBuilder, set, aLists); diff --git a/layout/xul/tree/nsTreeColFrame.h b/layout/xul/tree/nsTreeColFrame.h index 8fc3219d50..ebd16fa526 100644 --- a/layout/xul/tree/nsTreeColFrame.h +++ b/layout/xul/tree/nsTreeColFrame.h @@ -26,7 +26,6 @@ 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, |