diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 5f258ba3357..bea8fa9f718 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -752,11 +752,9 @@ nsDisplayBackground::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) } PRBool -nsDisplayBackground::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder) +nsDisplayBackground::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, + nsIFrame* aFrame) { - NS_ASSERTION(aBuilder->IsMovingFrame(mFrame), - "IsVaryingRelativeToMovingFrame called on non-moving frame!"); - // theme background overrides any other background and is never fixed if (mIsThemed) return PR_FALSE; @@ -771,14 +769,12 @@ nsDisplayBackground::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuild if (!bg->HasFixedBackground()) return PR_FALSE; - nsIFrame* movingFrame = aBuilder->GetRootMovingFrame(); - // movingFrame is the frame that is going to be moved. It must be equal - // to mFrame or some ancestor of mFrame, see assertion above. - // If mFrame is in the same document as movingFrame, then mFrame - // will move relative to its viewport, which means this display item will - // change when it is moved. If they are in different documents, we do not - // want to return true because mFrame won't move relative to its viewport. - return movingFrame->PresContext() == presContext; + // If aFrame is mFrame or an ancestor in this document, and aFrame is + // not the viewport frame, then moving aFrame will move mFrame + // relative to the viewport, so our fixed-pos background will change. + return aFrame->GetParent() && + (aFrame == mFrame || + nsLayoutUtils::IsProperAncestorFrame(aFrame, mFrame)); } PRBool @@ -1102,10 +1098,8 @@ PRBool nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aCo return PR_FALSE; } -PRBool nsDisplayWrapList::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder) { - // The only existing consumer of IsVaryingRelativeToMovingFrame is - // nsLayoutUtils::ComputeRepaintRegionForCopy, which refrains from calling - // this on wrapped lists. +PRBool nsDisplayWrapList::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, + nsIFrame* aFrame) { NS_WARNING("nsDisplayWrapList::IsVaryingRelativeToMovingFrame called unexpectedly"); // We could try to do something but let's conservatively just return PR_TRUE. return PR_TRUE; diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index c4c04e6330e..0b6ac531318 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -542,13 +542,13 @@ public: virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { return PR_FALSE; } /** * @return PR_FALSE if the painting performed by the item is invariant - * when frame aFrame is moved relative to aBuilder->GetRootMovingFrame(). + * when the item's underlying frame is moved relative to aFrame. * In other words, if you render the item at locations P and P', the rendering * only differs by the translation. - * This can only be called when aBuilder->IsMovingFrame(mFrame) is true. * It return PR_TRUE for all wrapped lists. */ - virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder) + virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, + nsIFrame* aFrame) { return PR_FALSE; } /** * @return PR_TRUE if the contents of this item are rendered fixed relative @@ -1309,7 +1309,8 @@ public: nsRegion* aVisibleRegion, nsRegion* aVisibleRegionBeforeMove); virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder); - virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder); + virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, + nsIFrame* aFrame); virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor); virtual PRBool IsFixedAndCoveringViewport(nsDisplayListBuilder* aBuilder); virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); @@ -1444,7 +1445,8 @@ public: virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder); virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor); - virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder); + virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, + nsIFrame* aFrame); virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx); virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp index b475f4b96fb..fa08840283b 100644 --- a/layout/base/nsLayoutDebugger.cpp +++ b/layout/base/nsLayoutDebugger.cpp @@ -176,15 +176,12 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList, } nscolor color; nsRect vis = i->GetVisibleRect(); - fprintf(aOutput, "%s %p(%s) (%d,%d,%d,%d)(%d,%d,%d,%d)%s%s%s%s\n", + fprintf(aOutput, "%s %p(%s) (%d,%d,%d,%d)(%d,%d,%d,%d)%s%s\n", i->Name(), (void*)f, NS_ConvertUTF16toUTF8(fName).get(), rect.x, rect.y, rect.width, rect.height, vis.x, vis.y, vis.width, vis.height, i->IsOpaque(aBuilder) ? " opaque" : "", - i->IsUniform(aBuilder, &color) ? " uniform" : "", - f && aBuilder->IsMovingFrame(f) ? " moving" : "", - f && aBuilder->IsMovingFrame(f) && !i->GetList() && - i->IsVaryingRelativeToMovingFrame(aBuilder) ? " varying" : ""); + i->IsUniform(aBuilder, &color) ? " uniform" : ""); nsDisplayList* list = i->GetList(); if (list) { PrintDisplayListTo(aBuilder, *list, aIndent + 4, aOutput); diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 20a170ff2be..730878c5555 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1525,17 +1525,18 @@ CanScrollWithBlitting(nsIFrame* aFrame, nsIFrame* aDisplayRoot) static void InvalidateFixedBackgroundFramesFromList(nsDisplayListBuilder* aBuilder, + nsIFrame* aMovingFrame, const nsDisplayList& aList) { for (nsDisplayItem* item = aList.GetBottom(); item; item = item->GetAbove()) { nsDisplayList* sublist = item->GetList(); if (sublist) { - InvalidateFixedBackgroundFramesFromList(aBuilder, *sublist); + InvalidateFixedBackgroundFramesFromList(aBuilder, aMovingFrame, *sublist); continue; } nsIFrame* f = item->GetUnderlyingFrame(); - if (f && aBuilder->IsMovingFrame(f) && - item->IsVaryingRelativeToMovingFrame(aBuilder)) { + if (f && + item->IsVaryingRelativeToMovingFrame(aBuilder, aMovingFrame)) { if (item->IsFixedAndCoveringViewport(aBuilder)) { // FrameLayerBuilder takes care of scrolling these } else { @@ -1559,7 +1560,6 @@ InvalidateFixedBackgroundFrames(nsIFrame* aRootFrame, // Build the 'after' display list over the whole area of interest. nsDisplayListBuilder builder(aRootFrame, PR_FALSE, PR_TRUE); builder.EnterPresShell(aRootFrame, aUpdateRect); - builder.SetMovingFrame(aMovingFrame); nsDisplayList list; nsresult rv = aRootFrame->BuildDisplayListForStackingContext(&builder, aUpdateRect, &list); @@ -1570,7 +1570,7 @@ InvalidateFixedBackgroundFrames(nsIFrame* aRootFrame, nsRegion visibleRegion(aUpdateRect); list.ComputeVisibility(&builder, &visibleRegion, nsnull); - InvalidateFixedBackgroundFramesFromList(&builder, list); + InvalidateFixedBackgroundFramesFromList(&builder, aMovingFrame, list); list.DeleteAll(); } diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 3b4dcbd4364..b27807c1d09 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1094,20 +1094,17 @@ nsDisplayTableItem::GetBounds(nsDisplayListBuilder* aBuilder) { } PRBool -nsDisplayTableItem::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder) +nsDisplayTableItem::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, + nsIFrame* aFrame) { if (!mPartHasFixedBackground) return PR_FALSE; - // aAncestorFrame is the frame that is going to be moved. - // Check if mFrame is equal to aAncestorFrame or aAncestorFrame is an - // ancestor of mFrame in the same document. If this is true, mFrame - // will move relative to its viewport, which means this display item will - // change when it is moved. If they are in different documents, we do not - // want to return true because mFrame won't move relative to its viewport. - nsIFrame* rootMover = aBuilder->GetRootMovingFrame(); - return mFrame == rootMover || - nsLayoutUtils::IsProperAncestorFrame(rootMover, mFrame); + // If aFrame is mFrame or an ancestor in this document, and aFrame is + // not the viewport frame, then moving aFrame will move mFrame + // relative to the viewport, so our fixed-pos background will change. + return mFrame == aFrame || + nsLayoutUtils::IsProperAncestorFrame(aFrame, mFrame); } /* static */ void diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index 706749f5519..16585b56721 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -79,7 +79,8 @@ public: nsDisplayTableItem(nsIFrame* aFrame) : nsDisplayItem(aFrame), mPartHasFixedBackground(PR_FALSE) {} - virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder); + virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, + nsIFrame* aFrame); // With collapsed borders, parts of the collapsed border can extend outside // the table part frames, so allow this display element to blow out to our // overflow rect. This is also useful for row frames that have spanning