summaryrefslogtreecommitdiff
path: root/layout/base/nsDisplayList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layout/base/nsDisplayList.cpp')
-rw-r--r--layout/base/nsDisplayList.cpp120
1 files changed, 42 insertions, 78 deletions
diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp
index f870c6d971..8a34d108f1 100644
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -721,6 +721,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
: mReferenceFrame(aReferenceFrame),
mIgnoreScrollFrame(nullptr),
mLayerEventRegions(nullptr),
+ mCurrentTableItem(nullptr),
mCurrentFrame(aReferenceFrame),
mCurrentReferenceFrame(aReferenceFrame),
mCurrentAGR(&mRootAGR),
@@ -730,7 +731,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mGlassDisplayItem(nullptr),
mScrollInfoItemsForHoisting(nullptr),
mMode(aMode),
- mTableBackgroundSet(nullptr),
mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID),
mCurrentScrollbarTarget(FrameMetrics::NULL_SCROLL_ID),
mCurrentScrollbarFlags(0),
@@ -783,10 +783,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
"Check nsDisplayItem::TYPE_MAX should not overflow");
}
-void
-nsDisplayListBuilder::MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame)
-{
- mFramesMarkedForDisplay.AppendElement(aFrame);
+static void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) {
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
if (f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)
@@ -799,22 +796,6 @@ nsDisplayListBuilder::MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFra
}
}
-void
-nsDisplayListBuilder::MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* aStopAtFrame)
-{
- mFramesMarkedForDisplay.AppendElement(aFrame);
- for (nsIFrame* f = aFrame; f;
- f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
- if (f->ForceDescendIntoIfVisible())
- return;
- f->SetForceDescendIntoIfVisible(true);
- if (f == aStopAtFrame) {
- // we've reached a frame that we know will be painted, so we can stop.
- break;
- }
- }
-}
-
bool nsDisplayListBuilder::NeedToForceTransparentSurfaceForItem(nsDisplayItem* aItem)
{
return aItem == mGlassDisplayItem || aItem->ClearsBackground();
@@ -883,10 +864,10 @@ nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsDisplayItem* aItem)
void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
- nsIFrame* aFrame)
+ nsIFrame* aFrame,
+ const nsRect& aDirtyRect)
{
- nsRect visible = GetVisibleRect();
- nsRect dirtyRectRelativeToDirtyFrame = GetDirtyRect();
+ nsRect dirtyRectRelativeToDirtyFrame = aDirtyRect;
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) &&
IsPaintingToWindow()) {
NS_ASSERTION(aDirtyFrame == aFrame->GetParent(), "Dirty frame should be viewport frame");
@@ -900,14 +881,8 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
} else {
dirtyRectRelativeToDirtyFrame.SizeTo(aDirtyFrame->GetSize());
}
- // TODO: We probably don't want visible and dirty to be the same here, figure
- // out what to do.
- visible = dirtyRectRelativeToDirtyFrame;
}
-
- nsPoint offset = aFrame->GetOffsetTo(aDirtyFrame);
- visible -= offset;
- nsRect dirty = dirtyRectRelativeToDirtyFrame - offset;
+ nsRect dirty = dirtyRectRelativeToDirtyFrame - aFrame->GetOffsetTo(aDirtyFrame);
nsRect overflowRect = aFrame->GetVisualOverflowRect();
if (aFrame->IsTransformed() &&
@@ -920,18 +895,15 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
*/
overflowRect.Inflate(nsPresContext::CSSPixelsToAppUnits(32));
}
- visible.IntersectRect(visible, overflowRect);
- dirty.IntersectRect(dirty, overflowRect);
- if (!(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) &&
- dirty.IsEmpty() &&
- (!aFrame->ForceDescendIntoIfVisible() ||
- visible.IsEmpty())) {
+
+ if (!dirty.IntersectRect(dirty, overflowRect) &&
+ !(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) {
return;
}
const DisplayItemClip* oldClip = mClipState.GetClipForContainingBlockDescendants();
const DisplayItemScrollClip* sc = mClipState.GetCurrentInnermostScrollClip();
- OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, visible, dirty);
+ OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, dirty);
aFrame->SetProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
MarkFrameForDisplay(aFrame, aDirtyFrame);
@@ -942,11 +914,9 @@ static void UnmarkFrameForDisplay(nsIFrame* aFrame) {
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
- if (!(f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) &&
- !f->ForceDescendIntoIfVisible())
+ if (!(f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO))
return;
f->RemoveStateBits(NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO);
- f->SetForceDescendIntoIfVisible(false);
}
}
@@ -955,6 +925,7 @@ nsDisplayListBuilder::~nsDisplayListBuilder() {
"All frames should have been unmarked");
NS_ASSERTION(mPresShellStates.Length() == 0,
"All presshells should have been exited");
+ NS_ASSERTION(!mCurrentTableItem, "No table item should be active");
nsCSSRendering::EndFrameTreesLocked();
@@ -1037,27 +1008,22 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
}
state->mInsidePointerEventsNoneDoc = pointerEventsNone;
- state->mPresShellIgnoreScrollFrame =
- state->mPresShell->IgnoringViewportScrolling()
- ? state->mPresShell->GetRootScrollFrame()
- : nullptr;
-
- nsPresContext* pc = aReferenceFrame->PresContext();
- nsCOMPtr<nsIDocShell> docShell = pc->GetDocShell();
- if (docShell) {
- docShell->GetWindowDraggingAllowed(&mWindowDraggingAllowed);
- }
-
- mIsInChromePresContext = pc->IsChrome();
-
if (!buildCaret)
return;
RefPtr<nsCaret> caret = state->mPresShell->GetCaret();
state->mCaretFrame = caret->GetPaintGeometry(&state->mCaretRect);
if (state->mCaretFrame) {
+ mFramesMarkedForDisplay.AppendElement(state->mCaretFrame);
MarkFrameForDisplay(state->mCaretFrame, nullptr);
}
+
+ nsPresContext* pc = aReferenceFrame->PresContext();
+ nsCOMPtr<nsIDocShell> docShell = pc->GetDocShell();
+ if (docShell) {
+ docShell->GetWindowDraggingAllowed(&mWindowDraggingAllowed);
+ }
+ mIsInChromePresContext = pc->IsChrome();
}
// A non-blank paint is a paint that does not just contain the canvas background.
@@ -1128,7 +1094,8 @@ nsDisplayListBuilder::ResetMarkedFramesForDisplayList()
void
nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
- const nsFrameList& aFrames) {
+ const nsFrameList& aFrames,
+ const nsRect& aDirtyRect) {
for (nsIFrame* e : aFrames) {
// Skip the AccessibleCaret frame when building no caret.
if (!IsBuildingCaret()) {
@@ -1141,7 +1108,8 @@ nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
}
}
- MarkOutOfFlowFrameForDisplay(aDirtyFrame, e);
+ mFramesMarkedForDisplay.AppendElement(e);
+ MarkOutOfFlowFrameForDisplay(aDirtyFrame, e, aDirtyRect);
}
}
@@ -1164,6 +1132,7 @@ nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame)
for (; !childFrames.AtEnd(); childFrames.Next()) {
nsIFrame *child = childFrames.get();
if (child->Combines3DTransformWithAncestors()) {
+ mFramesMarkedForDisplay.AppendElement(child);
MarkFrameForDisplay(child, aDirtyFrame);
}
}
@@ -2349,11 +2318,11 @@ nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(aFrame);
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(),
*mAnimatedGeometryRoot), "Bad");
- NS_ASSERTION(aBuilder->GetVisibleRect().width >= 0 ||
- !aBuilder->IsForPainting(), "visible rect not set");
- // The visible rect is for mCurrentFrame, so we have to use
+ NS_ASSERTION(aBuilder->GetDirtyRect().width >= 0 ||
+ !aBuilder->IsForPainting(), "dirty rect not set");
+ // The dirty rect is for mCurrentFrame, so we have to use
// mCurrentOffsetToReferenceFrame
- mVisibleRect = aBuilder->GetVisibleRect() +
+ mVisibleRect = aBuilder->GetDirtyRect() +
aBuilder->GetCurrentFrameOffsetToReferenceFrame();
}
@@ -2604,7 +2573,8 @@ static nsStyleContext* GetBackgroundStyleContext(nsIFrame* aFrame)
/* static */ void
SetBackgroundClipRegion(DisplayListClipState::AutoSaveRestore& aClipState,
- nsIFrame* aFrame, const nsStyleImageLayers::Layer& aLayer,
+ nsIFrame* aFrame, const nsPoint& aToReferenceFrame,
+ const nsStyleImageLayers::Layer& aLayer,
const nsRect& aBackgroundRect,
bool aWillPaintBorder)
{
@@ -2656,6 +2626,7 @@ SpecialCutoutRegionCase(nsDisplayListBuilder* aBuilder,
return true;
}
+
/*static*/ bool
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
@@ -2664,16 +2635,14 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
bool aAllowWillPaintBorderOptimization,
nsStyleContext* aStyleContext,
const nsRect& aBackgroundOriginRect,
- nsIFrame* aSecondaryReferenceFrame,
- Maybe<nsDisplayListBuilder::AutoBuildingDisplayList>*
- aAutoBuildingDisplayList)
+ nsIFrame* aSecondaryReferenceFrame)
{
nsStyleContext* bgSC = aStyleContext;
const nsStyleBackground* bg = nullptr;
- nsRect bgRect = aBackgroundRect;
+ nsRect bgRect = aBackgroundRect + aBuilder->ToReferenceFrame(aFrame);
nsRect bgOriginRect = bgRect;
if (!aBackgroundOriginRect.IsEmpty()) {
- bgOriginRect = aBackgroundOriginRect;
+ bgOriginRect = aBackgroundOriginRect + aBuilder->ToReferenceFrame(aFrame);
}
nsPresContext* presContext = aFrame->PresContext();
bool isThemed = aFrame->IsThemed();
@@ -2709,6 +2678,8 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
!isThemed && !hasInsetShadow &&
borderStyle->HasBorder();
+ nsPoint toRef = aBuilder->ToReferenceFrame(aFrame);
+
// An auxiliary list is necessary in case we have background blending; if that
// is the case, background items need to be wrapped by a blend container to
// isolate blending to the background
@@ -2717,9 +2688,6 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
// to create an item for hit testing.
if ((drawBackgroundColor && color != NS_RGBA(0,0,0,0)) ||
aBuilder->IsForEventDelivery()) {
- if (aAutoBuildingDisplayList && !*aAutoBuildingDisplayList) {
- aAutoBuildingDisplayList->emplace(aBuilder, aFrame);
- }
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
if (bg && !aBuilder->IsForEventDelivery()) {
// Disable the will-paint-border optimization for background
@@ -2731,7 +2699,7 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
// artifacts along the rounded corners.
bool useWillPaintBorderOptimization = willPaintBorder &&
nsLayoutUtils::HasNonZeroCorner(borderStyle->mBorderRadius);
- SetBackgroundClipRegion(clipState, aFrame,
+ SetBackgroundClipRegion(clipState, aFrame, toRef,
bg->BottomLayer(), bgRect,
useWillPaintBorderOptimization);
}
@@ -2784,10 +2752,6 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
continue;
}
- if (aAutoBuildingDisplayList && !*aAutoBuildingDisplayList) {
- aAutoBuildingDisplayList->emplace(aBuilder, aFrame);
- }
-
if (bg->mImage.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) {
needBlendContainer = true;
}
@@ -2795,8 +2759,8 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
if (!aBuilder->IsForEventDelivery()) {
const nsStyleImageLayers::Layer& layer = bg->mImage.mLayers[i];
- SetBackgroundClipRegion(clipState, aFrame, layer, bgRect,
- willPaintBorder);
+ SetBackgroundClipRegion(clipState, aFrame, toRef,
+ layer, bgRect, willPaintBorder);
}
nsDisplayList thisItemList;
@@ -4378,7 +4342,7 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
mReferenceFrame = i->ReferenceFrame();
mToReferenceFrame = i->ToReferenceFrame();
}
- mVisibleRect = aBuilder->GetVisibleRect() +
+ mVisibleRect = aBuilder->GetDirtyRect() +
aBuilder->GetCurrentFrameOffsetToReferenceFrame();
}
@@ -4404,7 +4368,7 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
mReferenceFrame = aItem->ReferenceFrame();
mToReferenceFrame = aItem->ToReferenceFrame();
}
- mVisibleRect = aBuilder->GetVisibleRect() +
+ mVisibleRect = aBuilder->GetDirtyRect() +
aBuilder->GetCurrentFrameOffsetToReferenceFrame();
}