diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1461,32 +1461,39 @@ nsIFrame::BuildDisplayListForChild(nsDis dirty = *savedDirty; } else { // The out-of-flow frame did not intersect the dirty area. We may still // need to traverse into it, since it may contain placeholders we need // to enter to reach other out-of-flow frames that are visible. dirty.Empty(); } pseudoStackingContext = PR_TRUE; - } else { - dirty.IntersectRect(dirty, aChild->GetOverflowRect()); } if (aBuilder->GetPaintAllFrames()) { dirty = aChild->GetOverflowRect(); } else if (!(aChild->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) { // No need to descend into aChild to catch placeholders for visible // positioned stuff. So see if we can short-circuit frame traversal here. - // We can stop if aChild's intersection with the dirty area ended up empty. + // We can stop if aChild's frame subtree's intersection with the + // dirty area is empty. // If the child is a scrollframe that we want to ignore, then we need // to descend into it because its scrolled child may intersect the dirty // area even if the scrollframe itself doesn't. - if (dirty.IsEmpty() && aChild != aBuilder->GetIgnoreScrollFrame()) - return NS_OK; + if (aChild != aBuilder->GetIgnoreScrollFrame()) { + nsRect childDirty; + if (!childDirty.IntersectRect(dirty, aChild->GetOverflowRect())) + return NS_OK; + // Usually we could set dirty to childDirty now but there's no + // benefit, and it can be confusing. It can especially confuse + // situations where we're going to ignore a scrollframe's clipping; + // we wouldn't want to clip the dirty area to the scrollframe's + // bounds in that case. + } // Note that aBuilder->GetRootMovingFrame() is non-null only if we're doing // ComputeRepaintRegionForCopy. if (aBuilder->GetRootMovingFrame() == this && !PresContext()->GetRenderedPositionVaryingContent()) { // No position-varying content has been rendered in this prescontext. // Therefore there is no need to descend into analyzing the moving frame's // descendants looking for such content, because any bitblit will diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1310,22 +1310,19 @@ nsGfxScrollFrameInner::BuildDisplayList( const nsDisplayListSet& aLists) { nsresult rv = mOuter->DisplayBorderBackgroundOutline(aBuilder, aLists); NS_ENSURE_SUCCESS(rv, rv); if (aBuilder->GetIgnoreScrollFrame() == mOuter) { // Don't clip the scrolled child, and don't paint scrollbars/scrollcorner. // The scrolled frame shouldn't have its own background/border, so we - // can just pass aLists directly. We do need to replace aDirtyRect with - // the scrolled area though, since callers may have restricted aDirtyRect - // to our bounds. - nsRect newDirty = GetScrolledRect(GetScrollPortSize()) + - aBuilder->ToReferenceFrame(mScrolledFrame); - return mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, newDirty, aLists); + // can just pass aLists directly. + return mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, + aDirtyRect, aLists); } // Now display the scrollbars and scrollcorner. These parts are drawn // in the border-background layer, on top of our own background and // borders and underneath borders and backgrounds of later elements // in the tree. nsIFrame* kid = mOuter->GetFirstChild(nsnull); while (kid) {