зеркало из https://github.com/mozilla/pjs.git
Bug 618975 Followup: bitrot and remove mDisplayport from nsDisplayScrollLayer r=cjones r=tn a=blocking-fennec
This commit is contained in:
Родитель
1a0ae63ebf
Коммит
30e537ff1a
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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));
|
||||
|
|
|
@ -1790,12 +1790,9 @@ public:
|
|||
* @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
|
||||
|
@ -1819,7 +1816,6 @@ public:
|
|||
}
|
||||
private:
|
||||
nsIFrame* mViewportFrame;
|
||||
nsRect mDisplayPort;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
|
|
@ -87,6 +87,8 @@ public:
|
|||
void PostOverflowEvent();
|
||||
void Destroy();
|
||||
|
||||
PRBool ShouldBuildLayer() const;
|
||||
|
||||
nsresult BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsDisplayListSet& aLists);
|
||||
|
@ -237,7 +239,7 @@ public:
|
|||
nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState);
|
||||
PRBool IsLTR() const;
|
||||
PRBool IsScrollbarOnRight() const;
|
||||
PRBool IsScrollingActive() const { return mScrollingActive; }
|
||||
PRBool IsScrollingActive() const { return mScrollingActive || ShouldBuildLayer(); }
|
||||
// adjust the scrollbar rectangle aRect to account for any visible resizer.
|
||||
// aHasResizer specifies if there is a content resizer, however this method
|
||||
// will also check if a widget resizer is present as well.
|
||||
|
@ -320,6 +322,12 @@ public:
|
|||
PRPackedBool mScrollbarsCanOverlapContent:1;
|
||||
// If true, the resizer is collapsed and not displayed
|
||||
PRPackedBool mCollapsedResizer:1;
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
// If true, the layer should always be active because we always build a layer.
|
||||
// Used for asynchronous scrolling.
|
||||
PRPackedBool mShouldBuildLayer:1;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -181,7 +181,11 @@ ComputeShadowTreeTransform(nsIFrame* aContainerFrame,
|
|||
aConfig.mScrollOffset.ToNearestPixels(auPerDevPixel);
|
||||
nsIntPoint metricsScrollOffset = aMetrics->mViewportScrollOffset;
|
||||
|
||||
if (aRootFrameLoader->AsyncScrollEnabled()) {
|
||||
if (aRootFrameLoader->AsyncScrollEnabled() && !aMetrics->mDisplayPort.IsEmpty()) {
|
||||
// Only use asynchronous scrolling if it is enabled and there is a
|
||||
// displayport defined. It is useful to have a scroll layer that is
|
||||
// synchronously scrolled for identifying a scroll area before it is
|
||||
// being actively scrolled.
|
||||
nsIntPoint scrollCompensation(
|
||||
scrollOffset.x * aInverseScaleX - metricsScrollOffset.x * aConfig.mXScale,
|
||||
scrollOffset.y * aInverseScaleY - metricsScrollOffset.y * aConfig.mYScale);
|
||||
|
|
Загрузка…
Ссылка в новой задаче