author | Robert O'Callahan <robert@ocallahan.org> |
Fri, 17 Aug 2012 11:39:00 +1200 | |
changeset 107343 | f2ef195a022a7dac87e0f0eca2383c422b8bb148 |
parent 107342 | 2b2e43e83d0fb836cb5aca91905e5702b5ea7854 |
child 107344 | 2e2c7ed818d6f352bbce323909d3a6e0b0b8415d |
push id | 14987 |
push user | rocallahan@mozilla.com |
push date | Tue, 18 Sep 2012 09:34:32 +0000 |
treeherder | mozilla-inbound@be9f5e549658 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mattwoodrow |
bugs | 777194 |
milestone | 18.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
|
--- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1948,37 +1948,56 @@ void nsGfxScrollFrameInner::ScrollVisual } else { flags |= nsIFrame::INVALIDATE_NO_THEBES_LAYERS; } } if (canScrollWithBlitting) { MarkActive(); } - nsRect invalidateRect, displayport; + nsRect invalidateRect, displayPort; + bool hasDisplayPort = + nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayPort); if (IsIgnoringViewportClipping()) { nsRect visualOverflow = mScrolledFrame->GetVisualOverflowRect(); invalidateRect.UnionRect(visualOverflow + mScrolledFrame->GetPosition(), visualOverflow + aOldScrolledFramePos); } else { - invalidateRect = - (nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayport)) ? - displayport : mScrollPort; + invalidateRect = hasDisplayPort ? displayPort : mScrollPort; } mOuter->InvalidateWithFlags(invalidateRect, flags); if (flags & nsIFrame::INVALIDATE_NO_THEBES_LAYERS) { nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(mOuter); nsRect update = GetScrollPortRect() + mOuter->GetOffsetToCrossDoc(displayRoot); - update = update.ConvertAppUnitsRoundOut( + nsRect displayRootUpdate = update.ConvertAppUnitsRoundOut( mOuter->PresContext()->AppUnitsPerDevPixel(), displayRoot->PresContext()->AppUnitsPerDevPixel()); - InvalidateFixedBackgroundFrames(displayRoot, mScrolledFrame, update); + InvalidateFixedBackgroundFrames(displayRoot, mScrolledFrame, displayRootUpdate); + + // Invalidate content that has scrolled into view. Normally, this will + // already be invalid, because it shouldn't have been drawn in any layer, + // but there can be stray rows/columns of pixels that partially overlapped + // the layer's visible region and hence were drawn and added to the layer's + // visible region, but these pixels ended up outside the cliprect after + // snapping so their contents need to be updated now that new content has + // scrolled into the cliprect. + nsPoint scrollDelta = mScrolledFrame->GetPosition() - aOldScrolledFramePos; + if (!hasDisplayPort) { + displayPort = GetScrollPortRect(); + } + nsRect preservedContents = displayPort + scrollDelta; + nsRegion invalidate; + invalidate.Sub(displayPort, preservedContents); + nsRegionRectIterator iter(invalidate); + while (const nsRect* r = iter.Next()) { + mOuter->InvalidateWithFlags(*r, nsIFrame::INVALIDATE_REASON_SCROLL_REPAINT); + } } } /** * Return an appunit value close to aDesired and between aLower and aUpper * such that (aDesired - aCurrent)*aRes/aAppUnitsPerPixel is an integer (or * as close as we can get modulo rounding to appunits). If that * can't be done, just returns aDesired.