diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 659652a12b6..404fcd88184 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -3702,6 +3702,7 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, , mScrollFrame(aScrollFrame) , mScrolledFrame(aScrolledFrame) , mScrollParentId(aBuilder->GetCurrentScrollParentId()) + , mDisplayPortContentsOpaque(false) { #ifdef NS_BUILD_REFCNT_LOGGING MOZ_COUNT_CTOR(nsDisplayScrollLayer); @@ -3720,6 +3721,7 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, , mScrollFrame(aScrollFrame) , mScrolledFrame(aScrolledFrame) , mScrollParentId(aBuilder->GetCurrentScrollParentId()) + , mDisplayPortContentsOpaque(false) { #ifdef NS_BUILD_REFCNT_LOGGING MOZ_COUNT_CTOR(nsDisplayScrollLayer); @@ -3737,6 +3739,7 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, , mScrollFrame(aScrollFrame) , mScrolledFrame(aScrolledFrame) , mScrollParentId(aBuilder->GetCurrentScrollParentId()) + , mDisplayPortContentsOpaque(false) { #ifdef NS_BUILD_REFCNT_LOGGING MOZ_COUNT_CTOR(nsDisplayScrollLayer); @@ -3764,6 +3767,22 @@ nsDisplayScrollLayer::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) return nsDisplayWrapList::GetBounds(aBuilder, aSnap); } +nsRect +nsDisplayScrollLayer::GetScrolledContentRectToDraw(nsDisplayListBuilder* aBuilder, + nsRect* aDisplayPort) +{ + if (aDisplayPort) { + // 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. + // XXX mScrollFrame seems wrong here; we should add the offset of the + // scrollport + return *aDisplayPort + mScrollFrame->GetOffsetToCrossDoc(ReferenceFrame()); + } + bool snap; + return GetBounds(aBuilder, &snap); +} + already_AddRefed nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, @@ -3780,9 +3799,26 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder, RecordFrameMetrics(mScrolledFrame, mScrollFrame, ReferenceFrame(), layer, viewport, false, false, aContainerParameters); + if (mList.IsOpaque()) { + nsRect displayport; + bool usingDisplayport = + nsLayoutUtils::GetDisplayPort(mScrolledFrame->GetContent(), &displayport); + mDisplayPortContentsOpaque = mList.GetBounds(aBuilder).Contains( + GetScrolledContentRectToDraw(aBuilder, usingDisplayport ? &displayport : nullptr)); + } else { + mDisplayPortContentsOpaque = false; + } + return layer.forget(); } +bool +nsDisplayScrollLayer::IsConstructingScrollLayerForScrolledFrame(const nsIFrame* aScrolledFrame) +{ + FrameProperties props = aScrolledFrame->Properties(); + return reinterpret_cast(props.Get(nsIFrame::ScrollLayerCount())) != 0; +} + bool nsDisplayScrollLayer::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) { @@ -3801,20 +3837,12 @@ nsDisplayScrollLayer::ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRect displayport; bool usingDisplayPort = nsLayoutUtils::GetDisplayPort(mScrolledFrame->GetContent(), &displayport); - nsRegion childVisibleRegion; - if (usingDisplayPort) { - // 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. - childVisibleRegion = displayport + mScrollFrame->GetOffsetToCrossDoc(ReferenceFrame()); - } else { - bool snap; - childVisibleRegion = GetBounds(aBuilder, &snap); - } + nsRect scrolledContentRect = GetScrolledContentRectToDraw(aBuilder, + usingDisplayPort ? &displayport : nullptr); - nsRect boundedRect = - childVisibleRegion.GetBounds().Intersect(mList.GetBounds(aBuilder)); + nsRect boundedRect = scrolledContentRect.Intersect(mList.GetBounds(aBuilder)); nsRect allowExpansion = boundedRect.Intersect(aAllowVisibleRegionExpansion); + nsRegion childVisibleRegion = scrolledContentRect; bool visible = mList.ComputeVisibilityForSublist( aBuilder, &childVisibleRegion, boundedRect, allowExpansion, usingDisplayPort ? mScrollFrame : nullptr); diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 87419ca6d9f..ebcc0fb29ff 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -3025,6 +3025,8 @@ public: // after merging, all the nsDisplayScrollLayers should flatten away. intptr_t GetScrollLayerCount(); + static bool IsConstructingScrollLayerForScrolledFrame(const nsIFrame* aScrolledFrame); + virtual nsIFrame* GetScrollFrame() { return mScrollFrame; } virtual nsIFrame* GetScrolledFrame() { return mScrolledFrame; } @@ -3032,10 +3034,16 @@ public: virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE; #endif + bool IsDisplayPortOpaque() { return mDisplayPortContentsOpaque; } + protected: + nsRect GetScrolledContentRectToDraw(nsDisplayListBuilder* aBuilder, + nsRect* aDisplayPort); + nsIFrame* mScrollFrame; nsIFrame* mScrolledFrame; ViewID mScrollParentId; + bool mDisplayPortContentsOpaque; }; /**