Skip to content

Commit

Permalink
Bug 618975 Followup: bitrot and remove mDisplayport from nsDisplayScr…
Browse files Browse the repository at this point in the history
…ollLayer r=cjones r=tn a=blocking-fennec
  • Loading branch information
Benjamin Stover committed Mar 9, 2011
1 parent e9b7771 commit a646bb5
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 114 deletions.
38 changes: 17 additions & 21 deletions dom/base/nsDOMWindowUtils.cpp
Expand Up @@ -315,31 +315,27 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
if (rootScrollFrame) {
if (content == rootScrollFrame->GetContent()) {
// We are setting the root displayport. The pres context needs a special
// flag to be set.
// We are setting a root displayport for a document.
// The pres shell needs a special flag set.
presShell->SetIgnoreViewportScrolling(PR_TRUE);

// The root document currently has a widget, but we might end up
// painting content inside the displayport but outside the widget
// bounds. This ensures the document's view honors invalidations
// within the displayport.
nsPresContext* presContext = GetPresContext();
if (presContext && presContext->IsRoot()) {
nsIFrame* rootFrame = presShell->GetRootFrame();
nsIView* view = rootFrame->GetView();
if (view) {
view->SetInvalidationDimensions(&displayport);
}
}
}
}

// FIXME (Bug 593243 should fix this.)
//
// Invalidated content does not pay any attention to the displayport, so
// invalidating the subdocument's root frame could end up not repainting
// visible content.
//
// For instance, imagine the iframe is located at y=1000. Even though the
// displayport may intersect the iframe's viewport, the visual overflow
// rect of the root content could be (0, 0, 800, 500). Since the dirty region
// does not intersect the visible overflow rect, the display list for the
// iframe will not even be generated.
//
// Here, we find the very top presShell and use its root frame for
// invalidation instead.
//
nsPresContext* rootPresContext = GetPresContext()->GetRootPresContext();
if (rootPresContext) {
nsIPresShell* rootPresShell = rootPresContext->GetPresShell();
nsIFrame* rootFrame = rootPresShell->FrameManager()->GetRootFrame();
if (presShell) {
nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
if (rootFrame) {
rootFrame->InvalidateWithFlags(rootFrame->GetVisualOverflowRectRelativeToSelf(),
nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
Expand Down
41 changes: 20 additions & 21 deletions layout/base/nsDisplayList.cpp
Expand Up @@ -153,7 +153,7 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
ContainerLayer* aRoot,
nsRect aVisibleRect,
nsRect aViewport,
nsRect aDisplayPort,
nsRect* aDisplayPort,
ViewID aScrollId) {
nsPresContext* presContext = aForFrame->PresContext();

Expand All @@ -164,11 +164,11 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,

PRInt32 auPerDevPixel = presContext->AppUnitsPerDevPixel();
metrics.mViewport = aViewport.ToNearestPixels(auPerDevPixel);
if (aViewport != aDisplayPort) {
metrics.mDisplayPort = aDisplayPort.ToNearestPixels(auPerDevPixel);
if (aDisplayPort) {
metrics.mDisplayPort = aDisplayPort->ToNearestPixels(auPerDevPixel);
}

nsIScrollableFrame* scrollableFrame = NULL;
nsIScrollableFrame* scrollableFrame = nsnull;
if (aViewportFrame)
scrollableFrame = aViewportFrame->GetScrollTargetFrame();

Expand Down Expand Up @@ -525,17 +525,17 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
: FrameMetrics::NULL_SCROLL_ID;

nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
nsRect visibleRect = mVisibleRect;
nsRect displayport;
bool usingDisplayport = false;
if (rootScrollFrame) {
nsIContent* content = rootScrollFrame->GetContent();
if (content) {
// If there is a displayport defined for the root content element,
// it will be stored in visibleRect.
nsLayoutUtils::GetDisplayPort(content, &visibleRect);
usingDisplayport = nsLayoutUtils::GetDisplayPort(content, &displayport);
}
}
RecordFrameMetrics(aForFrame, presShell->GetRootScrollFrame(),
root, mVisibleRect, mVisibleRect, visibleRect, id);
RecordFrameMetrics(aForFrame, rootScrollFrame,
root, mVisibleRect, mVisibleRect,
(usingDisplayport ? &displayport : nsnull), id);

// If the layer manager supports resolution scaling, set that up
if (LayerManager::LAYERS_BASIC == layerManager->GetBackendType()) {
Expand Down Expand Up @@ -1706,11 +1706,9 @@ nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
nsDisplayList* aList,
nsIFrame* aForFrame,
nsIFrame* aViewportFrame,
const nsRect& aDisplayPort)
nsIFrame* aViewportFrame)
: nsDisplayOwnLayer(aBuilder, aForFrame, aList)
, mViewportFrame(aViewportFrame)
, mDisplayPort(aDisplayPort)
{
#ifdef NS_BUILD_REFCNT_LOGGING
MOZ_COUNT_CTOR(nsDisplayScrollLayer);
Expand All @@ -1735,8 +1733,13 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
mViewportFrame->GetPosition() +
aBuilder->ToReferenceFrame(mViewportFrame);

bool usingDisplayport = false;
nsRect displayport;
if (content) {
usingDisplayport = nsLayoutUtils::GetDisplayPort(content, &displayport);
}
RecordFrameMetrics(mFrame, mViewportFrame, layer, mVisibleRect, viewport,
mDisplayPort, scrollId);
(usingDisplayport ? &displayport : nsnull), scrollId);

return layer.forget();
}
Expand All @@ -1748,17 +1751,13 @@ nsDisplayScrollLayer::ComputeVisibility(nsDisplayListBuilder* aBuilder,
PRBool& aContainsRootContentDocBG)
{
nsPresContext* presContext = mFrame->PresContext();

nsRect viewport = mViewportFrame->GetRect() -
mViewportFrame->GetPosition() +
aBuilder->ToReferenceFrame(mViewportFrame);

if (mDisplayPort != viewport) {
nsRect displayport;
if (nsLayoutUtils::GetDisplayPort(mFrame->GetContent(), &displayport)) {
// The visible region for the children may be much bigger than the hole we
// are viewing the children from, so that the compositor process has enough
// content to asynchronously pan while content is being refreshed.

nsRegion childVisibleRegion = mDisplayPort + aBuilder->ToReferenceFrame(mViewportFrame);
nsRegion childVisibleRegion = displayport + aBuilder->ToReferenceFrame(mViewportFrame);

nsRect boundedRect;
boundedRect.IntersectRect(childVisibleRegion.GetBounds(), mList.GetBounds(aBuilder));
Expand Down
6 changes: 1 addition & 5 deletions layout/base/nsDisplayList.h
Expand Up @@ -1790,12 +1790,9 @@ class nsDisplayScrollLayer : public nsDisplayOwnLayer
* @param aForFrame This will determine what the displayport is. It should be
* the root content frame of the scrolled area.
* @param aViewportFrame The viewport frame you see this content through.
* @param aDisplayPort Overrides the visibility of the child items if it
* is not equal to the visible area.
*/
nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
nsIFrame* aForFrame, nsIFrame* aViewportFrame,
const nsRect& aDisplayPort);
nsIFrame* aForFrame, nsIFrame* aViewportFrame);
NS_DISPLAY_DECL_NAME("ScrollLayer", TYPE_SCROLL_LAYER)

#ifdef NS_BUILD_REFCNT_LOGGING
Expand All @@ -1819,7 +1816,6 @@ class nsDisplayScrollLayer : public nsDisplayOwnLayer
}
private:
nsIFrame* mViewportFrame;
nsRect mDisplayPort;
};
#endif

Expand Down
5 changes: 0 additions & 5 deletions layout/base/nsPresShell.cpp
Expand Up @@ -6046,11 +6046,6 @@ void PresShell::SetRenderingState(const RenderingState& aState)
mRenderFlags = aState.mRenderFlags;
mXResolution = aState.mXResolution;
mYResolution = aState.mYResolution;

nsIView* rootView;
if (NS_SUCCEEDED(mViewManager->GetRootView(rootView)) && rootView) {
rootView->SetInvalidationDimensions(&mDisplayPort);
}
}

void PresShell::SynthesizeMouseMove(PRBool aFromScroll)
Expand Down
125 changes: 65 additions & 60 deletions layout/generic/nsGfxScrollFrame.cpp
Expand Up @@ -195,12 +195,14 @@ nsHTMLScrollFrame::InvalidateInternal(const nsRect& aDamageRect,
nsRect damage = aDamageRect + nsPoint(aX, aY);
// This is the damage rect that we're going to pass up to our parent.
nsRect parentDamage;
nsIPresShell* presShell = PresContext()->PresShell();
// If we're using a displayport, we might be displaying an area
// different than our scroll port and the damage needs to be
// clipped to that instead.
if (mInner.mIsRoot && presShell->UsingDisplayPort()) {
parentDamage.IntersectRect(damage, presShell->GetDisplayPort());
nsRect displayport;
PRBool usingDisplayport = nsLayoutUtils::GetDisplayPort(GetContent(),
&displayport);
if (usingDisplayport) {
parentDamage.IntersectRect(damage, displayport);
} else {
parentDamage.IntersectRect(damage, mInner.mScrollPort);
}
Expand Down Expand Up @@ -1112,12 +1114,14 @@ nsXULScrollFrame::InvalidateInternal(const nsRect& aDamageRect,
nsRect damage = aDamageRect + nsPoint(aX, aY);
// This is the damage rect that we're going to pass up to our parent.
nsRect parentDamage;
nsIPresShell* presShell = PresContext()->PresShell();
// If we're using a displayport, we might be displaying an area
// different than our scroll port and the damage needs to be
// clipped to that instead.
if (mInner.mIsRoot && presShell->UsingDisplayPort()) {
parentDamage.IntersectRect(damage, presShell->GetDisplayPort());
nsRect displayport;
PRBool usingDisplayport = nsLayoutUtils::GetDisplayPort(GetContent(),
&displayport);
if (usingDisplayport) {
parentDamage.IntersectRect(damage, displayport);
} else {
parentDamage.IntersectRect(damage, mInner.mScrollPort);
}
Expand Down Expand Up @@ -1370,33 +1374,36 @@ static ScrollFrameActivityTracker *gScrollFrameActivityTracker = nsnull;

nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsContainerFrame* aOuter,
PRBool aIsRoot)
: mHScrollbarBox(nsnull),
mVScrollbarBox(nsnull),
mScrolledFrame(nsnull),
mScrollCornerBox(nsnull),
mResizerBox(nsnull),
mOuter(aOuter),
mAsyncScroll(nsnull),
mDestination(0, 0),
mScrollPosAtLastPaint(0, 0),
mRestorePos(-1, -1),
mLastPos(-1, -1),
mNeverHasVerticalScrollbar(PR_FALSE),
mNeverHasHorizontalScrollbar(PR_FALSE),
mHasVerticalScrollbar(PR_FALSE),
mHasHorizontalScrollbar(PR_FALSE),
mFrameIsUpdatingScrollbar(PR_FALSE),
mDidHistoryRestore(PR_FALSE),
mIsRoot(aIsRoot),
mSupppressScrollbarUpdate(PR_FALSE),
mSkippedScrollbarLayout(PR_FALSE),
mHadNonInitialReflow(PR_FALSE),
mHorizontalOverflow(PR_FALSE),
mVerticalOverflow(PR_FALSE),
mPostedReflowCallback(PR_FALSE),
mMayHaveDirtyFixedChildren(PR_FALSE),
mUpdateScrollbarAttributes(PR_FALSE),
mCollapsedResizer(PR_FALSE)
: mHScrollbarBox(nsnull)
, mVScrollbarBox(nsnull)
, mScrolledFrame(nsnull)
, mScrollCornerBox(nsnull)
, mResizerBox(nsnull)
, mOuter(aOuter)
, mAsyncScroll(nsnull)
, mDestination(0, 0)
, mScrollPosAtLastPaint(0, 0)
, mRestorePos(-1, -1)
, mLastPos(-1, -1)
, mNeverHasVerticalScrollbar(PR_FALSE)
, mNeverHasHorizontalScrollbar(PR_FALSE)
, mHasVerticalScrollbar(PR_FALSE)
, mHasHorizontalScrollbar(PR_FALSE)
, mFrameIsUpdatingScrollbar(PR_FALSE)
, mDidHistoryRestore(PR_FALSE)
, mIsRoot(aIsRoot)
, mSupppressScrollbarUpdate(PR_FALSE)
, mSkippedScrollbarLayout(PR_FALSE)
, mHadNonInitialReflow(PR_FALSE)
, mHorizontalOverflow(PR_FALSE)
, mVerticalOverflow(PR_FALSE)
, mPostedReflowCallback(PR_FALSE)
, mMayHaveDirtyFixedChildren(PR_FALSE)
, mUpdateScrollbarAttributes(PR_FALSE)
, mCollapsedResizer(PR_FALSE)
#ifdef MOZ_IPC
, mShouldBuildLayer(PR_FALSE)
#endif
{
// lookup if we're allowed to overlap the content from the look&feel object
PRBool canOverlap;
Expand Down Expand Up @@ -1710,7 +1717,13 @@ void nsGfxScrollFrameInner::ScrollVisual()
if (canScrollWithBlitting) {
MarkActive();
}
mOuter->InvalidateWithFlags(mScrollPort, flags);

nsRect invalidateRect, displayport;
invalidateRect =
(nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayport)) ?
displayport : mScrollPort;

mOuter->InvalidateWithFlags(invalidateRect, flags);

if (flags & nsIFrame::INVALIDATE_NO_THEBES_LAYERS) {
nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(mOuter);
Expand Down Expand Up @@ -1835,6 +1848,16 @@ nsGfxScrollFrameInner::AppendScrollPartsTo(nsDisplayListBuilder* aBuild
return rv;
}

PRBool
nsGfxScrollFrameInner::ShouldBuildLayer() const
{
#ifdef MOZ_IPC
return mShouldBuildLayer;
#else
return PR_FALSE;
#endif
}

nsresult
nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
Expand Down Expand Up @@ -1879,13 +1902,6 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
scrollParts, createLayersForScrollbars);
}

nsRect displayport;
PRBool usingDisplayPort = nsLayoutUtils::GetDisplayPort(mOuter->GetContent(),
&displayport);
if (!usingDisplayPort) {
displayport = mScrollPort;
}

// Overflow clipping can never clip frames outside our subtree, so there
// is no need to worry about whether we are a moving frame that might clip
// non-moving frames.
Expand All @@ -1897,14 +1913,12 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// dirty rect here.
dirtyRect.IntersectRect(aDirtyRect, mScrollPort);

if (usingDisplayPort) {
dirtyRect = displayport;
}
// Override the dirty rectangle if the displayport has been set.
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &dirtyRect);

nsDisplayListCollection set;

nsPresContext* presContext = mOuter->PresContext();
PRInt32 appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();

#ifdef MOZ_IPC
// Since making new layers is expensive, only use nsDisplayScrollLayer
Expand All @@ -1916,34 +1930,25 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// range of 20 pixels to eliminate many gfx scroll frames from becoming a
// layer.
//
PRInt32 appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
nsRect scrollRange = GetScrollRange();
PRBool buildingLayer =
mShouldBuildLayer =
(XRE_GetProcessType() == GeckoProcessType_Content &&
(scrollRange.width >= NSIntPixelsToAppUnits(20, appUnitsPerDevPixel) ||
scrollRange.height >= NSIntPixelsToAppUnits(20, appUnitsPerDevPixel))) &&
(!mIsRoot || !mOuter->PresContext()->IsRootContentDocument());

#else
PRBool buildingLayer = false;
#endif

if (buildingLayer) {
if (ShouldBuildLayer()) {
// Note that using StackingContext breaks z order, so the resulting
// rendering can be incorrect for weird edge cases!

nsDisplayList list;
rv = mScrolledFrame->BuildDisplayListForStackingContext(
aBuilder,
dirtyRect + mOuter->GetOffsetTo(mScrolledFrame),
set.Content()
);
aBuilder, dirtyRect + mOuter->GetOffsetTo(mScrolledFrame), &list);

nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollLayer(
aBuilder,
set.Content(),
mScrolledFrame,
mOuter,
displayport
);
aBuilder, &list, mScrolledFrame, mOuter);
set.Content()->AppendNewToTop(layerItem);
} else {
rv = mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, set);
Expand Down

0 comments on commit a646bb5

Please sign in to comment.