Bug 1460491 - Part 1: Split nsDisplayItem::mVisibleRect into two members, one for each stated purpose. Gets rid of the save/restore since we no longer modify the building rect. r=jnicol
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 16 May 2018 15:56:32 +1200
changeset 418430 920d49a96e6ec78991466cb5e1850c81d39937f2
parent 418429 63988e7c891f8d664f428fbaf91d9b181e3557e1
child 418431 0571c2da7c437eb965ebf0cb79a4d991e6d7b8c2
push id34000
push userebalazs@mozilla.com
push dateWed, 16 May 2018 09:59:58 +0000
treeherdermozilla-central@dedd25bfd279 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjnicol
bugs1460491
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1460491 - Part 1: Split nsDisplayItem::mVisibleRect into two members, one for each stated purpose. Gets rid of the save/restore since we no longer modify the building rect. r=jnicol MozReview-Commit-ID: 5wcsSoZRN44
gfx/layers/wr/WebRenderCommandBuilder.cpp
layout/base/nsLayoutDebugger.cpp
layout/forms/nsButtonFrameRenderer.cpp
layout/forms/nsFieldSetFrame.cpp
layout/forms/nsRangeFrame.cpp
layout/generic/TextOverflow.cpp
layout/generic/nsBulletFrame.cpp
layout/generic/nsCanvasFrame.cpp
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsImageFrame.cpp
layout/generic/nsPageFrame.cpp
layout/generic/nsPluginFrame.cpp
layout/generic/nsSimplePageSequenceFrame.cpp
layout/generic/nsTextFrame.cpp
layout/mathml/nsMathMLChar.cpp
layout/mathml/nsMathMLmtableFrame.cpp
layout/painting/FrameLayerBuilder.cpp
layout/painting/RetainedDisplayListBuilder.cpp
layout/painting/nsCSSRendering.cpp
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
layout/svg/nsSVGOuterSVGFrame.cpp
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableFrame.cpp
layout/xul/nsGroupBoxFrame.cpp
layout/xul/nsImageBoxFrame.cpp
layout/xul/nsTextBoxFrame.cpp
layout/xul/tree/nsTreeBodyFrame.cpp
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -1620,20 +1620,20 @@ WebRenderCommandBuilder::GenerateFallbac
   if (useBlobImage || aItem->MustPaintOnContentSide()) {
     paintBounds = itemBounds;
   } else {
     paintBounds = aItem->GetClippedBounds(aDisplayListBuilder);
   }
 
   // nsDisplayItem::Paint() may refer the variables that come from ComputeVisibility().
   // So we should call ComputeVisibility() before painting. e.g.: nsDisplayBoxShadowInner
-  // uses mVisibleRegion in Paint() and mVisibleRegion is computed in
+  // uses mPaintRect in Paint() and mPaintRect is computed in
   // nsDisplayBoxShadowInner::ComputeVisibility().
   nsRegion visibleRegion(paintBounds);
-  aItem->SetVisibleRect(paintBounds, false);
+  aItem->SetPaintRect(paintBounds);
   aItem->ComputeVisibility(aDisplayListBuilder, &visibleRegion);
 
   const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
   LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(paintBounds, appUnitsPerDevPixel);
 
   gfx::Size scale = aSc.GetInheritedScale();
   gfx::Size oldScale = fallbackData->GetScale();
   // This scale determination should probably be done using
--- a/layout/base/nsLayoutDebugger.cpp
+++ b/layout/base/nsLayoutDebugger.cpp
@@ -133,17 +133,17 @@ PrintDisplayItemTo(nsDisplayListBuilder*
       classes->ToString(tmp);
       contentData.AppendLiteral(" class:");
       contentData.Append(tmp);
     }
   }
   bool snap;
   nsRect rect = aItem->GetBounds(aBuilder, &snap);
   nsRect layerRect = rect - (*aItem->GetAnimatedGeometryRoot())->GetOffsetToCrossDoc(aItem->ReferenceFrame());
-  nsRect vis = aItem->GetVisibleRect();
+  nsRect vis = aItem->GetPaintRect();
   nsRect component = aItem->GetComponentAlphaBounds(aBuilder);
   nsDisplayList* list = aItem->GetChildren();
   const DisplayItemClip& clip = aItem->GetClip();
   nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, &snap);
 
 #ifdef MOZ_DUMP_PAINTING
   if (aDumpHtml && aItem->Painted()) {
     nsCString string(aItem->Name());
--- a/layout/forms/nsButtonFrameRenderer.cpp
+++ b/layout/forms/nsButtonFrameRenderer.cpp
@@ -108,17 +108,17 @@ nsDisplayButtonBoxShadowOuter::GetBounds
 }
 
 void
 nsDisplayButtonBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder,
                                      gfxContext* aCtx) {
   nsRect frameRect = nsRect(ToReferenceFrame(), mFrame->GetSize());
 
   nsCSSRendering::PaintBoxShadowOuter(mFrame->PresContext(), *aCtx, mFrame,
-                                      frameRect, mVisibleRect);
+                                      frameRect, GetPaintRect());
 }
 
 bool
 nsDisplayButtonBoxShadowOuter::CanBuildWebRenderDisplayItems()
 {
   nsCSSShadowArray* shadows = mFrame->StyleEffects()->mBoxShadow;
   if (!shadows) {
     return false;
@@ -150,17 +150,17 @@ nsDisplayButtonBoxShadowOuter::CreateWeb
   }
   int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
   nsRect shadowRect = nsRect(ToReferenceFrame(), mFrame->GetSize());
   LayoutDeviceRect deviceBox =
     LayoutDeviceRect::FromAppUnits(shadowRect, appUnitsPerDevPixel);
   wr::LayoutRect deviceBoxRect = wr::ToRoundedLayoutRect(deviceBox);
 
   LayoutDeviceRect clipRect =
-    LayoutDeviceRect::FromAppUnits(mVisibleRect, appUnitsPerDevPixel);
+    LayoutDeviceRect::FromAppUnits(GetPaintRect(), appUnitsPerDevPixel);
   wr::LayoutRect deviceClipRect = wr::ToRoundedLayoutRect(clipRect);
 
   bool hasBorderRadius;
   Unused << nsCSSRendering::HasBoxShadowNativeTheme(mFrame, hasBorderRadius);
 
   LayoutDeviceSize zeroSize;
   wr::BorderRadius borderRadius = wr::ToBorderRadius(zeroSize, zeroSize,
                                                      zeroSize, zeroSize);
@@ -314,17 +314,17 @@ nsDisplayButtonBorder::Paint(nsDisplayLi
                              gfxContext* aCtx)
 {
   NS_ASSERTION(mFrame, "No frame?");
   nsPresContext* pc = mFrame->PresContext();
   nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize());
 
   // draw the border and background inside the focus and outline borders
   ImgDrawResult result =
-    mBFR->PaintBorder(aBuilder, pc, *aCtx, mVisibleRect, r);
+    mBFR->PaintBorder(aBuilder, pc, *aCtx, GetPaintRect(), r);
 
   nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
 }
 
 nsRect
 nsDisplayButtonBorder::GetBounds(nsDisplayListBuilder* aBuilder,
                                  bool* aSnap) const
 {
@@ -391,17 +391,17 @@ void nsDisplayButtonForeground::Paint(ns
   nsPresContext *presContext = mFrame->PresContext();
   const nsStyleDisplay *disp = mFrame->StyleDisplay();
   if (!mFrame->IsThemed(disp) ||
       !presContext->GetTheme()->ThemeDrawsFocusForWidget(disp->mAppearance)) {
     nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize());
 
     // Draw the -moz-focus-inner border
     ImgDrawResult result =
-      mBFR->PaintInnerFocusBorder(aBuilder, presContext, *aCtx, mVisibleRect, r);
+      mBFR->PaintInnerFocusBorder(aBuilder, presContext, *aCtx, GetPaintRect(), r);
 
     nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
   }
 }
 
 bool
 nsDisplayButtonForeground::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                                    mozilla::wr::IpcResourceUpdateQueue& aResources,
@@ -412,17 +412,17 @@ nsDisplayButtonForeground::CreateWebRend
   Maybe<nsCSSBorderRenderer> br;
   bool borderIsEmpty = false;
   nsPresContext *presContext = mFrame->PresContext();
   const nsStyleDisplay *disp = mFrame->StyleDisplay();
   if (!mFrame->IsThemed(disp) ||
       !presContext->GetTheme()->ThemeDrawsFocusForWidget(disp->mAppearance)) {
     nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize());
     br = mBFR->CreateInnerFocusBorderRenderer(aDisplayListBuilder, presContext, nullptr,
-                                              mVisibleRect, r, &borderIsEmpty);
+                                              GetPaintRect(), r, &borderIsEmpty);
   }
 
   if (!br) {
     return borderIsEmpty;
   }
 
   br->CreateWebRenderCommands(this, aBuilder, aResources, aSc);
   return true;
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -107,17 +107,17 @@ public:
   NS_DISPLAY_DECL_NAME("FieldSetBorder", TYPE_FIELDSET_BORDER_BACKGROUND)
 };
 
 void
 nsDisplayFieldSetBorder::Paint(nsDisplayListBuilder* aBuilder,
                                gfxContext* aCtx)
 {
   image::ImgDrawResult result = static_cast<nsFieldSetFrame*>(mFrame)->
-    PaintBorder(aBuilder, *aCtx, ToReferenceFrame(), mVisibleRect);
+    PaintBorder(aBuilder, *aCtx, ToReferenceFrame(), GetPaintRect());
 
   nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
 }
 
 nsDisplayItemGeometry*
 nsDisplayFieldSetBorder::AllocateGeometry(nsDisplayListBuilder* aBuilder)
 {
   return new nsDisplayItemGenericImageGeometry(this, aBuilder);
--- a/layout/forms/nsRangeFrame.cpp
+++ b/layout/forms/nsRangeFrame.cpp
@@ -237,17 +237,17 @@ nsDisplayRangeFocusRing::Paint(nsDisplay
   MOZ_ASSERT(computedStyle, "We only exist if mOuterFocusStyle is non-null");
 
   PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages()
                          ? PaintBorderFlags::SYNC_DECODE_IMAGES
                          : PaintBorderFlags();
 
   ImgDrawResult result =
     nsCSSRendering::PaintBorder(mFrame->PresContext(), *aCtx, mFrame,
-                                mVisibleRect, GetBounds(aBuilder, &unused),
+                                GetPaintRect(), GetBounds(aBuilder, &unused),
                                 computedStyle, flags);
 
   nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
 }
 
 void
 nsRangeFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                const nsDisplayListSet& aLists)
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -241,17 +241,17 @@ nsDisplayTextOverflowMarker::Paint(nsDis
 {
   DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
                                                     mDisableSubpixelAA);
 
   nscolor foregroundColor = nsLayoutUtils::
     GetColor(mFrame, &nsStyleText::mWebkitTextFillColor);
 
   // Paint the text-shadows for the overflow marker
-  nsLayoutUtils::PaintTextShadow(mFrame, aCtx, mRect, mVisibleRect,
+  nsLayoutUtils::PaintTextShadow(mFrame, aCtx, mRect, GetPaintRect(),
                                  foregroundColor, PaintTextShadowCallback,
                                  (void*)this);
   aCtx->SetColor(gfx::Color::FromABGR(foregroundColor));
   PaintTextToContext(aCtx, nsPoint(0, 0));
 }
 
 void
 nsDisplayTextOverflowMarker::PaintTextToContext(gfxContext* aCtx,
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -710,17 +710,17 @@ void nsDisplayBullet::Paint(nsDisplayLis
                             gfxContext* aCtx)
 {
   uint32_t flags = imgIContainer::FLAG_NONE;
   if (aBuilder->ShouldSyncDecodeImages()) {
     flags |= imgIContainer::FLAG_SYNC_DECODE;
   }
 
   ImgDrawResult result = static_cast<nsBulletFrame*>(mFrame)->
-    PaintBullet(*aCtx, ToReferenceFrame(), mVisibleRect, flags,
+    PaintBullet(*aCtx, ToReferenceFrame(), GetPaintRect(), flags,
                 mDisableSubpixelAA);
 
   nsDisplayBulletGeometry::UpdateDrawResult(this, result);
 }
 
 void
 nsBulletFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsDisplayListSet& aLists)
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -350,17 +350,17 @@ nsDisplayCanvasBackgroundColor::WriteDeb
 void
 nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
                                       gfxContext* aCtx)
 {
   nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
   nsPoint offset = ToReferenceFrame();
   nsRect bgClipRect = frame->CanvasArea() + offset;
 
-  PaintInternal(aBuilder, aCtx, mVisibleRect, &bgClipRect);
+  PaintInternal(aBuilder, aCtx, GetPaintRect(), &bgClipRect);
 }
 
 bool
 nsDisplayCanvasBackgroundImage::IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder,
                                                            const nsRect& aClipRect,
                                                            gfxRect* aDestRect)
 {
   if (!mBackgroundStyle)
@@ -397,17 +397,17 @@ nsDisplayCanvasBackgroundImage::IsSingle
 void
 nsDisplayCanvasThemedBackground::Paint(nsDisplayListBuilder* aBuilder,
                                        gfxContext* aCtx)
 {
   nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
   nsPoint offset = ToReferenceFrame();
   nsRect bgClipRect = frame->CanvasArea() + offset;
 
-  PaintInternal(aBuilder, aCtx, mVisibleRect, &bgClipRect);
+  PaintInternal(aBuilder, aCtx, GetPaintRect(), &bgClipRect);
 }
 
 /**
  * A display item to paint the focus ring for the document.
  *
  * The only reason this can't use nsDisplayGeneric is overriding GetBounds.
  */
 class nsDisplayCanvasFocus : public nsDisplayItem {
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -54,17 +54,17 @@ private:
   nsTArray<nsCSSBorderRenderer> mBorderRenderers;
 };
 
 void
 nsDisplayColumnRule::Paint(nsDisplayListBuilder* aBuilder,
                            gfxContext* aCtx)
 {
   static_cast<nsColumnSetFrame*>(mFrame)->
-    CreateBorderRenderers(mBorderRenderers, aCtx, mVisibleRect, ToReferenceFrame());
+    CreateBorderRenderers(mBorderRenderers, aCtx, GetPaintRect(), ToReferenceFrame());
 
   for (auto iter = mBorderRenderers.begin(); iter != mBorderRenderers.end(); iter++) {
     iter->DrawBorders();
   }
 }
 
 bool
 nsDisplayColumnRule::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
@@ -72,17 +72,17 @@ nsDisplayColumnRule::CreateWebRenderComm
                                              const StackingContextHelper& aSc,
                                              mozilla::layers::WebRenderLayerManager* aManager,
                                              nsDisplayListBuilder* aDisplayListBuilder)
 {
   RefPtr<gfxContext> screenRefCtx = gfxContext::CreateOrNull(
     gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget().get());
 
   static_cast<nsColumnSetFrame*>(mFrame)->
-    CreateBorderRenderers(mBorderRenderers, screenRefCtx, mVisibleRect, ToReferenceFrame());
+    CreateBorderRenderers(mBorderRenderers, screenRefCtx, GetPaintRect(), ToReferenceFrame());
 
   if (mBorderRenderers.IsEmpty()) {
     return true;
   }
 
   for (auto& renderer : mBorderRenderers) {
     renderer.CreateWebRenderCommands(this, aBuilder, aResources, aSc);
   }
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2227,17 +2227,17 @@ nsDisplaySelectionOverlay::ComputeColor(
 
 void nsDisplaySelectionOverlay::Paint(nsDisplayListBuilder* aBuilder,
                                       gfxContext* aCtx)
 {
   DrawTarget& aDrawTarget = *aCtx->GetDrawTarget();
   ColorPattern color(ComputeColor());
 
   nsIntRect pxRect =
-    mVisibleRect.ToOutsidePixels(mFrame->PresContext()->AppUnitsPerDevPixel());
+    GetPaintRect().ToOutsidePixels(mFrame->PresContext()->AppUnitsPerDevPixel());
   Rect rect(pxRect.x, pxRect.y, pxRect.width, pxRect.height);
   MaybeSnapToDevicePixels(rect, aDrawTarget, true);
 
   aDrawTarget.FillRect(rect, color);
 }
 
 
 bool
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -1616,17 +1616,17 @@ public:
 };
 
 void nsDisplayFramesetBlank::Paint(nsDisplayListBuilder* aBuilder,
                                    gfxContext* aCtx)
 {
   DrawTarget* drawTarget = aCtx->GetDrawTarget();
   int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
   Rect rect =
-    NSRectToSnappedRect(mVisibleRect, appUnitsPerDevPixel, *drawTarget);
+    NSRectToSnappedRect(GetPaintRect(), appUnitsPerDevPixel, *drawTarget);
   ColorPattern white(ToDeviceColor(Color(1.f, 1.f, 1.f, 1.f)));
   drawTarget->FillRect(rect, white);
 }
 
 void
 nsHTMLFramesetBlankFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                            const nsDisplayListSet& aLists)
 {
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1337,17 +1337,17 @@ public:
   {
     // Always sync decode, because these icons are UI, and since they're not
     // discardable we'll pay the price of sync decoding at most once.
     uint32_t flags = imgIContainer::FLAG_SYNC_DECODE;
 
     nsImageFrame* f = static_cast<nsImageFrame*>(mFrame);
     ImgDrawResult result =
       f->DisplayAltFeedback(*aCtx,
-                            mVisibleRect,
+                            GetPaintRect(),
                             ToReferenceFrame(),
                             flags);
 
     nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
   }
 
   NS_DISPLAY_DECL_NAME("AltFeedback", TYPE_ALT_FEEDBACK)
 };
@@ -1534,26 +1534,26 @@ nsDisplayImage::Paint(nsDisplayListBuild
   if (aBuilder->ShouldSyncDecodeImages()) {
     flags |= imgIContainer::FLAG_SYNC_DECODE;
   }
   if (aBuilder->IsPaintingToWindow()) {
     flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING;
   }
 
   ImgDrawResult result = static_cast<nsImageFrame*>(mFrame)->
-    PaintImage(*aCtx, ToReferenceFrame(), mVisibleRect, mImage, flags);
+    PaintImage(*aCtx, ToReferenceFrame(), GetPaintRect(), mImage, flags);
 
   if (result == ImgDrawResult::NOT_READY ||
       result == ImgDrawResult::INCOMPLETE ||
       result == ImgDrawResult::TEMPORARY_ERROR) {
     // If the current image failed to paint because it's still loading or
     // decoding, try painting the previous image.
     if (mPrevImage) {
       result = static_cast<nsImageFrame*>(mFrame)->
-        PaintImage(*aCtx, ToReferenceFrame(), mVisibleRect, mPrevImage, flags);
+        PaintImage(*aCtx, ToReferenceFrame(), GetPaintRect(), mPrevImage, flags);
     }
   }
 
   nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
 }
 
 nsDisplayItemGeometry*
 nsDisplayImage::AllocateGeometry(nsDisplayListBuilder* aBuilder)
--- a/layout/generic/nsPageFrame.cpp
+++ b/layout/generic/nsPageFrame.cpp
@@ -582,17 +582,17 @@ nsPageFrame::BuildDisplayList(nsDisplayL
     nsRect backgroundRect =
       nsRect(aBuilder->ToReferenceFrame(child), child->GetSize());
 
     PresContext()->GetPresShell()->AddCanvasBackgroundColorItem(
       *aBuilder, content, child, backgroundRect, NS_RGBA(0,0,0,0));
   }
 
   content.AppendToTop(MakeDisplayItem<nsDisplayTransform>(aBuilder, child,
-      &content, content.GetVisibleRect(), ::ComputePageTransform));
+      &content, content.GetBuildingRect(), ::ComputePageTransform));
 
   set.Content()->AppendToTop(&content);
 
   if (PresContext()->IsRootPaginatedDocument()) {
     set.Content()->AppendToTop(
         MakeDisplayItem<nsDisplayHeaderFooter>(aBuilder, this));
   }
 
--- a/layout/generic/nsPluginFrame.cpp
+++ b/layout/generic/nsPluginFrame.cpp
@@ -941,17 +941,17 @@ nsDisplayPlugin::GetBounds(nsDisplayList
 }
 
 void
 nsDisplayPlugin::Paint(nsDisplayListBuilder* aBuilder,
                        gfxContext* aCtx)
 {
   nsPluginFrame* f = static_cast<nsPluginFrame*>(mFrame);
   bool snap;
-  f->PaintPlugin(aBuilder, *aCtx, mVisibleRect, GetBounds(aBuilder, &snap));
+  f->PaintPlugin(aBuilder, *aCtx, GetPaintRect(), GetBounds(aBuilder, &snap));
 }
 
 static nsRect
 GetClippedBoundsIncludingAllScrollClips(nsDisplayItem* aItem,
                                         nsDisplayListBuilder* aBuilder)
 {
   nsRect r = aItem->GetClippedBounds(aBuilder);
   for (auto* sc = aItem->GetClipChain(); sc; sc = sc->mParent) {
--- a/layout/generic/nsSimplePageSequenceFrame.cpp
+++ b/layout/generic/nsSimplePageSequenceFrame.cpp
@@ -746,17 +746,17 @@ nsSimplePageSequenceFrame::BuildDisplayL
         child->BuildDisplayListForStackingContext(aBuilder, &content);
         aBuilder->ResetMarkedFramesForDisplayList(this);
       }
       child = child->GetNextSibling();
     }
   }
 
   content.AppendToTop(
-      MakeDisplayItem<nsDisplayTransform>(aBuilder, this, &content, content.GetVisibleRect(),
+      MakeDisplayItem<nsDisplayTransform>(aBuilder, this, &content, content.GetBuildingRect(),
                                           ::ComputePageSequenceTransform));
 
   aLists.Content()->AppendToTop(&content);
   aBuilder->SetInPageSequence(false);
 }
 
 //------------------------------------------------------------------------------
 void
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -5119,17 +5119,17 @@ nsDisplayText::RenderToContext(gfxContex
 {
   nsTextFrame* f = static_cast<nsTextFrame*>(mFrame);
 
   // Add 1 pixel of dirty area around mVisibleRect to allow us to paint
   // antialiased pixels beyond the measured text extents.
   // This is temporary until we do this in the actual calculation of text extents.
   auto A2D = mFrame->PresContext()->AppUnitsPerDevPixel();
   LayoutDeviceRect extraVisible =
-    LayoutDeviceRect::FromAppUnits(mVisibleRect, A2D);
+    LayoutDeviceRect::FromAppUnits(GetPaintRect(), A2D);
   extraVisible.Inflate(1);
 
   gfxRect pixelVisible(extraVisible.x, extraVisible.y,
                        extraVisible.width, extraVisible.height);
   pixelVisible.Inflate(2);
   pixelVisible.RoundOut();
 
   bool willClip = !aBuilder->IsForGenerateGlyphMask() &&
--- a/layout/mathml/nsMathMLChar.cpp
+++ b/layout/mathml/nsMathMLChar.cpp
@@ -1950,21 +1950,21 @@ void nsDisplayMathMLCharDebug::Paint(nsD
 
   PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages()
                          ? PaintBorderFlags::SYNC_DECODE_IMAGES
                          : PaintBorderFlags();
 
   // Since this is used only for debugging, we don't need to worry about
   // tracking the ImgDrawResult.
   Unused <<
-    nsCSSRendering::PaintBorder(presContext, *aCtx, mFrame, mVisibleRect,
+    nsCSSRendering::PaintBorder(presContext, *aCtx, mFrame, GetPaintRect(),
                                 rect, computedStyle, flags, skipSides);
 
   nsCSSRendering::PaintOutline(presContext, *aCtx, mFrame,
-                               mVisibleRect, rect, computedStyle);
+                               GetPaintRect(), rect, computedStyle);
 }
 #endif
 
 
 void
 nsMathMLChar::Display(nsDisplayListBuilder*   aBuilder,
                       nsIFrame*               aForFrame,
                       const nsDisplayListSet& aLists,
--- a/layout/mathml/nsMathMLmtableFrame.cpp
+++ b/layout/mathml/nsMathMLmtableFrame.cpp
@@ -315,17 +315,17 @@ public:
     bounds.Inflate(overflow);
 
     PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages()
                            ? PaintBorderFlags::SYNC_DECODE_IMAGES
                            : PaintBorderFlags();
 
     ImgDrawResult result =
       nsCSSRendering::PaintBorderWithStyleBorder(mFrame->PresContext(), *aCtx,
-                                                 mFrame, mVisibleRect,
+                                                 mFrame, GetPaintRect(),
                                                  bounds,
                                                  styleBorder,
                                                  mFrame->Style(),
                                                  flags,
                                                  mFrame->GetSkipSides());
 
     nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
   }
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -3780,17 +3780,17 @@ PaintedLayerData::Accumulate(ContainerSt
 
   if (!aState->mParameters.mDisableSubpixelAntialiasingInDescendants &&
       !componentAlphaBounds.IsEmpty()) {
     nsIntRect componentAlphaRect =
       aState->ScaleToOutsidePixels(componentAlphaBounds, false).Intersect(aVisibleRect);
 
     if (!mOpaqueRegion.Contains(componentAlphaRect)) {
       if (IsItemAreaInWindowOpaqueRegion(aState->mBuilder, aItem,
-            componentAlphaBounds.Intersect(aItem->GetVisibleRect()))) {
+            componentAlphaBounds.Intersect(aItem->GetBuildingRect()))) {
         mNeedComponentAlpha = true;
       } else {
         aItem->DisableComponentAlpha();
       }
     }
   }
 
   // Ensure animated text does not get flattened, even if it forces other
@@ -4003,17 +4003,17 @@ PaintInactiveLayer(nsDisplayListBuilder*
 {
   // This item has an inactive layer. Render it to a PaintedLayer
   // using a temporary BasicLayerManager.
   BasicLayerManager* basic = static_cast<BasicLayerManager*>(aManager);
   RefPtr<gfxContext> context = aContext;
 #ifdef MOZ_DUMP_PAINTING
   int32_t appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem);
   nsIntRect itemVisibleRect =
-    aItem->GetVisibleRect().ToOutsidePixels(appUnitsPerDevPixel);
+    aItem->GetPaintRect().ToOutsidePixels(appUnitsPerDevPixel);
 
   RefPtr<DrawTarget> tempDT;
   if (gfxEnv::DumpPaint()) {
     tempDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
                                       itemVisibleRect.Size(),
                                       SurfaceFormat::B8G8R8A8);
     if (tempDT) {
       context = gfxContext::CreateOrNull(tempDT);
@@ -4468,22 +4468,21 @@ ContainerState::ProcessDisplayItems(nsDi
           bounds = clip.ref();
         }
       }
     }
     ((nsRect&)mAccumulatedChildBounds).UnionRect(mAccumulatedChildBounds, bounds);
 #endif
 
     nsIntRect itemVisibleRect = itemDrawRect;
-    // We haven't computed visibility at this point, so item->GetVisibleRect()
-    // is just the dirty rect that item was initialized with. We intersect it
-    // with the clipped item bounds to get a tighter visible rect.
+    // We intersect the building rect with the clipped item bounds to get a
+    // tighter visible rect.
     if (!prerenderedTransform) {
       itemVisibleRect = itemVisibleRect.Intersect(
-        ScaleToOutsidePixels(item->GetVisibleRect(), false));
+        ScaleToOutsidePixels(item->GetBuildingRect(), false));
     }
 
     if (maxLayers != -1 && layerCount >= maxLayers) {
       forceInactive = true;
     }
 
     // Assign the item to a layer
     if (layerState == LAYER_ACTIVE_FORCE ||
@@ -4765,31 +4764,31 @@ ContainerState::ProcessDisplayItems(nsDi
             (itemType == DisplayItemType::TYPE_TRANSFORM &&
              (item->Frame()->Extend3DContext() ||
               item->Frame()->Combines3DTransformWithAncestors() ||
               item->Frame()->HasPerspective()))) {
           // Give untransformed visible region as outer visible region
           // to avoid failure caused by singular transforms.
           newLayerEntry->mUntransformedVisibleRegion = true;
           newLayerEntry->mVisibleRegion =
-            item->GetVisibleRectForChildren().ScaleToOutsidePixels(contentXScale, contentYScale, mAppUnitsPerDevPixel);
+            item->GetBuildingRectForChildren().ScaleToOutsidePixels(contentXScale, contentYScale, mAppUnitsPerDevPixel);
         } else {
           newLayerEntry->mVisibleRegion = itemVisibleRegion;
         }
         newLayerEntry->mOpaqueRegion = ComputeOpaqueRect(item,
           animatedGeometryRoot, itemASR, itemClip, aList,
           &newLayerEntry->mHideAllLayersBelow,
           &newLayerEntry->mOpaqueForAnimatedGeometryRootParent);
       } else {
         bool useChildrenVisible =
           itemType == DisplayItemType::TYPE_TRANSFORM &&
           (item->Frame()->IsPreserve3DLeaf() ||
            item->Frame()->HasPerspective());
         const nsIntRegion &visible = useChildrenVisible ?
-          item->GetVisibleRectForChildren().ScaleToOutsidePixels(contentXScale, contentYScale, mAppUnitsPerDevPixel):
+          item->GetBuildingRectForChildren().ScaleToOutsidePixels(contentXScale, contentYScale, mAppUnitsPerDevPixel):
           itemVisibleRegion;
 
         SetOuterVisibleRegionForLayer(ownLayer, visible,
             layerContentsVisibleRect.width >= 0 ? &layerContentsVisibleRect : nullptr,
             useChildrenVisible);
       }
       if (itemType == DisplayItemType::TYPE_SCROLL_INFO_LAYER) {
         nsDisplayScrollInfoLayer* scrollItem = static_cast<nsDisplayScrollInfoLayer*>(item);
@@ -5087,17 +5086,17 @@ FrameLayerBuilder::AddPaintedDisplayItem
       tempManager->EndTransaction(nullptr, nullptr);
       tempManager->SetUserData(&gLayerManagerLayerBuilder, nullptr);
       aItem.mItem = nullptr;
       return;
     }
 
     bool snap;
     nsRect visibleRect =
-      aItem.mItem->GetVisibleRect().Intersect(aItem.mItem->GetBounds(mDisplayListBuilder, &snap));
+      aItem.mItem->GetBuildingRect().Intersect(aItem.mItem->GetBounds(mDisplayListBuilder, &snap));
     nsIntRegion rgn = visibleRect.ToOutsidePixels(paintedData->mAppUnitsPerDevPixel);
 
     // Convert the visible rect to a region and give the item
     // a chance to try restrict it further.
     nsRegion tightBounds = aItem.mItem->GetTightBounds(mDisplayListBuilder, &snap);
     if (!tightBounds.IsEmpty()) {
       rgn.AndWith(tightBounds.ToOutsidePixels(paintedData->mAppUnitsPerDevPixel));
     }
@@ -5940,17 +5939,17 @@ FrameLayerBuilder::BuildContainerLayerFo
     containerASR = aBuilder->ActiveScrolledRootForRootScrollframe();
     containerScrollMetadataASR = containerASR;
     containerCompositorASR = containerASR;
   }
 
   ContainerLayerParameters scaleParameters;
   nsRect bounds = aChildren->GetClippedBoundsWithRespectToASR(aBuilder, containerASR);
   nsRect childrenVisible =
-      aContainerItem ? aContainerItem->GetVisibleRectForChildren() :
+      aContainerItem ? aContainerItem->GetBuildingRectForChildren() :
           aContainerFrame->GetVisualOverflowRectRelativeToSelf();
   if (!ChooseScaleAndSetTransform(this, aBuilder, aContainerFrame,
                                   aContainerItem,
                                   bounds.Intersect(childrenVisible),
                                   aTransform, aParameters,
                                   containerLayer, scaleParameters)) {
     return nullptr;
   }
@@ -6331,17 +6330,17 @@ FrameLayerBuilder::PaintItems(nsTArray<A
     AssignedDisplayItem& cdi = aItems[i];
     nsDisplayItem* item = cdi.mItem;
 
     if (!item) {
       MOZ_ASSERT(cdi.mType == DisplayItemEntryType::ITEM);
       continue;
     }
 
-    const nsRect& visibleRect = item->GetVisibleRect();
+    const nsRect& visibleRect = item->GetPaintRect();
     const nsRect paintRect = visibleRect.Intersect(boundRect);
 
     if (paintRect.IsEmpty() || emptyOpacityNesting > 0) {
       // In order for this branch to be hit, either this item has an empty paint
       // rect and nothing would be drawn, or a PUSH_OPACITY marker before this
       // item had an empty paint rect. In the latter case, the items are skipped
       // until POP_OPACITY markers bring |emptyOpacityNesting| back to 0.
       UpdateOpacityNesting(emptyOpacityNesting, cdi.mType);
--- a/layout/painting/RetainedDisplayListBuilder.cpp
+++ b/layout/painting/RetainedDisplayListBuilder.cpp
@@ -819,17 +819,17 @@ ProcessFrameInternal(nsIFrame* aFrame, n
 
       if (!aStopAtStackingContext) {
         // Continue ascending the frame tree until we reach aStopAtFrame.
         continue;
       }
 
       // Grab the visible (display list building) rect for children of this wrapper
       // item and convert into into coordinate relative to the current frame.
-      nsRect previousVisible = wrapperItem->GetVisibleRectForChildren();
+      nsRect previousVisible = wrapperItem->GetBuildingRectForChildren();
       if (wrapperItem->ReferenceFrameForChildren() == wrapperItem->ReferenceFrame()) {
         previousVisible -= wrapperItem->ToReferenceFrame();
       } else {
         MOZ_ASSERT(wrapperItem->ReferenceFrameForChildren() == wrapperItem->Frame());
       }
 
       if (!previousVisible.Contains(aOverflow)) {
         // If the overflow area of the changed frame isn't contained within the old
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -762,17 +762,17 @@ nsCSSRendering::CreateWebRenderCommandsF
   }
 
   image::ImgDrawResult result;
   Maybe<nsCSSBorderImageRenderer> bir =
     nsCSSBorderImageRenderer::CreateBorderImageRenderer(aForFrame->PresContext(),
                                                         aForFrame,
                                                         aBorderArea,
                                                         *styleBorder,
-                                                        aItem->GetVisibleRect(),
+                                                        aItem->GetPaintRect(),
                                                         aForFrame->GetSkipSides(),
                                                         flags,
                                                         &result);
 
   if (!bir) {
     return false;
   }
 
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2351,38 +2351,38 @@ nsDisplayList::GetBounds(nsDisplayListBu
     bounds.UnionRect(bounds, i->GetClippedBounds(aBuilder));
   }
   return bounds;
 }
 
 nsRect
 nsDisplayList::GetClippedBoundsWithRespectToASR(nsDisplayListBuilder* aBuilder,
                                                 const ActiveScrolledRoot* aASR,
-                                                nsRect* aVisibleRect) const {
+                                                nsRect* aBuildingRect) const {
   nsRect bounds;
   for (nsDisplayItem* i = GetBottom(); i != nullptr; i = i->GetAbove()) {
     nsRect r = i->GetClippedBounds(aBuilder);
     if (aASR != i->GetActiveScrolledRoot() && !r.IsEmpty()) {
       if (Maybe<nsRect> clip = i->GetClipWithRespectToASR(aBuilder, aASR)) {
         r = clip.ref();
       }
     }
-    if (aVisibleRect) {
-      aVisibleRect->UnionRect(*aVisibleRect, i->GetVisibleRect());
+    if (aBuildingRect) {
+      aBuildingRect->UnionRect(*aBuildingRect, i->GetBuildingRect());
     }
     bounds.UnionRect(bounds, r);
   }
   return bounds;
 }
 
 nsRect
-nsDisplayList::GetVisibleRect() const {
+nsDisplayList::GetBuildingRect() const {
   nsRect result;
   for (nsDisplayItem* i = GetBottom(); i != nullptr; i = i->GetAbove()) {
-    result.UnionRect(result, i->GetVisibleRect());
+    result.UnionRect(result, i->GetBuildingRect());
   }
   return result;
 }
 
 bool
 nsDisplayList::ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
                                         nsRegion* aVisibleRegion) {
   AUTO_PROFILER_LABEL("nsDisplayList::ComputeVisibilityForRoot", GRAPHICS);
@@ -2448,24 +2448,25 @@ nsDisplayList::ComputeVisibilityForSubli
 
   AutoTArray<nsDisplayItem*, 512> elements;
   MoveListTo(this, &elements);
 
   for (int32_t i = elements.Length() - 1; i >= 0; --i) {
     nsDisplayItem* item = elements[i];
 
     if (item->ForceNotVisible() && !item->GetSameCoordinateSystemChildren()) {
-      NS_ASSERTION(item->GetVisibleRect().IsEmpty(),
+      NS_ASSERTION(item->GetBuildingRect().IsEmpty(),
         "invisible items should have empty vis rect");
+      item->SetPaintRect(nsRect());
     } else {
       nsRect bounds = item->GetClippedBounds(aBuilder);
 
       nsRegion itemVisible;
       itemVisible.And(*aVisibleRegion, bounds);
-      item->SetVisibleRect(itemVisible.GetBounds(), false);
+      item->SetPaintRect(itemVisible.GetBounds());
     }
 
     if (item->ComputeVisibility(aBuilder, aVisibleRegion)) {
       anyVisible = true;
 
       nsRegion opaque = TreatAsOpaque(item, aBuilder);
       // Subtract opaque item from the visible region
       aBuilder->SubtractFromVisibleRegion(aVisibleRegion, opaque);
@@ -3135,17 +3136,17 @@ nsDisplayItem::nsDisplayItem(nsDisplayLi
                !aBuilder->IsForPainting(), "visible rect not set");
 
   SetClipChain(aBuilder->ClipState().GetCurrentCombinedClipChain(aBuilder), true);
 
   // The visible rect is for mCurrentFrame, so we have to use
   // mCurrentOffsetToReferenceFrame
   nsRect visible = aBuilder->GetVisibleRect() +
     aBuilder->GetCurrentFrameOffsetToReferenceFrame();
-  SetVisibleRect(visible, true);
+  SetBuildingRect(visible);
 }
 
 /* static */ bool
 nsDisplayItem::ForceActiveLayers()
 {
   static bool sForce = false;
   static bool sForceCached = false;
 
@@ -3175,49 +3176,50 @@ nsDisplayItem::ZIndex() const
 {
   return ZIndexForFrame(mFrame);
 }
 
 bool
 nsDisplayItem::ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                  nsRegion* aVisibleRegion)
 {
-  return !mVisibleRect.IsEmpty() &&
+  return !GetPaintRect().IsEmpty() &&
     !IsInvisibleInRect(aVisibleRegion->GetBounds());
 }
 
 bool
 nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder,
                                    nsRegion* aVisibleRegion,
                                    bool aUseClipBounds) {
   if (mForceNotVisible && !GetSameCoordinateSystemChildren()) {
     // mForceNotVisible wants to ensure that this display item doesn't render
     // anything itself. If this item has contents, then we obviously want to
     // render those, so we don't need this check in that case.
-    NS_ASSERTION(mVisibleRect.IsEmpty(),
+    NS_ASSERTION(GetBuildingRect().IsEmpty(),
       "invisible items without children should have empty vis rect");
+    SetPaintRect(nsRect());
   } else {
     nsRect bounds;
     if (aUseClipBounds) {
       bounds = GetClippedBounds(aBuilder);
     } else {
       bool snap;
       bounds = GetBounds(aBuilder, &snap);
     }
 
     nsRegion itemVisible;
     itemVisible.And(*aVisibleRegion, bounds);
-    SetVisibleRect(itemVisible.GetBounds(), false);
+    SetPaintRect(itemVisible.GetBounds());
   }
 
   // When we recompute visibility within layers we don't need to
   // expand the visible region for content behind plugins (the plugin
   // is not in the layer).
   if (!ComputeVisibility(aBuilder, aVisibleRegion)) {
-    SetVisibleRect(nsRect(), false);
+    SetPaintRect(nsRect());
     return false;
   }
 
   nsRegion opaque = TreatAsOpaque(this, aBuilder);
   aBuilder->SubtractFromVisibleRegion(aVisibleRegion, opaque);
   return true;
 }
 
@@ -3382,17 +3384,17 @@ nsDisplaySolidColor::BuildLayer(nsDispla
 
 void
 nsDisplaySolidColor::Paint(nsDisplayListBuilder* aBuilder,
                            gfxContext* aCtx)
 {
   int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
   DrawTarget* drawTarget = aCtx->GetDrawTarget();
   Rect rect =
-    NSRectToSnappedRect(mVisibleRect, appUnitsPerDevPixel, *drawTarget);
+    NSRectToSnappedRect(GetPaintRect(), appUnitsPerDevPixel, *drawTarget);
   drawTarget->FillRect(rect, ColorPattern(ToDeviceColor(mColor)));
 }
 
 void
 nsDisplaySolidColor::WriteDebugInfo(std::stringstream& aStream)
 {
   aStream << " (rgba "
           << (int)NS_GET_R(mColor) << ","
@@ -3404,17 +3406,17 @@ nsDisplaySolidColor::WriteDebugInfo(std:
 bool
 nsDisplaySolidColor::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                              mozilla::wr::IpcResourceUpdateQueue& aResources,
                                              const StackingContextHelper& aSc,
                                              mozilla::layers::WebRenderLayerManager* aManager,
                                              nsDisplayListBuilder* aDisplayListBuilder)
 {
   LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(
-        mVisibleRect, mFrame->PresContext()->AppUnitsPerDevPixel());
+        GetPaintRect(), mFrame->PresContext()->AppUnitsPerDevPixel());
   wr::LayoutRect roundedRect = wr::ToRoundedLayoutRect(bounds);
 
   aBuilder.PushRect(roundedRect,
                     roundedRect,
                     !BackfaceIsHidden(),
                     wr::ToColorF(ToDeviceColor(mColor)));
 
   return true;
@@ -3559,17 +3561,17 @@ nsDisplayBackgroundImage::nsDisplayBackg
   mBounds = GetBoundsInternal(aInitData.builder, aFrameForBounds);
   if (mShouldFixToViewport) {
     mAnimatedGeometryRoot = aInitData.builder->FindAnimatedGeometryRootFor(this);
 
     // Expand the item's visible rect to cover the entire bounds, limited to the
     // viewport rect. This is necessary because the background's clip can move
     // asynchronously.
     if (Maybe<nsRect> viewportRect = GetViewportRectRelativeToReferenceFrame(aInitData.builder, mFrame)) {
-      SetVisibleRect(mBounds.Intersect(*viewportRect), true);
+      SetBuildingRect(mBounds.Intersect(*viewportRect));
     }
   }
 }
 
 nsDisplayBackgroundImage::~nsDisplayBackgroundImage()
 {
 #ifdef NS_BUILD_REFCNT_LOGGING
   MOZ_COUNT_DTOR(nsDisplayBackgroundImage);
@@ -4145,17 +4147,17 @@ nsDisplayBackgroundImage::CreateWebRende
   ContainerLayerParameters parameter;
   if (!CanBuildWebRenderDisplayItems(aManager, aDisplayListBuilder)) {
     return false;
   }
 
   CheckForBorderItem(this, mImageFlags);
   nsCSSRendering::PaintBGParams params =
     nsCSSRendering::PaintBGParams::ForSingleLayer(*StyleFrame()->PresContext(),
-                                                  mVisibleRect, mBackgroundRect,
+                                                  GetPaintRect(), mBackgroundRect,
                                                   StyleFrame(), mImageFlags, mLayer,
                                                   CompositionOp::OP_OVER);
   params.bgClipRect = &mBounds;
   ImgDrawResult result =
     nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayer(params, aBuilder, aResources, aSc, aManager, this);
   nsDisplayBackgroundGeometry::UpdateDrawResult(this, result);
 
   return true;
@@ -4290,17 +4292,17 @@ nsDisplayBackgroundImage::RenderingMight
     return true;
   }
   return false;
 }
 
 void
 nsDisplayBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
                                 gfxContext* aCtx) {
-  PaintInternal(aBuilder, aCtx, mVisibleRect, &mBounds);
+  PaintInternal(aBuilder, aCtx, GetPaintRect(), &mBounds);
 }
 
 void
 nsDisplayBackgroundImage::PaintInternal(nsDisplayListBuilder* aBuilder,
                                         gfxContext* aCtx, const nsRect& aBounds,
                                         nsRect* aClipRect) {
   gfxContext* ctx = aCtx;
   StyleGeometryBox clip = mBackgroundStyle->StyleBackground()->mImage.mLayers[mLayer].mClip;
@@ -4503,17 +4505,17 @@ nsDisplayThemedBackground::GetPositionin
 {
   return mBackgroundRect;
 }
 
 void
 nsDisplayThemedBackground::Paint(nsDisplayListBuilder* aBuilder,
                                  gfxContext* aCtx)
 {
-  PaintInternal(aBuilder, aCtx, mVisibleRect, nullptr);
+  PaintInternal(aBuilder, aCtx, GetPaintRect(), nullptr);
 }
 
 
 void
 nsDisplayThemedBackground::PaintInternal(nsDisplayListBuilder* aBuilder,
                                          gfxContext* aCtx, const nsRect& aBounds,
                                          nsRect* aClipRect)
 {
@@ -4954,17 +4956,17 @@ void
 nsDisplayOutline::Paint(nsDisplayListBuilder* aBuilder,
                         gfxContext* aCtx) {
   // TODO join outlines together
   MOZ_ASSERT(mFrame->StyleOutline()->ShouldPaintOutline(),
              "Should have not created a nsDisplayOutline!");
 
   nsPoint offset = ToReferenceFrame();
   nsCSSRendering::PaintOutline(mFrame->PresContext(), *aCtx, mFrame,
-                               mVisibleRect,
+                               GetPaintRect(),
                                nsRect(offset, mFrame->GetSize()),
                                mFrame->Style());
 }
 
 bool
 nsDisplayOutline::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                           mozilla::wr::IpcResourceUpdateQueue& aResources,
                                           const StackingContextHelper& aSc,
@@ -4982,17 +4984,17 @@ nsDisplayOutline::CreateWebRenderCommand
       }
   }
 
   nsPoint offset = ToReferenceFrame();
 
   mozilla::Maybe<nsCSSBorderRenderer> borderRenderer =
     nsCSSRendering::CreateBorderRendererForOutline(mFrame->PresContext(),
                                                    nullptr, mFrame,
-                                                   mVisibleRect,
+                                                   GetPaintRect(),
                                                    nsRect(offset, mFrame->GetSize()),
                                                    mFrame->Style());
 
   if (!borderRenderer) {
     return false;
   }
 
   borderRenderer->CreateWebRenderCommands(this, aBuilder, aResources, aSc);
@@ -5704,17 +5706,17 @@ nsDisplayBorder::Paint(nsDisplayListBuil
   nsPoint offset = ToReferenceFrame();
 
   PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages()
                          ? PaintBorderFlags::SYNC_DECODE_IMAGES
                          : PaintBorderFlags();
 
   ImgDrawResult result =
     nsCSSRendering::PaintBorder(mFrame->PresContext(), *aCtx, mFrame,
-                                mVisibleRect,
+                                GetPaintRect(),
                                 nsRect(offset, mFrame->GetSize()),
                                 mFrame->Style(),
                                 flags,
                                 mFrame->GetSkipSides());
 
   nsDisplayBorderGeometry::UpdateDrawResult(this, result);
 }
 
@@ -5809,17 +5811,17 @@ nsDisplayBoxShadowOuter::IsInvisibleInRe
 
 bool
 nsDisplayBoxShadowOuter::ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                            nsRegion* aVisibleRegion) {
   if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion)) {
     return false;
   }
 
-  mVisibleRegion.And(*aVisibleRegion, mVisibleRect);
+  mVisibleRegion.And(*aVisibleRegion, GetPaintRect());
   return true;
 }
 
 bool
 nsDisplayBoxShadowOuter::CanBuildWebRenderDisplayItems()
 {
   nsCSSShadowArray* shadows = mFrame->StyleEffects()->mBoxShadow;
   if (!shadows) {
@@ -6102,17 +6104,17 @@ nsDisplayBoxShadowInner::CreateWebRender
 
 bool
 nsDisplayBoxShadowInner::ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                            nsRegion* aVisibleRegion) {
   if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion)) {
     return false;
   }
 
-  mVisibleRegion.And(*aVisibleRegion, mVisibleRect);
+  mVisibleRegion.And(*aVisibleRegion, GetPaintRect());
   return true;
 }
 
 nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
                                      nsIFrame* aFrame, nsDisplayList* aList, bool aAnonymous)
   : nsDisplayWrapList(aBuilder, aFrame, aList,
                       aBuilder->CurrentActiveScrolledRoot(), false, 0, aAnonymous)
 {}
@@ -6127,17 +6129,17 @@ nsDisplayWrapList::nsDisplayWrapList(nsD
   , mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot())
   , mOverrideZIndex(0)
   , mIndex(aIndex)
   , mHasZIndexOverride(false)
   , mClearingClipChain(aClearClipChain)
 {
   MOZ_COUNT_CTOR(nsDisplayWrapList);
 
-  mBaseVisibleRect = mVisibleRect;
+  mBaseBuildingRect = GetBuildingRect();
 
   mListPtr = &mList;
   mListPtr->AppendToTop(aList);
   UpdateBounds(aBuilder);
 
   if (!aFrame || !aFrame->IsTransformed()) {
     return;
   }
@@ -6157,29 +6159,29 @@ nsDisplayWrapList::nsDisplayWrapList(nsD
       i->Frame() == mFrame) {
     mReferenceFrame = i->ReferenceFrame();
     mToReferenceFrame = i->ToReferenceFrame();
   }
 
   nsRect visible = aBuilder->GetVisibleRect() +
     aBuilder->GetCurrentFrameOffsetToReferenceFrame();
 
-  SetVisibleRect(visible, true);
+  SetBuildingRect(visible);
 }
 
 nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
                                      nsIFrame* aFrame, nsDisplayItem* aItem, bool aAnonymous)
   : nsDisplayItem(aBuilder, aFrame, aBuilder->CurrentActiveScrolledRoot(), aAnonymous)
   , mOverrideZIndex(0)
   , mIndex(0)
   , mHasZIndexOverride(false)
 {
   MOZ_COUNT_CTOR(nsDisplayWrapList);
 
-  mBaseVisibleRect = mVisibleRect;
+  mBaseBuildingRect = GetBuildingRect();
 
   mListPtr = &mList;
   mListPtr->AppendToTop(aItem);
   UpdateBounds(aBuilder);
 
   if (!aFrame || !aFrame->IsTransformed()) {
     return;
   }
@@ -6188,17 +6190,17 @@ nsDisplayWrapList::nsDisplayWrapList(nsD
   if (aItem->Frame() == aFrame) {
     mReferenceFrame = aItem->ReferenceFrame();
     mToReferenceFrame = aItem->ToReferenceFrame();
   }
 
   nsRect visible = aBuilder->GetVisibleRect() +
     aBuilder->GetCurrentFrameOffsetToReferenceFrame();
 
-  SetVisibleRect(visible, true);
+  SetBuildingRect(visible);
 }
 
 nsDisplayWrapList::~nsDisplayWrapList() {
   MOZ_COUNT_DTOR(nsDisplayWrapList);
 }
 
 void
 nsDisplayWrapList::MergeDisplayListFromItem(nsDisplayListBuilder* aBuilder,
@@ -6233,23 +6235,23 @@ nsDisplayWrapList::GetBounds(nsDisplayLi
 }
 
 bool
 nsDisplayWrapList::ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                      nsRegion* aVisibleRegion) {
   // Convert the passed in visible region to our appunits.
   nsRegion visibleRegion;
   // mVisibleRect has been clipped to GetClippedBounds
-  visibleRegion.And(*aVisibleRegion, mVisibleRect);
+  visibleRegion.And(*aVisibleRegion, GetPaintRect());
   nsRegion originalVisibleRegion = visibleRegion;
 
   bool retval =
     mListPtr->ComputeVisibilityForSublist(aBuilder,
                                           &visibleRegion,
-                                          mVisibleRect);
+                                          GetPaintRect());
   nsRegion removed;
   // removed = originalVisibleRegion - visibleRegion
   removed.Sub(originalVisibleRegion, visibleRegion);
   // aVisibleRegion = aVisibleRegion - removed (modulo any simplifications
   // SubtractFromVisibleRegion does)
   aBuilder->SubtractFromVisibleRegion(aVisibleRegion, removed);
 
   return retval;
@@ -7854,22 +7856,22 @@ void nsDisplayZoom::HitTest(nsDisplayLis
 }
 
 bool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder,
                                       nsRegion *aVisibleRegion)
 {
   // Convert the passed in visible region to our appunits.
   nsRegion visibleRegion;
   // mVisibleRect has been clipped to GetClippedBounds
-  visibleRegion.And(*aVisibleRegion, mVisibleRect);
+  visibleRegion.And(*aVisibleRegion, GetPaintRect());
   visibleRegion = visibleRegion.ScaleToOtherAppUnitsRoundOut(mParentAPD, mAPD);
   nsRegion originalVisibleRegion = visibleRegion;
 
   nsRect transformedVisibleRect =
-    mVisibleRect.ScaleToOtherAppUnitsRoundOut(mParentAPD, mAPD);
+    GetPaintRect().ScaleToOtherAppUnitsRoundOut(mParentAPD, mAPD);
   bool retval;
   // If we are to generate a scrollable layer we call
   // nsDisplaySubDocument::ComputeVisibility to make the necessary adjustments
   // for ComputeVisibility, it does all it's calculations in the child APD.
   bool usingDisplayPort = UseDisplayPortForViewport(aBuilder, mFrame);
   if (!(mFlags & nsDisplayOwnLayerFlags::eGenerateScrollableLayer) || !usingDisplayPort) {
     retval =
       mList.ComputeVisibilityForSublist(aBuilder, &visibleRegion,
@@ -7904,25 +7906,25 @@ bool nsDisplayZoom::ComputeVisibility(ns
 // and consequently get the wrong value.  Write #define DEBUG_HIT here to have
 // the nsDisplayTransform class dump out a bunch of information about hit
 // detection.
 #undef  UNIFIED_CONTINUATIONS
 #undef  DEBUG_HIT
 
 nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
                                        nsIFrame *aFrame, nsDisplayList *aList,
-                                       const nsRect& aChildrenVisibleRect,
+                                       const nsRect& aChildrenBuildingRect,
                                        ComputeTransformFunction aTransformGetter,
                                        uint32_t aIndex)
   : nsDisplayItem(aBuilder, aFrame)
   , mStoredList(aBuilder, aFrame, aList)
   , mTransformGetter(aTransformGetter)
   , mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot)
   , mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot)
-  , mChildrenVisibleRect(aChildrenVisibleRect)
+  , mChildrenBuildingRect(aChildrenBuildingRect)
   , mIndex(aIndex)
   , mNoExtendContext(false)
   , mIsTransformSeparator(false)
   , mTransformPreserves3DInited(false)
   , mAllowAsyncAnimation(false)
 {
   MOZ_COUNT_CTOR(nsDisplayTransform);
   MOZ_ASSERT(aFrame, "Must have a frame!");
@@ -7959,85 +7961,85 @@ nsDisplayTransform::SetReferenceFrameToA
       // so that FrameLayerBuilder knows that this layer moves with the transform
       // and won't compute occlusions. If we're not animated then use our parent
       // AGR so that inactive transform layers can go in the same PaintedLayer as
       // surrounding content.
       mAnimatedGeometryRoot = mAnimatedGeometryRoot->mParentAGR;
     }
   }
 
-  SetVisibleRect(aBuilder->GetVisibleRect() + mToReferenceFrame, true);
+  SetBuildingRect(aBuilder->GetVisibleRect() + mToReferenceFrame);
 }
 
 void
 nsDisplayTransform::Init(nsDisplayListBuilder* aBuilder)
 {
   mHasBounds = false;
   mStoredList.SetClipChain(nullptr, true);
-  mStoredList.SetVisibleRect(mChildrenVisibleRect, true);
+  mStoredList.SetBuildingRect(mChildrenBuildingRect);
 }
 
 nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
                                        nsIFrame *aFrame, nsDisplayList *aList,
-                                       const nsRect& aChildrenVisibleRect,
+                                       const nsRect& aChildrenBuildingRect,
                                        uint32_t aIndex,
                                        bool aAllowAsyncAnimation)
   : nsDisplayItem(aBuilder, aFrame)
   , mStoredList(aBuilder, aFrame, aList)
   , mTransformGetter(nullptr)
   , mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot)
   , mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot)
-  , mChildrenVisibleRect(aChildrenVisibleRect)
+  , mChildrenBuildingRect(aChildrenBuildingRect)
   , mIndex(aIndex)
   , mNoExtendContext(false)
   , mIsTransformSeparator(false)
   , mTransformPreserves3DInited(false)
   , mAllowAsyncAnimation(aAllowAsyncAnimation)
 {
   MOZ_COUNT_CTOR(nsDisplayTransform);
   MOZ_ASSERT(aFrame, "Must have a frame!");
   SetReferenceFrameToAncestor(aBuilder);
   Init(aBuilder);
   UpdateBoundsFor3D(aBuilder);
 }
 
 nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
                                        nsIFrame *aFrame, nsDisplayItem *aItem,
-                                       const nsRect& aChildrenVisibleRect,
+                                       const nsRect& aChildrenBuildingRect,
                                        uint32_t aIndex)
   : nsDisplayItem(aBuilder, aFrame)
   , mStoredList(aBuilder, aFrame, aItem)
   , mTransformGetter(nullptr)
   , mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot)
   , mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot)
-  , mChildrenVisibleRect(aChildrenVisibleRect)
+  , mChildrenBuildingRect(aChildrenBuildingRect)
   , mIndex(aIndex)
   , mNoExtendContext(false)
   , mIsTransformSeparator(false)
   , mTransformPreserves3DInited(false)
   , mAllowAsyncAnimation(false)
 {
   MOZ_COUNT_CTOR(nsDisplayTransform);
   MOZ_ASSERT(aFrame, "Must have a frame!");
   SetReferenceFrameToAncestor(aBuilder);
   Init(aBuilder);
 }
 
 nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
                                        nsIFrame *aFrame, nsDisplayList *aList,
-                                       const nsRect& aChildrenVisibleRect,
+                                       const nsRect& aChildrenBuildingRect,
                                        const Matrix4x4& aTransform,
                                        uint32_t aIndex)
   : nsDisplayItem(aBuilder, aFrame)
   , mStoredList(aBuilder, aFrame, aList)
   , mTransform(aTransform)
   , mTransformGetter(nullptr)
   , mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot)
   , mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot)
-  , mChildrenVisibleRect(aChildrenVisibleRect)
+  , mChildrenBuildingRect(aChildrenBuildingRect)
   , mIndex(aIndex)
   , mNoExtendContext(false)
   , mIsTransformSeparator(true)
   , mTransformPreserves3DInited(false)
   , mAllowAsyncAnimation(false)
 {
   MOZ_COUNT_CTOR(nsDisplayTransform);
   MOZ_ASSERT(aFrame, "Must have a frame!");
@@ -8785,17 +8787,17 @@ bool nsDisplayTransform::ComputeVisibili
     return true;
   }
 
   /* As we do this, we need to be sure to
    * untransform the visible rect, since we want everything that's painting to
    * think that it's painting in its original rectangular coordinate space.
    * If we can't untransform, take the entire overflow rect */
   nsRect untransformedVisibleRect;
-  if (!UntransformVisibleRect(aBuilder, &untransformedVisibleRect))
+  if (!UntransformPaintRect(aBuilder, &untransformedVisibleRect))
   {
     untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf();
   }
   nsRegion untransformedVisible = untransformedVisibleRect;
   // Call RecomputeVisiblity instead of ComputeVisibility since
   // nsDisplayItem::ComputeVisibility should only be called from
   // nsDisplayList::ComputeVisibility (which sets mVisibleRect on the item)
   mStoredList.RecomputeVisibility(aBuilder, &untransformedVisible);
@@ -9001,50 +9003,50 @@ nsDisplayTransform::ComputeBounds(nsDisp
  * certainly contains the actual (non-axis-aligned) untransformed rect.
  */
 nsRegion
 nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
                                              bool* aSnap) const
 {
   *aSnap = false;
   nsRect untransformedVisible;
-  if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) {
+  if (!UntransformBuildingRect(aBuilder, &untransformedVisible)) {
       return nsRegion();
   }
 
   const Matrix4x4Flagged& matrix = GetTransform();
 
   nsRegion result;
   Matrix matrix2d;
   bool tmpSnap;
   if (matrix.Is2D(&matrix2d) &&
       matrix2d.PreservesAxisAlignedRectangles() &&
       mStoredList.GetOpaqueRegion(aBuilder, &tmpSnap).Contains(untransformedVisible)) {
-    result = mVisibleRect.Intersect(GetBounds(aBuilder, &tmpSnap));
+    result = GetBuildingRect().Intersect(GetBounds(aBuilder, &tmpSnap));
   }
   return result;
 }
 
 /* The transform is uniform if it fills the entire bounding rect and the
  * wrapped list is uniform.  See GetOpaqueRegion for discussion of why this
  * works.
  */
 Maybe<nscolor>
 nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder) const
 {
   nsRect untransformedVisible;
-  if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) {
+  if (!UntransformBuildingRect(aBuilder, &untransformedVisible)) {
     return Nothing();
   }
   const Matrix4x4Flagged& matrix = GetTransform();
 
   Matrix matrix2d;
   if (matrix.Is2D(&matrix2d) &&
       matrix2d.PreservesAxisAlignedRectangles() &&
-      mStoredList.GetVisibleRect().Contains(untransformedVisible)) {
+      mStoredList.GetBuildingRect().Contains(untransformedVisible)) {
     return mStoredList.IsUniform(aBuilder);
   }
 
   return Nothing();
 }
 
 /* TransformRect takes in as parameters a rectangle (in app space) and returns
  * the smallest rectangle (in app space) containing the transformed image of
@@ -9101,29 +9103,30 @@ bool nsDisplayTransform::UntransformRect
                             NSAppUnitsToFloatPixels(aChildBounds.width, factor),
                             NSAppUnitsToFloatPixels(aChildBounds.height, factor));
 
   result = transform.Inverse().ProjectRectBounds(result, childGfxBounds);
   *aOutRect = nsLayoutUtils::RoundGfxRectToAppRect(ThebesRect(result), factor);
   return true;
 }
 
-bool nsDisplayTransform::UntransformVisibleRect(nsDisplayListBuilder* aBuilder,
-                                                nsRect *aOutRect) const
+bool nsDisplayTransform::UntransformRect(nsDisplayListBuilder* aBuilder,
+                                         const nsRect& aRect,
+                                         nsRect *aOutRect) const
 {
   const Matrix4x4Flagged& matrix = GetTransform();
   if (matrix.IsSingular())
     return false;
 
   // GetTransform always operates in dev pixels.
   float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
-  RectDouble result(NSAppUnitsToFloatPixels(mVisibleRect.x, factor),
-                    NSAppUnitsToFloatPixels(mVisibleRect.y, factor),
-                    NSAppUnitsToFloatPixels(mVisibleRect.width, factor),
-                    NSAppUnitsToFloatPixels(mVisibleRect.height, factor));
+  RectDouble result(NSAppUnitsToFloatPixels(aRect.x, factor),
+                    NSAppUnitsToFloatPixels(aRect.y, factor),
+                    NSAppUnitsToFloatPixels(aRect.width, factor),
+                    NSAppUnitsToFloatPixels(aRect.height, factor));
 
   bool snap;
   nsRect childBounds = mStoredList.GetBounds(aBuilder, &snap);
   RectDouble childGfxBounds(NSAppUnitsToFloatPixels(childBounds.x, factor),
                             NSAppUnitsToFloatPixels(childBounds.y, factor),
                             NSAppUnitsToFloatPixels(childBounds.width, factor),
                             NSAppUnitsToFloatPixels(childBounds.height, factor));
 
@@ -9604,17 +9607,17 @@ nsDisplayMask::PaintMask(nsDisplayListBu
 {
   MOZ_ASSERT(aMaskContext->GetDrawTarget()->GetFormat() == SurfaceFormat::A8);
 
   imgDrawingParams imgParmas(aBuilder->ShouldSyncDecodeImages()
                              ? imgIContainer::FLAG_SYNC_DECODE
                              : imgIContainer::FLAG_SYNC_DECODE_IF_FAST);
   nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
   nsSVGIntegrationUtils::PaintFramesParams params(*aMaskContext,
-                                                  mFrame,  mVisibleRect,
+                                                  mFrame,  GetPaintRect(),
                                                   borderArea, aBuilder,
                                                   nullptr,
                                                   mHandleOpacity, imgParmas);
   ComputeMaskGeometry(params);
   nsSVGIntegrationUtils::PaintMask(params);
 
   nsDisplayMaskGeometry::UpdateDrawResult(this, imgParmas.result);
 
@@ -9653,18 +9656,18 @@ bool nsDisplayMask::CanPaintOnMaskLayer(
   return true;
 }
 
 bool nsDisplayMask::ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                       nsRegion* aVisibleRegion)
 {
   // Our children may be made translucent or arbitrarily deformed so we should
   // not allow them to subtract area from aVisibleRegion.
-  nsRegion childrenVisible(mVisibleRect);
-  nsRect r = mVisibleRect.Intersect(mList.GetBounds(aBuilder));
+  nsRegion childrenVisible(GetPaintRect());
+  nsRect r = GetPaintRect().Intersect(mList.GetBounds(aBuilder));
   mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r);
   return true;
 }
 
 void
 nsDisplayMask::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion* aInvalidRegion) const
@@ -9711,26 +9714,26 @@ nsDisplayMask::PaintAsLayer(nsDisplayLis
                             gfxContext* aCtx,
                             LayerManager* aManager)
 {
   // Clip the drawing target by mVisibleRect, which contains the visible
   // region of the target frame and its out-of-flow and inflow descendants.
   gfxContext* context = aCtx;
 
   Rect bounds =
-    NSRectToRect(mVisibleRect, mFrame->PresContext()->AppUnitsPerDevPixel());
+    NSRectToRect(GetPaintRect(), mFrame->PresContext()->AppUnitsPerDevPixel());
   bounds.RoundOut();
   context->Clip(bounds);
 
   imgDrawingParams imgParams(aBuilder->ShouldSyncDecodeImages()
                              ? imgIContainer::FLAG_SYNC_DECODE
                              : imgIContainer::FLAG_SYNC_DECODE_IF_FAST);
   nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
   nsSVGIntegrationUtils::PaintFramesParams params(*aCtx,
-                                                  mFrame,  mVisibleRect,
+                                                  mFrame,  GetPaintRect(),
                                                   borderArea, aBuilder,
                                                   aManager,
                                                   mHandleOpacity, imgParams);
 
   ComputeMaskGeometry(params);
 
   nsSVGIntegrationUtils::PaintMaskAndClipPath(params);
 
@@ -9920,17 +9923,17 @@ nsDisplayFilter::GetLayerState(nsDisplay
 
 bool
 nsDisplayFilter::ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                    nsRegion* aVisibleRegion)
 {
   nsPoint offset = ToReferenceFrame();
   nsRect dirtyRect =
     nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(mFrame,
-                                                           mVisibleRect - offset) +
+                                                           GetPaintRect() - offset) +
     offset;
 
   // Our children may be made translucent or arbitrarily deformed so we should
   // not allow them to subtract area from aVisibleRegion.
   nsRegion childrenVisible(dirtyRect);
   nsRect r = dirtyRect.Intersect(
     mList.GetClippedBoundsWithRespectToASR(aBuilder, mActiveScrolledRoot));
   mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r);
@@ -9961,17 +9964,17 @@ nsDisplayFilter::PaintAsLayer(nsDisplayL
                               gfxContext* aCtx,
                               LayerManager* aManager)
 {
   imgDrawingParams imgParams(aBuilder->ShouldSyncDecodeImages()
                              ? imgIContainer::FLAG_SYNC_DECODE
                              : imgIContainer::FLAG_SYNC_DECODE_IF_FAST);
   nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
   nsSVGIntegrationUtils::PaintFramesParams params(*aCtx,
-                                                  mFrame,  mVisibleRect,
+                                                  mFrame,  GetPaintRect(),
                                                   borderArea, aBuilder,
                                                   aManager,
                                                   mHandleOpacity, imgParams);
   nsSVGIntegrationUtils::PaintFilter(params);
   nsDisplayFilterGeometry::UpdateDrawResult(this, imgParams.result);
 }
 
 static float
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -2137,17 +2137,16 @@ public:
   {
     DisplayItemType type = GetType();
     this->~nsDisplayItem();
     aBuilder->Destroy(type, this);
   }
 
   virtual void RestoreState()
   {
-    mVisibleRect = mState.mVisibleRect;
     mClipChain = mState.mClipChain;
     mClip = mState.mClip;
     mDisableSubpixelAA = false;
   }
 
   virtual void RemoveFrame(nsIFrame* aFrame)
   {
     if (mFrame && aFrame == mFrame) {
@@ -2180,17 +2179,18 @@ public:
   nsDisplayItem(nsDisplayListBuilder* aBuilder, const nsDisplayItem& aOther)
     : mFrame(aOther.mFrame)
     , mClipChain(aOther.mClipChain)
     , mClip(aOther.mClip)
     , mActiveScrolledRoot(aOther.mActiveScrolledRoot)
     , mReferenceFrame(aOther.mReferenceFrame)
     , mAnimatedGeometryRoot(aOther.mAnimatedGeometryRoot)
     , mToReferenceFrame(aOther.mToReferenceFrame)
-    , mVisibleRect(aOther.mVisibleRect)
+    , mBuildingRect(aOther.mBuildingRect)
+    , mPaintRect(aOther.mPaintRect)
     , mForceNotVisible(aOther.mForceNotVisible)
     , mDisableSubpixelAA(aOther.mDisableSubpixelAA)
     , mReusedItem(false)
     , mBackfaceHidden(mFrame->In3DContextAndBackfaceIsHidden())
 #ifdef MOZ_DUMP_PAINTING
     , mPainted(false)
 #endif
   {
@@ -2660,36 +2660,37 @@ public:
 
   /**
    * If this has a child list, return it, even if the children are in
    * a different coordinate system to this item.
    */
   virtual RetainedDisplayList* GetChildren() const { return nullptr; }
 
   /**
-   * Returns the visible rect.
-   */
-  const nsRect& GetVisibleRect() const { return mVisibleRect; }
-
-  void SetVisibleRect(const nsRect& aVisibleRect, bool aStore)
-  {
-    mVisibleRect = aVisibleRect;
-
-    if (aStore) {
-      mState.mVisibleRect = mVisibleRect;
-    }
-  }
-
-  /**
-   * Returns the visible rect for the children, relative to their
-   * reference frame. Can be different from mVisibleRect for nsDisplayTransform,
+   * Returns the building rectangle used by nsDisplayListBuilder when
+   * this item was constructed.
+   */
+  const nsRect& GetBuildingRect() const { return mBuildingRect; }
+
+  void SetBuildingRect(const nsRect& aBuildingRect)
+  {
+    mPaintRect = mBuildingRect = aBuildingRect;
+  }
+
+  void SetPaintRect(const nsRect& aPaintRect) {
+    mPaintRect = aPaintRect;
+  }
+
+  /**
+   * Returns the building rect for the children, relative to their
+   * reference frame. Can be different from mBuildingRect for nsDisplayTransform,
    * since the reference frame for the children is different from the reference
    * frame for the item itself.
    */
-  virtual const nsRect& GetVisibleRectForChildren() const { return mVisibleRect; }
+  virtual const nsRect& GetBuildingRectForChildren() const { return mBuildingRect; }
 
   /**
    * Stores the given opacity value to be applied when drawing. It is an error to
    * call this if CanApplyOpacity returned false.
    */
   virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
                             float aOpacity,
                             const DisplayItemClipChain* aClip) {
@@ -2860,16 +2861,20 @@ public:
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
     if (mOldList != reinterpret_cast<uintptr_t>(aList)) {
       MOZ_CRASH_UNSAFE_PRINTF("Item found was in the wrong list! type %d", GetPerFrameKey());
     }
 #endif
     return mOldListIndex;
   }
 
+  const nsRect& GetPaintRect() const {
+    return mPaintRect;
+  }
+
 protected:
   nsDisplayItem() = delete;
 
   typedef bool (*PrefFunc)(void);
   bool ShouldUseAdvancedLayer(LayerManager* aManager, PrefFunc aFunc) const;
   bool CanUseAdvancedLayer(LayerManager* aManager) const;
 
   nsIFrame* mFrame;
@@ -2877,23 +2882,29 @@ protected:
   const DisplayItemClip* mClip;
   RefPtr<const ActiveScrolledRoot> mActiveScrolledRoot;
   // Result of FindReferenceFrameFor(mFrame), if mFrame is non-null
   const nsIFrame* mReferenceFrame;
   RefPtr<struct AnimatedGeometryRoot> mAnimatedGeometryRoot;
   // Result of ToReferenceFrame(mFrame), if mFrame is non-null
   nsPoint   mToReferenceFrame;
   RefPtr<mozilla::DisplayItemData> mDisplayItemData;
-  // This is the rectangle that needs to be painted.
-  // Display item construction sets this to the dirty rect.
+
+private:
+  // This is the rectangle that nsDisplayListBuilder was using as the visible
+  // rect to decide which items to construct.
+  nsRect    mBuildingRect;
+
   // nsDisplayList::ComputeVisibility sets this to the visible region
-  // of the item by intersecting the current visible region with the bounds
+  // of the item by intersecting the visible region with the bounds
   // of the item. Paint implementations can use this to limit their drawing.
   // Guaranteed to be contained in GetBounds().
-  nsRect    mVisibleRect;
+  nsRect    mPaintRect;
+
+protected:
 
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
 public:
   uintptr_t mOldList = 0;
   bool mMergedItem = false;
   bool mPreProcessedItem = false;
 protected:
 #endif
@@ -2904,17 +2915,16 @@ protected:
   bool      mReusedItem;
   bool      mBackfaceHidden;
 #ifdef MOZ_DUMP_PAINTING
   // True if this frame has been painted.
   bool      mPainted;
 #endif
 
   struct {
-    nsRect mVisibleRect;
     RefPtr<const DisplayItemClipChain> mClipChain;
     const DisplayItemClip* mClip;
   } mState;
 };
 
 /**
  * Manages a singly-linked list of display list items.
  *
@@ -3181,37 +3191,37 @@ public:
    * Get this list's bounds, respecting clips relative to aASR. The result is
    * the union of each item's clipped bounds with respect to aASR. That means
    * that if an item can move asynchronously with an ASR that is a descendant
    * of aASR, then the clipped bounds with respect to aASR will be the clip of
    * that item for aASR, because the item can move anywhere inside that clip.
    * If there is an item in this list which is not bounded with respect to
    * aASR (i.e. which does not have "finite bounds" with respect to aASR),
    * then this method trigger an assertion failure.
-   * The optional aVisibleRect out argument can be set to non-null if the
-   * caller is also interested to know the visible rect.  This can be used
+   * The optional aBuildingRect out argument can be set to non-null if the
+   * caller is also interested to know the building rect.  This can be used
    * to get the visible rect efficiently without traversing the display list
    * twice.
    */
   nsRect GetClippedBoundsWithRespectToASR(nsDisplayListBuilder* aBuilder,
                                           const ActiveScrolledRoot* aASR,
-                                          nsRect* aVisibleRect = nullptr) const;
+                                          nsRect* aBuildingRect = nullptr) const;
 
   /**
    * Find the topmost display item that returns a non-null frame, and return
    * the frame.
    */
   void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                nsDisplayItem::HitTestState* aState,
                nsTArray<nsIFrame*> *aOutFrames) const;
   /**
    * Compute the union of the visible rects of the items in the list. The
    * result is not cached.
    */
-  nsRect GetVisibleRect() const;
+  nsRect GetBuildingRect() const;
 
   void SetIsOpaque()
   {
     mIsOpaque = true;
   }
   void SetNeedsTransparentSurface()
   {
     mForceTransparentSurface = true;
@@ -3579,19 +3589,19 @@ public:
     MOZ_COUNT_DTOR(nsDisplayGeneric);
   }
 #endif
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      gfxContext* aCtx) override {
     MOZ_ASSERT(!!mPaint != !!mOldPaint);
     if (mPaint) {
-      mPaint(mFrame, aCtx->GetDrawTarget(), mVisibleRect, ToReferenceFrame());
+      mPaint(mFrame, aCtx->GetDrawTarget(), GetPaintRect(), ToReferenceFrame());
     } else {
-      mOldPaint(mFrame, aCtx, mVisibleRect, ToReferenceFrame());
+      mOldPaint(mFrame, aCtx, GetPaintRect(), ToReferenceFrame());
     }
   }
   virtual const char* Name() const override { return mName; }
   virtual DisplayItemType GetType() const override { return mType; }
 
   // This override is needed because GetType() for nsDisplayGeneric subclasses
   // does not match TYPE_GENERIC that was used to allocate the object.
   virtual void Destroy(nsDisplayListBuilder* aBuilder) override
@@ -5035,32 +5045,32 @@ public:
   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
     : nsDisplayItem(aBuilder, aFrame)
     , mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot())
     , mOverrideZIndex(0)
     , mIndex(0)
     , mHasZIndexOverride(false)
   {
     MOZ_COUNT_CTOR(nsDisplayWrapList);
-    mBaseVisibleRect = mVisibleRect;
+    mBaseBuildingRect = GetBuildingRect();
     mListPtr = &mList;
   }
 
   /**
    * A custom copy-constructor that does not copy mList, as this would mutate
    * the other item.
    */
   nsDisplayWrapList(const nsDisplayWrapList& aOther) = delete;
   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, const nsDisplayWrapList& aOther)
     : nsDisplayItem(aBuilder, aOther)
     , mListPtr(&mList)
     , mFrameActiveScrolledRoot(aOther.mFrameActiveScrolledRoot)
     , mMergedFrames(aOther.mMergedFrames)
     , mBounds(aOther.mBounds)
-    , mBaseVisibleRect(aOther.mBaseVisibleRect)
+    , mBaseBuildingRect(aOther.mBaseBuildingRect)
     , mOverrideZIndex(aOther.mOverrideZIndex)
     , mIndex(aOther.mIndex)
     , mHasZIndexOverride(aOther.mHasZIndexOverride)
     , mClearingClipChain(aOther.mClearingClipChain)
   {
     MOZ_COUNT_CTOR(nsDisplayWrapList);
   }
 
@@ -5098,28 +5108,28 @@ public:
     if (mClearingClipChain) {
       const DisplayItemClipChain* clip = mState.mClipChain;
       while (clip && ActiveScrolledRoot::IsAncestor(GetActiveScrolledRoot(), clip->mASR)) {
         clip = clip->mParent;
       }
       SetClipChain(clip, false);
     }
 
-    nsRect visibleRect;
+    nsRect buildingRect;
     mBounds =
-      mListPtr->GetClippedBoundsWithRespectToASR(aBuilder, mActiveScrolledRoot, &visibleRect);
+      mListPtr->GetClippedBoundsWithRespectToASR(aBuilder, mActiveScrolledRoot, &buildingRect);
     // The display list may contain content that's visible outside the visible
     // rect (i.e. the current dirty rect) passed in when the item was created.
     // This happens when the dirty rect has been restricted to the visual
     // overflow rect of a frame for some reason (e.g. when setting up dirty
     // rects in nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay), but that
     // frame contains placeholders for out-of-flows that aren't descendants of
     // the frame.
-    mVisibleRect.UnionRect(mBaseVisibleRect, visibleRect);
-    mState.mVisibleRect = mVisibleRect;
+    buildingRect.UnionRect(mBaseBuildingRect, buildingRect);
+    SetBuildingRect(buildingRect);
   }
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
                            bool* aSnap) const override;
   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                                    bool* aSnap) const override;
   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
@@ -5223,33 +5233,35 @@ public:
   const ActiveScrolledRoot* GetFrameActiveScrolledRoot() { return mFrameActiveScrolledRoot; }
 
 protected:
   nsDisplayWrapList() = delete;
 
   void MergeFromTrackingMergedFrames(const nsDisplayWrapList* aOther)
   {
     mBounds.UnionRect(mBounds, aOther->mBounds);
-    mVisibleRect.UnionRect(mVisibleRect, aOther->mVisibleRect);
+    nsRect buildingRect;
+    buildingRect.UnionRect(GetBuildingRect(), aOther->GetBuildingRect());
+    SetBuildingRect(buildingRect);
     mMergedFrames.AppendElement(aOther->mFrame);
     mMergedFrames.AppendElements(aOther->mMergedFrames);
   }
 
   RetainedDisplayList mList;
   RetainedDisplayList* mListPtr;
   // The active scrolled root for the frame that created this
   // wrap list.
   RefPtr<const ActiveScrolledRoot> mFrameActiveScrolledRoot;
   // The frames from items that have been merged into this item, excluding
   // this item's own frame.
   nsTArray<nsIFrame*> mMergedFrames;
   nsRect mBounds;
-  // Visible rect contributed by this display item itself.
-  // Our mVisibleRect may include the visible areas of children.
-  nsRect mBaseVisibleRect;
+  // Displaylist building rect contributed by this display item itself.
+  // Our mBuildingRect may include the visible areas of children.
+  nsRect mBaseBuildingRect;
   int32_t mOverrideZIndex;
   uint32_t mIndex;
   bool mHasZIndexOverride;
   bool mClearingClipChain = false;
 };
 
 /**
  * We call WrapDisplayList on the in-flow lists: BorderBackground(),
@@ -6344,26 +6356,26 @@ public:
    * @param aAppUnitsPerPixel The number of app units per graphics unit.
    */
   typedef Matrix4x4 (* ComputeTransformFunction)(nsIFrame* aFrame, float aAppUnitsPerPixel);
 
   /* Constructor accepts a display list, empties it, and wraps it up.  It also
    * ferries the underlying frame to the nsDisplayItem constructor.
    */
   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
-                     nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
+                     nsDisplayList *aList, const nsRect& aChildrenBuildingRect,
                      uint32_t aIndex = 0, bool aAllowAsyncAnimation = false);
   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
-                     nsDisplayItem *aItem, const nsRect& aChildrenVisibleRect,
+                     nsDisplayItem *aItem, const nsRect& aChildrenBuildingRect,
                      uint32_t aIndex = 0);
   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
-                     nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
+                     nsDisplayList *aList, const nsRect& aChildrenBuildingRect,
                      ComputeTransformFunction aTransformGetter, uint32_t aIndex = 0);
   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
-                     nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
+                     nsDisplayList *aList, const nsRect& aChildrenBuildingRect,
                      const Matrix4x4& aTransform, uint32_t aIndex = 0);
 
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayTransform()
   {
     MOZ_COUNT_DTOR(nsDisplayTransform);
   }
 #endif
@@ -6455,19 +6467,19 @@ public:
     }
     return nsDisplayItem::ReferenceFrameForChildren();
   }
 
   AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override {
     return mAnimatedGeometryRootForScrollMetadata;
   }
 
-  virtual const nsRect& GetVisibleRectForChildren() const override
-  {
-    return mChildrenVisibleRect;
+  virtual const nsRect& GetBuildingRectForChildren() const override
+  {
+    return mChildrenBuildingRect;
   }
 
   enum {
     INDEX_MAX = UINT32_MAX >> TYPE_BITS
   };
 
   /**
    * We include the perspective matrix from our containing block for the
@@ -6511,18 +6523,30 @@ public:
   /* UntransformRect is like TransformRect, except that it inverts the
    * transform.
    */
   static bool UntransformRect(const nsRect &aTransformedBounds,
                               const nsRect &aChildBounds,
                               const nsIFrame* aFrame,
                               nsRect *aOutRect);
 
-  bool UntransformVisibleRect(nsDisplayListBuilder* aBuilder,
-                              nsRect* aOutRect) const;
+  bool UntransformRect(nsDisplayListBuilder* aBuilder,
+                       const nsRect& aRect,
+                       nsRect* aOutRect) const;
+  bool UntransformBuildingRect(nsDisplayListBuilder* aBuilder,
+                               nsRect* aOutRect) const
+  {
+    return UntransformRect(aBuilder, GetBuildingRect(), aOutRect);
+
+  }
+  bool UntransformPaintRect(nsDisplayListBuilder* aBuilder,
+                            nsRect* aOutRect) const
+  {
+    return UntransformRect(aBuilder, GetPaintRect(), aOutRect);
+  }
 
   static Point3D GetDeltaToTransformOrigin(const nsIFrame* aFrame,
                                            float aAppUnitsPerPixel,
                                            const nsRect* aBoundsOverride);
 
   /*
    * Returns true if aFrame has perspective applied from its containing
    * block.
@@ -6683,17 +6707,17 @@ private:
 
   StoreList mStoredList;
   mutable Matrix4x4Flagged mTransform;
   // Accumulated transform of ancestors on the preserves-3d chain.
   Matrix4x4 mTransformPreserves3D;
   ComputeTransformFunction mTransformGetter;
   RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForChildren;
   RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForScrollMetadata;
-  nsRect mChildrenVisibleRect;
+  nsRect mChildrenBuildingRect;
   uint32_t mIndex;
   mutable nsRect mBounds;
   // True for mBounds is valid.
   mutable bool mHasBounds;
   // Be forced not to extend 3D context.  Since we don't create a
   // transform item, a container layer, for every frames in a
   // preserves3d context, the transform items of a child preserves3d
   // context may extend the parent context not intented if the root of
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -611,17 +611,17 @@ nsDisplayOuterSVG::Paint(nsDisplayListBu
 
   if (aBuilder->IsPaintingToWindow()) {
     state.SetPaintingToWindow(true);
   }
 
   nsRect viewportRect =
     mFrame->GetContentRectRelativeToSelf() + ToReferenceFrame();
 
-  nsRect clipRect = mVisibleRect.Intersect(viewportRect);
+  nsRect clipRect = GetPaintRect().Intersect(viewportRect);
 
   uint32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
 
   nsIntRect contentAreaDirtyRect =
     (clipRect - viewportRect.TopLeft()).
       ToOutsidePixels(appUnitsPerDevPixel);
 
   gfxPoint devPixelOffset =
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -418,17 +418,17 @@ public:
                            bool* aSnap) const override;
   NS_DISPLAY_DECL_NAME("TableCellBackground", TYPE_TABLE_CELL_BACKGROUND)
 };
 
 void nsDisplayTableCellBackground::Paint(nsDisplayListBuilder* aBuilder,
                                          gfxContext* aCtx)
 {
   ImgDrawResult result = static_cast<nsTableCellFrame*>(mFrame)->
-    PaintBackground(*aCtx, mVisibleRect, ToReferenceFrame(),
+    PaintBackground(*aCtx, GetPaintRect(), ToReferenceFrame(),
                     aBuilder->GetBackgroundPaintFlags());
 
   nsDisplayTableItemGeometry::UpdateDrawResult(this, result);
 }
 
 nsRect
 nsDisplayTableCellBackground::GetBounds(nsDisplayListBuilder* aBuilder,
                                         bool* aSnap) const
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1277,29 +1277,29 @@ nsDisplayTableBorderCollapse::Paint(nsDi
     nsLayoutUtils::PointToGfxPoint(pt, mFrame->PresContext()->AppUnitsPerDevPixel());
 
   // XXX we should probably get rid of this translation at some stage
   // But that would mean modifying PaintBCBorders, ugh
   AutoRestoreTransform autoRestoreTransform(drawTarget);
   drawTarget->SetTransform(
       drawTarget->GetTransform().PreTranslate(ToPoint(devPixelOffset)));
 
-  static_cast<nsTableFrame*>(mFrame)->PaintBCBorders(*drawTarget, mVisibleRect - pt);
+  static_cast<nsTableFrame*>(mFrame)->PaintBCBorders(*drawTarget, GetPaintRect() - pt);
 }
 
 bool
 nsDisplayTableBorderCollapse::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                                       wr::IpcResourceUpdateQueue& aResources,
                                                       const StackingContextHelper& aSc,
                                                       mozilla::layers::WebRenderLayerManager* aManager,
                                                       nsDisplayListBuilder* aDisplayListBuilder)
 {
   static_cast<nsTableFrame *>(mFrame)->CreateWebRenderCommandsForBCBorders(aBuilder,
                                                                           aSc,
-                                                                          mVisibleRect,
+                                                                          GetPaintRect(),
                                                                           ToReferenceFrame());
   return true;
 }
 
 /* static */ void
 nsTableFrame::GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
                                const nsDisplayListSet& aLists)
 {
--- a/layout/xul/nsGroupBoxFrame.cpp
+++ b/layout/xul/nsGroupBoxFrame.cpp
@@ -134,17 +134,17 @@ nsDisplayXULGroupBorder::ComputeInvalida
   nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
 }
 
 void
 nsDisplayXULGroupBorder::Paint(nsDisplayListBuilder* aBuilder,
                                    gfxContext* aCtx)
 {
   ImgDrawResult result = static_cast<nsGroupBoxFrame*>(mFrame)
-    ->PaintBorder(*aCtx, ToReferenceFrame(), mVisibleRect);
+    ->PaintBorder(*aCtx, ToReferenceFrame(), GetPaintRect());
 
   nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
 }
 
 void
 nsGroupBoxFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                   const nsDisplayListSet& aLists)
 {
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -530,17 +530,17 @@ void nsDisplayXULImage::Paint(nsDisplayL
   // decoding at the correct size for this class like nsImageFrame has.
   uint32_t flags = imgIContainer::FLAG_SYNC_DECODE_IF_FAST;
   if (aBuilder->ShouldSyncDecodeImages())
     flags |= imgIContainer::FLAG_SYNC_DECODE;
   if (aBuilder->IsPaintingToWindow())
     flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING;
 
   ImgDrawResult result = static_cast<nsImageBoxFrame*>(mFrame)->
-    PaintImage(*aCtx, mVisibleRect, ToReferenceFrame(), flags);
+    PaintImage(*aCtx, GetPaintRect(), ToReferenceFrame(), flags);
 
   nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
 }
 
 bool
 nsDisplayXULImage::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                            mozilla::wr::IpcResourceUpdateQueue& aResources,
                                            const StackingContextHelper& aSc,
--- a/layout/xul/nsTextBoxFrame.cpp
+++ b/layout/xul/nsTextBoxFrame.cpp
@@ -326,31 +326,31 @@ nsDisplayXULTextBox::Paint(nsDisplayList
 {
   DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
                                                     mDisableSubpixelAA);
 
   // Paint the text shadow before doing any foreground stuff
   nsRect drawRect = static_cast<nsTextBoxFrame*>(mFrame)->mTextDrawRect +
                     ToReferenceFrame();
   nsLayoutUtils::PaintTextShadow(mFrame, aCtx,
-                                 drawRect, mVisibleRect,
+                                 drawRect, GetPaintRect(),
                                  mFrame->StyleColor()->mColor,
                                  PaintTextShadowCallback,
                                  (void*)this);
 
   PaintTextToContext(aCtx, nsPoint(0, 0), nullptr);
 }
 
 void
 nsDisplayXULTextBox::PaintTextToContext(gfxContext* aCtx,
                                         nsPoint aOffset,
                                         const nscolor* aColor)
 {
   static_cast<nsTextBoxFrame*>(mFrame)->
-    PaintTitle(*aCtx, mVisibleRect, ToReferenceFrame() + aOffset, aColor);
+    PaintTitle(*aCtx, GetPaintRect(), ToReferenceFrame() + aOffset, aColor);
 }
 
 nsRect
 nsDisplayXULTextBox::GetBounds(nsDisplayListBuilder* aBuilder,
                                bool* aSnap) const
 {
   *aSnap = false;
   return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -2806,17 +2806,17 @@ public:
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      gfxContext* aCtx) override
   {
     MOZ_ASSERT(aBuilder);
     DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
                                                       mDisableSubpixelAA);
 
     ImgDrawResult result = static_cast<nsTreeBodyFrame*>(mFrame)
-      ->PaintTreeBody(*aCtx, mVisibleRect, ToReferenceFrame(), aBuilder);
+      ->PaintTreeBody(*aCtx, GetPaintRect(), ToReferenceFrame(), aBuilder);
 
     nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
   }
 
   NS_DISPLAY_DECL_NAME("XULTreeBody", TYPE_XUL_TREE_BODY)
 
   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override
   {