summaryrefslogtreecommitdiffstats
path: root/layout/base
diff options
context:
space:
mode:
Diffstat (limited to 'layout/base')
-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
4 files changed, 159 insertions, 76 deletions
diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp
index 8a34d108f..f870c6d97 100644
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -721,7 +721,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
: mReferenceFrame(aReferenceFrame),
mIgnoreScrollFrame(nullptr),
mLayerEventRegions(nullptr),
- mCurrentTableItem(nullptr),
mCurrentFrame(aReferenceFrame),
mCurrentReferenceFrame(aReferenceFrame),
mCurrentAGR(&mRootAGR),
@@ -731,6 +730,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mGlassDisplayItem(nullptr),
mScrollInfoItemsForHoisting(nullptr),
mMode(aMode),
+ mTableBackgroundSet(nullptr),
mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID),
mCurrentScrollbarTarget(FrameMetrics::NULL_SCROLL_ID),
mCurrentScrollbarFlags(0),
@@ -783,7 +783,10 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
"Check nsDisplayItem::TYPE_MAX should not overflow");
}
-static void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) {
+void
+nsDisplayListBuilder::MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame)
+{
+ mFramesMarkedForDisplay.AppendElement(aFrame);
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
if (f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)
@@ -796,6 +799,22 @@ static void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) {
}
}
+void
+nsDisplayListBuilder::MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* aStopAtFrame)
+{
+ mFramesMarkedForDisplay.AppendElement(aFrame);
+ for (nsIFrame* f = aFrame; f;
+ f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
+ if (f->ForceDescendIntoIfVisible())
+ return;
+ f->SetForceDescendIntoIfVisible(true);
+ if (f == aStopAtFrame) {
+ // we've reached a frame that we know will be painted, so we can stop.
+ break;
+ }
+ }
+}
+
bool nsDisplayListBuilder::NeedToForceTransparentSurfaceForItem(nsDisplayItem* aItem)
{
return aItem == mGlassDisplayItem || aItem->ClearsBackground();
@@ -864,10 +883,10 @@ nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsDisplayItem* aItem)
void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
- nsIFrame* aFrame,
- const nsRect& aDirtyRect)
+ nsIFrame* aFrame)
{
- nsRect dirtyRectRelativeToDirtyFrame = aDirtyRect;
+ nsRect visible = GetVisibleRect();
+ nsRect dirtyRectRelativeToDirtyFrame = GetDirtyRect();
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) &&
IsPaintingToWindow()) {
NS_ASSERTION(aDirtyFrame == aFrame->GetParent(), "Dirty frame should be viewport frame");
@@ -881,8 +900,14 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
} else {
dirtyRectRelativeToDirtyFrame.SizeTo(aDirtyFrame->GetSize());
}
+ // TODO: We probably don't want visible and dirty to be the same here, figure
+ // out what to do.
+ visible = dirtyRectRelativeToDirtyFrame;
}
- nsRect dirty = dirtyRectRelativeToDirtyFrame - aFrame->GetOffsetTo(aDirtyFrame);
+
+ nsPoint offset = aFrame->GetOffsetTo(aDirtyFrame);
+ visible -= offset;
+ nsRect dirty = dirtyRectRelativeToDirtyFrame - offset;
nsRect overflowRect = aFrame->GetVisualOverflowRect();
if (aFrame->IsTransformed() &&
@@ -895,15 +920,18 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
*/
overflowRect.Inflate(nsPresContext::CSSPixelsToAppUnits(32));
}
-
- if (!dirty.IntersectRect(dirty, overflowRect) &&
- !(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) {
+ visible.IntersectRect(visible, overflowRect);
+ dirty.IntersectRect(dirty, overflowRect);
+ if (!(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) &&
+ dirty.IsEmpty() &&
+ (!aFrame->ForceDescendIntoIfVisible() ||
+ visible.IsEmpty())) {
return;
}
const DisplayItemClip* oldClip = mClipState.GetClipForContainingBlockDescendants();
const DisplayItemScrollClip* sc = mClipState.GetCurrentInnermostScrollClip();
- OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, dirty);
+ OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, visible, dirty);
aFrame->SetProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
MarkFrameForDisplay(aFrame, aDirtyFrame);
@@ -914,9 +942,11 @@ static void UnmarkFrameForDisplay(nsIFrame* aFrame) {
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
- if (!(f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO))
+ if (!(f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) &&
+ !f->ForceDescendIntoIfVisible())
return;
f->RemoveStateBits(NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO);
+ f->SetForceDescendIntoIfVisible(false);
}
}
@@ -925,7 +955,6 @@ nsDisplayListBuilder::~nsDisplayListBuilder() {
"All frames should have been unmarked");
NS_ASSERTION(mPresShellStates.Length() == 0,
"All presshells should have been exited");
- NS_ASSERTION(!mCurrentTableItem, "No table item should be active");
nsCSSRendering::EndFrameTreesLocked();
@@ -1008,22 +1037,27 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
}
state->mInsidePointerEventsNoneDoc = pointerEventsNone;
+ state->mPresShellIgnoreScrollFrame =
+ state->mPresShell->IgnoringViewportScrolling()
+ ? state->mPresShell->GetRootScrollFrame()
+ : nullptr;
+
+ nsPresContext* pc = aReferenceFrame->PresContext();
+ nsCOMPtr<nsIDocShell> docShell = pc->GetDocShell();
+ if (docShell) {
+ docShell->GetWindowDraggingAllowed(&mWindowDraggingAllowed);
+ }
+
+ mIsInChromePresContext = pc->IsChrome();
+
if (!buildCaret)
return;
RefPtr<nsCaret> caret = state->mPresShell->GetCaret();
state->mCaretFrame = caret->GetPaintGeometry(&state->mCaretRect);
if (state->mCaretFrame) {
- mFramesMarkedForDisplay.AppendElement(state->mCaretFrame);
MarkFrameForDisplay(state->mCaretFrame, nullptr);
}
-
- nsPresContext* pc = aReferenceFrame->PresContext();
- nsCOMPtr<nsIDocShell> docShell = pc->GetDocShell();
- if (docShell) {
- docShell->GetWindowDraggingAllowed(&mWindowDraggingAllowed);
- }
- mIsInChromePresContext = pc->IsChrome();
}
// A non-blank paint is a paint that does not just contain the canvas background.
@@ -1094,8 +1128,7 @@ nsDisplayListBuilder::ResetMarkedFramesForDisplayList()
void
nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
- const nsFrameList& aFrames,
- const nsRect& aDirtyRect) {
+ const nsFrameList& aFrames) {
for (nsIFrame* e : aFrames) {
// Skip the AccessibleCaret frame when building no caret.
if (!IsBuildingCaret()) {
@@ -1108,8 +1141,7 @@ nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
}
}
- mFramesMarkedForDisplay.AppendElement(e);
- MarkOutOfFlowFrameForDisplay(aDirtyFrame, e, aDirtyRect);
+ MarkOutOfFlowFrameForDisplay(aDirtyFrame, e);
}
}
@@ -1132,7 +1164,6 @@ nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame)
for (; !childFrames.AtEnd(); childFrames.Next()) {
nsIFrame *child = childFrames.get();
if (child->Combines3DTransformWithAncestors()) {
- mFramesMarkedForDisplay.AppendElement(child);
MarkFrameForDisplay(child, aDirtyFrame);
}
}
@@ -2318,11 +2349,11 @@ nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(aFrame);
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(),
*mAnimatedGeometryRoot), "Bad");
- NS_ASSERTION(aBuilder->GetDirtyRect().width >= 0 ||
- !aBuilder->IsForPainting(), "dirty rect not set");
- // The dirty rect is for mCurrentFrame, so we have to use
+ NS_ASSERTION(aBuilder->GetVisibleRect().width >= 0 ||
+ !aBuilder->IsForPainting(), "visible rect not set");
+ // The visible rect is for mCurrentFrame, so we have to use
// mCurrentOffsetToReferenceFrame
- mVisibleRect = aBuilder->GetDirtyRect() +
+ mVisibleRect = aBuilder->GetVisibleRect() +
aBuilder->GetCurrentFrameOffsetToReferenceFrame();
}
@@ -2573,8 +2604,7 @@ static nsStyleContext* GetBackgroundStyleContext(nsIFrame* aFrame)
/* static */ void
SetBackgroundClipRegion(DisplayListClipState::AutoSaveRestore& aClipState,
- nsIFrame* aFrame, const nsPoint& aToReferenceFrame,
- const nsStyleImageLayers::Layer& aLayer,
+ nsIFrame* aFrame, const nsStyleImageLayers::Layer& aLayer,
const nsRect& aBackgroundRect,
bool aWillPaintBorder)
{
@@ -2626,7 +2656,6 @@ SpecialCutoutRegionCase(nsDisplayListBuilder* aBuilder,
return true;
}
-
/*static*/ bool
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
@@ -2635,14 +2664,16 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
bool aAllowWillPaintBorderOptimization,
nsStyleContext* aStyleContext,
const nsRect& aBackgroundOriginRect,
- nsIFrame* aSecondaryReferenceFrame)
+ nsIFrame* aSecondaryReferenceFrame,
+ Maybe<nsDisplayListBuilder::AutoBuildingDisplayList>*
+ aAutoBuildingDisplayList)
{
nsStyleContext* bgSC = aStyleContext;
const nsStyleBackground* bg = nullptr;
- nsRect bgRect = aBackgroundRect + aBuilder->ToReferenceFrame(aFrame);
+ nsRect bgRect = aBackgroundRect;
nsRect bgOriginRect = bgRect;
if (!aBackgroundOriginRect.IsEmpty()) {
- bgOriginRect = aBackgroundOriginRect + aBuilder->ToReferenceFrame(aFrame);
+ bgOriginRect = aBackgroundOriginRect;
}
nsPresContext* presContext = aFrame->PresContext();
bool isThemed = aFrame->IsThemed();
@@ -2678,8 +2709,6 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
!isThemed && !hasInsetShadow &&
borderStyle->HasBorder();
- nsPoint toRef = aBuilder->ToReferenceFrame(aFrame);
-
// An auxiliary list is necessary in case we have background blending; if that
// is the case, background items need to be wrapped by a blend container to
// isolate blending to the background
@@ -2688,6 +2717,9 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
// to create an item for hit testing.
if ((drawBackgroundColor && color != NS_RGBA(0,0,0,0)) ||
aBuilder->IsForEventDelivery()) {
+ if (aAutoBuildingDisplayList && !*aAutoBuildingDisplayList) {
+ aAutoBuildingDisplayList->emplace(aBuilder, aFrame);
+ }
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
if (bg && !aBuilder->IsForEventDelivery()) {
// Disable the will-paint-border optimization for background
@@ -2699,7 +2731,7 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
// artifacts along the rounded corners.
bool useWillPaintBorderOptimization = willPaintBorder &&
nsLayoutUtils::HasNonZeroCorner(borderStyle->mBorderRadius);
- SetBackgroundClipRegion(clipState, aFrame, toRef,
+ SetBackgroundClipRegion(clipState, aFrame,
bg->BottomLayer(), bgRect,
useWillPaintBorderOptimization);
}
@@ -2752,6 +2784,10 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
continue;
}
+ if (aAutoBuildingDisplayList && !*aAutoBuildingDisplayList) {
+ aAutoBuildingDisplayList->emplace(aBuilder, aFrame);
+ }
+
if (bg->mImage.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) {
needBlendContainer = true;
}
@@ -2759,8 +2795,8 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
if (!aBuilder->IsForEventDelivery()) {
const nsStyleImageLayers::Layer& layer = bg->mImage.mLayers[i];
- SetBackgroundClipRegion(clipState, aFrame, toRef,
- layer, bgRect, willPaintBorder);
+ SetBackgroundClipRegion(clipState, aFrame, layer, bgRect,
+ willPaintBorder);
}
nsDisplayList thisItemList;
@@ -4342,7 +4378,7 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
mReferenceFrame = i->ReferenceFrame();
mToReferenceFrame = i->ToReferenceFrame();
}
- mVisibleRect = aBuilder->GetDirtyRect() +
+ mVisibleRect = aBuilder->GetVisibleRect() +
aBuilder->GetCurrentFrameOffsetToReferenceFrame();
}
@@ -4368,7 +4404,7 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
mReferenceFrame = aItem->ReferenceFrame();
mToReferenceFrame = aItem->ToReferenceFrame();
}
- mVisibleRect = aBuilder->GetDirtyRect() +
+ mVisibleRect = aBuilder->GetVisibleRect() +
aBuilder->GetCurrentFrameOffsetToReferenceFrame();
}
diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h
index 9cee7b517..9ae76e2ac 100644
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -48,6 +48,7 @@ class nsISelection;
class nsIScrollableFrame;
class nsDisplayLayerEventRegions;
class nsDisplayScrollInfoLayer;
+class nsDisplayTableBackgroundSet;
class nsCaret;
namespace mozilla {
@@ -202,6 +203,7 @@ class nsDisplayListBuilder {
: mAccumulatedTransform()
, mAccumulatedRect()
, mAccumulatedRectLevels(0)
+ , mVisibleRect(aOther.mVisibleRect)
, mDirtyRect(aOther.mDirtyRect) {}
// Accmulate transforms of ancestors on the preserves-3d chain.
@@ -210,6 +212,7 @@ class nsDisplayListBuilder {
nsRect mAccumulatedRect;
// How far this frame is from the root of the current 3d context.
int mAccumulatedRectLevels;
+ nsRect mVisibleRect;
nsRect mDirtyRect;
};
@@ -443,7 +446,14 @@ public:
* Get dirty rect relative to current frame (the frame that we're calling
* BuildDisplayList on right now).
*/
+ const nsRect& GetVisibleRect() { return mVisibleRect; }
const nsRect& GetDirtyRect() { return mDirtyRect; }
+
+ void SetVisibleRect(const nsRect& aVisibleRect) { mVisibleRect = aVisibleRect; }
+ void IntersectVisibleRect(const nsRect& aVisibleRect) { mVisibleRect.IntersectRect(mVisibleRect, aVisibleRect); }
+ void SetDirtyRect(const nsRect& aDirtyRect) { mDirtyRect = aDirtyRect; }
+ void IntersectDirtyRect(const nsRect& aDirtyRect) { mDirtyRect.IntersectRect(mDirtyRect, aDirtyRect); }
+
const nsIFrame* GetCurrentFrame() { return mCurrentFrame; }
const nsIFrame* GetCurrentReferenceFrame() { return mCurrentReferenceFrame; }
const nsPoint& GetCurrentFrameOffsetToReferenceFrame() { return mCurrentOffsetToReferenceFrame; }
@@ -493,11 +503,10 @@ public:
/**
* Display the caret if needed.
*/
- void DisplayCaret(nsIFrame* aFrame, const nsRect& aDirtyRect,
- nsDisplayList* aList) {
+ void DisplayCaret(nsIFrame* aFrame, nsDisplayList* aList) {
nsIFrame* frame = GetCaretFrame();
if (aFrame == frame) {
- frame->DisplayCaret(this, aDirtyRect, aList);
+ frame->DisplayCaret(this, aList);
}
}
/**
@@ -517,6 +526,15 @@ public:
* Get the caret associated with the current presshell.
*/
nsCaret* GetCaret();
+
+ /**
+ * Returns the root scroll frame for the current PresShell, if the PresShell
+ * is ignoring viewport scrolling.
+ */
+ nsIFrame* GetPresShellIgnoreScrollFrame() {
+ return CurrentPresShellState()->mPresShellIgnoreScrollFrame;
+ }
+
/**
* Notify the display list builder that we're entering a presshell.
* aReferenceFrame should be a frame in the new presshell.
@@ -577,6 +595,16 @@ public:
mSyncDecodeImages = aSyncDecodeImages;
}
+ nsDisplayTableBackgroundSet* SetTableBackgroundSet(
+ nsDisplayTableBackgroundSet* aTableSet) {
+ nsDisplayTableBackgroundSet* old = mTableBackgroundSet;
+ mTableBackgroundSet = aTableSet;
+ return old;
+ }
+ nsDisplayTableBackgroundSet* GetTableBackgroundSet() const {
+ return mTableBackgroundSet;
+ }
+
/**
* Helper method to generate background painting flags based on the
* information available in the display list builder. Currently only
@@ -602,8 +630,9 @@ public:
* destroyed.
*/
void MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
- const nsFrameList& aFrames,
- const nsRect& aDirtyRect);
+ const nsFrameList& aFrames);
+ void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame = nullptr);
+ void MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* aStopAtFrame = nullptr);
/**
* Mark all child frames that Preserve3D() as needing display.
* Because these frames include transforms set on their parent, dirty rects
@@ -618,9 +647,10 @@ public:
* the display list, even though it doesn't intersect the dirty
* rect, because it may have out-of-flows that do so.
*/
- bool ShouldDescendIntoFrame(nsIFrame* aFrame) const {
+ bool ShouldDescendIntoFrame(nsIFrame* aFrame, bool aVisible) const {
return
(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) ||
+ (aVisible && aFrame->ForceDescendIntoIfVisible()) ||
GetIncludeAllOutOfFlows();
}
@@ -700,14 +730,20 @@ public:
friend class AutoBuildingDisplayList;
class AutoBuildingDisplayList {
public:
- AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder,
- nsIFrame* aForChild,
+ AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* aForChild)
+ : AutoBuildingDisplayList(
+ aBuilder, aForChild, aBuilder->GetVisibleRect(),
+ aBuilder->GetDirtyRect(), aForChild->IsTransformed()){}
+
+ AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* aForChild,
+ const nsRect& aVisibleRect,
const nsRect& aDirtyRect, bool aIsRoot)
: mBuilder(aBuilder),
mPrevFrame(aBuilder->mCurrentFrame),
mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame),
mPrevLayerEventRegions(aBuilder->mLayerEventRegions),
mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame),
+ mPrevVisibleRect(aBuilder->mVisibleRect),
mPrevDirtyRect(aBuilder->mDirtyRect),
mPrevAGR(aBuilder->mCurrentAGR),
mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
@@ -733,12 +769,10 @@ public:
}
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(), *aBuilder->mCurrentAGR));
aBuilder->mCurrentFrame = aForChild;
+ aBuilder->mVisibleRect = aVisibleRect;
aBuilder->mDirtyRect = aDirtyRect;
aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
}
- void SetDirtyRect(const nsRect& aRect) {
- mBuilder->mDirtyRect = aRect;
- }
void SetReferenceFrameAndCurrentOffset(const nsIFrame* aFrame, const nsPoint& aOffset) {
mBuilder->mCurrentReferenceFrame = aFrame;
mBuilder->mCurrentOffsetToReferenceFrame = aOffset;
@@ -760,6 +794,7 @@ public:
mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame;
mBuilder->mLayerEventRegions = mPrevLayerEventRegions;
mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
+ mBuilder->mVisibleRect = mPrevVisibleRect;
mBuilder->mDirtyRect = mPrevDirtyRect;
mBuilder->mCurrentAGR = mPrevAGR;
mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext;
@@ -773,6 +808,7 @@ public:
nsIFrame* mPrevAnimatedGeometryRoot;
nsDisplayLayerEventRegions* mPrevLayerEventRegions;
nsPoint mPrevOffset;
+ nsRect mPrevVisibleRect;
nsRect mPrevDirtyRect;
AnimatedGeometryRoot* mPrevAGR;
bool mPrevIsAtRootOfPseudoStackingContext;
@@ -981,20 +1017,19 @@ public:
return mPreserves3DCtx.mAccumulatedRectLevels;
}
- // Helpers for tables
- nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; }
- void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; }
-
struct OutOfFlowDisplayData {
OutOfFlowDisplayData(const DisplayItemClip* aContainingBlockClip,
const DisplayItemScrollClip* aContainingBlockScrollClip,
+ const nsRect &aVisibleRect,
const nsRect &aDirtyRect)
: mContainingBlockClip(aContainingBlockClip ? *aContainingBlockClip : DisplayItemClip())
, mContainingBlockScrollClip(aContainingBlockScrollClip)
+ , mVisibleRect(aVisibleRect)
, mDirtyRect(aDirtyRect)
{}
DisplayItemClip mContainingBlockClip;
const DisplayItemScrollClip* mContainingBlockScrollClip;
+ nsRect mVisibleRect;
nsRect mDirtyRect;
};
@@ -1120,11 +1155,13 @@ public:
Preserves3DContext mSavedCtx;
};
- const nsRect GetPreserves3DDirtyRect(const nsIFrame *aFrame) const {
+ const nsRect GetPreserves3DRects(nsRect* aOutVisibleRect) const {
+ *aOutVisibleRect = mPreserves3DCtx.mVisibleRect;
return mPreserves3DCtx.mDirtyRect;
}
- void SetPreserves3DDirtyRect(const nsRect &aDirtyRect) {
- mPreserves3DCtx.mDirtyRect = aDirtyRect;
+ void SavePreserves3DRects() {
+ mPreserves3DCtx.mVisibleRect = mVisibleRect;
+ mPreserves3DCtx.mDirtyRect = mDirtyRect;
}
bool IsBuildingInvisibleItems() const { return mBuildingInvisibleItems; }
@@ -1133,8 +1170,7 @@ public:
}
private:
- void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
- const nsRect& aDirtyRect);
+ void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame);
/**
* Returns whether a frame acts as an animated geometry root, optionally
@@ -1174,6 +1210,7 @@ private:
nsRect mCaretRect;
uint32_t mFirstFrameMarkedForDisplay;
bool mIsBackgroundOnly;
+ nsIFrame* mPresShellIgnoreScrollFrame;
// This is a per-document flag turning off event handling for all content
// in the document, and is set when we enter a subdocument for a pointer-
// events:none frame.
@@ -1202,7 +1239,6 @@ private:
AutoTArray<PresShellState,8> mPresShellStates;
AutoTArray<nsIFrame*,400> mFramesMarkedForDisplay;
AutoTArray<ThemeGeometry,2> mThemeGeometries;
- nsDisplayTableItem* mCurrentTableItem;
DisplayListClipState mClipState;
// mCurrentFrame is the frame that we're currently calling (or about to call)
// BuildDisplayList on.
@@ -1229,6 +1265,7 @@ private:
nsTHashtable<nsPtrHashKey<nsIFrame> > mAGRBudgetSet;
// Relative to mCurrentFrame.
+ nsRect mVisibleRect;
nsRect mDirtyRect;
nsRegion mWindowExcludeGlassRegion;
nsRegion mWindowOpaqueRegion;
@@ -1245,6 +1282,7 @@ private:
nsTArray<DisplayItemScrollClip*> mScrollClipsToDestroy;
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;
nsDisplayListBuilderMode mMode;
+ nsDisplayTableBackgroundSet* mTableBackgroundSet;
ViewID mCurrentScrollParentId;
ViewID mCurrentScrollbarTarget;
uint32_t mCurrentScrollbarFlags;
@@ -2287,12 +2325,13 @@ protected:
* to the object, and all distinct.
*/
struct nsDisplayListCollection : public nsDisplayListSet {
- nsDisplayListCollection() :
- nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4],
- &mLists[5]) {}
- explicit nsDisplayListCollection(nsDisplayList* aBorderBackground) :
- nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4],
+ explicit nsDisplayListCollection(nsDisplayListBuilder* aBuilder)
+ : nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4],
&mLists[5]) {}
+ explicit nsDisplayListCollection(nsDisplayListBuilder* aBuilder,
+ nsDisplayList* aBorderBackground)
+ : nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4],
+ &mLists[5]) {}
/**
* Sort all lists by content order.
@@ -2739,7 +2778,9 @@ public:
bool aAllowWillPaintBorderOptimization = true,
nsStyleContext* aStyleContext = nullptr,
const nsRect& aBackgroundOriginRect = nsRect(),
- nsIFrame* aSecondaryReferenceFrame = nullptr);
+ nsIFrame* aSecondaryReferenceFrame = nullptr,
+ mozilla::Maybe<nsDisplayListBuilder::AutoBuildingDisplayList>*
+ aAutoBuildingDisplayList = nullptr);
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
index 21d20c69f..39bef4d56 100644
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3189,7 +3189,9 @@ nsLayoutUtils::GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
}
builder.EnterPresShell(aFrame);
- aFrame->BuildDisplayListForStackingContext(&builder, aRect, &list);
+ builder.SetVisibleRect(aRect);
+ builder.SetDirtyRect(aRect);
+ aFrame->BuildDisplayListForStackingContext(&builder, &list);
builder.LeavePresShell(aFrame, nullptr);
#ifdef MOZ_DUMP_PAINTING
@@ -3448,7 +3450,8 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
nsIScrollableFrame* rootScrollableFrame = presShell->GetRootScrollFrameAsScrollable();
MOZ_ASSERT(rootScrollableFrame);
nsRect displayPortBase = aFrame->GetVisualOverflowRectRelativeToSelf();
- Unused << rootScrollableFrame->DecideScrollableLayer(&builder, &displayPortBase,
+ nsRect temp = displayPortBase;
+ Unused << rootScrollableFrame->DecideScrollableLayer(&builder, &displayPortBase, &temp,
/* aAllowCreateDisplayPort = */ true);
}
@@ -3538,7 +3541,9 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
PROFILER_LABEL("nsLayoutUtils", "PaintFrame::BuildDisplayList",
js::ProfileEntry::Category::GRAPHICS);
- aFrame->BuildDisplayListForStackingContext(&builder, dirtyRect, &list);
+ builder.SetDirtyRect(dirtyRect);
+ builder.SetVisibleRect(dirtyRect);
+ aFrame->BuildDisplayListForStackingContext(&builder, &list);
}
nsIAtom* frameType = aFrame->GetType();
@@ -3550,7 +3555,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
nsRect bounds = nsRect(builder.ToReferenceFrame(aFrame),
aFrame->GetSize());
nsDisplayListBuilder::AutoBuildingDisplayList
- buildingDisplayList(&builder, aFrame, bounds, false);
+ buildingDisplayList(&builder, aFrame, bounds, bounds, false);
presShell->AddPrintPreviewBackgroundItem(builder, list, aFrame, bounds);
} else if (frameType != nsGkAtoms::pageFrame) {
// For printing, this function is first called on an nsPageFrame, which
@@ -3564,7 +3569,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
// can monkey with the contents if necessary.
canvasArea.IntersectRect(canvasArea, visibleRegion.GetBounds());
nsDisplayListBuilder::AutoBuildingDisplayList
- buildingDisplayList(&builder, aFrame, canvasArea, false);
+ buildingDisplayList(&builder, aFrame, canvasArea, canvasArea, false);
presShell->AddCanvasBackgroundColorItem(
builder, list, aFrame, canvasArea, aBackstop);
}
diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp
index 264b52b18..222428a89 100644
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -4894,8 +4894,9 @@ PresShell::CreateRangePaintInfo(nsIDOMRange* aRange,
nsIFrame* frame = aNode->AsContent()->GetPrimaryFrame();
// XXX deal with frame being null due to display:contents
for (; frame; frame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(frame)) {
- frame->BuildDisplayListForStackingContext(&info->mBuilder,
- frame->GetVisualOverflowRect(), &info->mList);
+ info->mBuilder.SetVisibleRect(frame->GetVisualOverflowRect());
+ info->mBuilder.SetDirtyRect(frame->GetVisualOverflowRect());
+ frame->BuildDisplayListForStackingContext(&info->mBuilder, &info->mList);
}
};
if (startParent->NodeType() == nsIDOMNode::TEXT_NODE) {