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