зеркало из https://github.com/mozilla/gecko-dev.git
Bug 982888 - Populate the scroll parent field as appropriate. r=
This commit is contained in:
Родитель
f22e15107b
Коммит
1665cb02ce
|
@ -505,6 +505,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
|||
mCachedOffset(0, 0),
|
||||
mGlassDisplayItem(nullptr),
|
||||
mMode(aMode),
|
||||
mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID),
|
||||
mBuildCaret(aBuildCaret),
|
||||
mIgnoreSuppression(false),
|
||||
mHadToIgnoreSuppression(false),
|
||||
|
@ -3524,7 +3525,9 @@ nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||
nsDisplaySubDocument::nsDisplaySubDocument(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, nsDisplayList* aList,
|
||||
uint32_t aFlags)
|
||||
: nsDisplayOwnLayer(aBuilder, aFrame, aList, aFlags) {
|
||||
: nsDisplayOwnLayer(aBuilder, aFrame, aList, aFlags)
|
||||
, mScrollParentId(aBuilder->GetCurrentScrollParentId())
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplaySubDocument);
|
||||
}
|
||||
|
||||
|
@ -3574,6 +3577,7 @@ nsDisplaySubDocument::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||
mFrame->GetPosition() +
|
||||
mFrame->GetOffsetToCrossDoc(ReferenceFrame());
|
||||
|
||||
container->SetScrollHandoffParentId(mScrollParentId);
|
||||
RecordFrameMetrics(mFrame, rootScrollFrame, ReferenceFrame(),
|
||||
container, mList.GetVisibleRect(), viewport,
|
||||
(usingDisplayport ? &displayport : nullptr),
|
||||
|
@ -3779,6 +3783,7 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
|
|||
: nsDisplayWrapList(aBuilder, aForFrame, aList)
|
||||
, mScrollFrame(aScrollFrame)
|
||||
, mScrolledFrame(aScrolledFrame)
|
||||
, mScrollParentId(aBuilder->GetCurrentScrollParentId())
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
MOZ_COUNT_CTOR(nsDisplayScrollLayer);
|
||||
|
@ -3796,6 +3801,7 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
|
|||
: nsDisplayWrapList(aBuilder, aForFrame, aItem)
|
||||
, mScrollFrame(aScrollFrame)
|
||||
, mScrolledFrame(aScrolledFrame)
|
||||
, mScrollParentId(aBuilder->GetCurrentScrollParentId())
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
MOZ_COUNT_CTOR(nsDisplayScrollLayer);
|
||||
|
@ -3812,6 +3818,7 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
|
|||
: nsDisplayWrapList(aBuilder, aForFrame)
|
||||
, mScrollFrame(aScrollFrame)
|
||||
, mScrolledFrame(aScrolledFrame)
|
||||
, mScrollParentId(aBuilder->GetCurrentScrollParentId())
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
MOZ_COUNT_CTOR(nsDisplayScrollLayer);
|
||||
|
@ -3864,6 +3871,7 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||
usingCriticalDisplayport =
|
||||
nsLayoutUtils::GetCriticalDisplayPort(content, &criticalDisplayport);
|
||||
}
|
||||
layer->SetScrollHandoffParentId(mScrollParentId);
|
||||
RecordFrameMetrics(mScrolledFrame, mScrollFrame, ReferenceFrame(), layer,
|
||||
mList.GetVisibleRect(), viewport,
|
||||
(usingDisplayport ? &displayport : nullptr),
|
||||
|
|
|
@ -114,6 +114,7 @@ public:
|
|||
typedef mozilla::DisplayListClipState DisplayListClipState;
|
||||
typedef nsIWidget::ThemeGeometry ThemeGeometry;
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
typedef mozilla::layers::FrameMetrics::ViewID ViewID;
|
||||
|
||||
/**
|
||||
* @param aReferenceFrame the frame at the root of the subtree; its origin
|
||||
|
@ -248,6 +249,10 @@ public:
|
|||
* Get the scrollframe to ignore, if any.
|
||||
*/
|
||||
nsIFrame* GetIgnoreScrollFrame() { return mIgnoreScrollFrame; }
|
||||
/**
|
||||
* Get the ViewID of the nearest scrolling ancestor frame.
|
||||
*/
|
||||
ViewID GetCurrentScrollParentId() const { return mCurrentScrollParentId; }
|
||||
/**
|
||||
* Calling this setter makes us include all out-of-flow descendant
|
||||
* frames in the display list, wherever they may be positioned (even
|
||||
|
@ -602,6 +607,25 @@ public:
|
|||
bool mOldValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper class to temporarily set the value of mCurrentScrollParentId.
|
||||
*/
|
||||
class AutoCurrentScrollParentIdSetter;
|
||||
friend class AutoCurrentScrollParentIdSetter;
|
||||
class AutoCurrentScrollParentIdSetter {
|
||||
public:
|
||||
AutoCurrentScrollParentIdSetter(nsDisplayListBuilder* aBuilder, ViewID aScrollId)
|
||||
: mBuilder(aBuilder), mOldValue(aBuilder->mCurrentScrollParentId) {
|
||||
aBuilder->mCurrentScrollParentId = aScrollId;
|
||||
}
|
||||
~AutoCurrentScrollParentIdSetter() {
|
||||
mBuilder->mCurrentScrollParentId = mOldValue;
|
||||
}
|
||||
private:
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
ViewID mOldValue;
|
||||
};
|
||||
|
||||
// Helpers for tables
|
||||
nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; }
|
||||
void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; }
|
||||
|
@ -706,6 +730,7 @@ private:
|
|||
nsDisplayItem* mGlassDisplayItem;
|
||||
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;
|
||||
Mode mMode;
|
||||
ViewID mCurrentScrollParentId;
|
||||
bool mBuildCaret;
|
||||
bool mIgnoreSuppression;
|
||||
bool mHadToIgnoreSuppression;
|
||||
|
@ -2834,6 +2859,8 @@ public:
|
|||
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
|
||||
|
||||
NS_DISPLAY_DECL_NAME("SubDocument", TYPE_SUBDOCUMENT)
|
||||
protected:
|
||||
ViewID mScrollParentId;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -2971,6 +2998,7 @@ public:
|
|||
protected:
|
||||
nsIFrame* mScrollFrame;
|
||||
nsIFrame* mScrolledFrame;
|
||||
ViewID mScrollParentId;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -2523,8 +2523,41 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
dirtyRect = ExpandRect(dirtyRect);
|
||||
}
|
||||
|
||||
// Since making new layers is expensive, only use nsDisplayScrollLayer
|
||||
// if the area is scrollable and we're the content process (unless we're on
|
||||
// B2G, where we support async scrolling for scrollable elements in the
|
||||
// parent process as well).
|
||||
// When a displayport is being used, force building of a layer so that
|
||||
// CompositorParent can always find the scrollable layer for the root content
|
||||
// document.
|
||||
// If the element is marked 'scrollgrab', also force building of a layer
|
||||
// so that APZ can implement scroll grabbing.
|
||||
mShouldBuildScrollableLayer = usingDisplayport || nsContentUtils::HasScrollgrab(mOuter->GetContent());
|
||||
bool shouldBuildLayer = false;
|
||||
if (mShouldBuildScrollableLayer) {
|
||||
shouldBuildLayer = true;
|
||||
} else {
|
||||
shouldBuildLayer =
|
||||
nsLayoutUtils::WantSubAPZC() &&
|
||||
WantAsyncScroll() &&
|
||||
// If we are the root scroll frame for the display root then we don't need a scroll
|
||||
// info layer to make a RecordFrameMetrics call for us as
|
||||
// nsDisplayList::PaintForFrame already calls RecordFrameMetrics for us.
|
||||
(!mIsRoot || aBuilder->RootReferenceFrame()->PresContext() != mOuter->PresContext());
|
||||
}
|
||||
|
||||
nsDisplayListCollection scrolledContent;
|
||||
{
|
||||
// Note that setting the current scroll parent id here means that positioned children
|
||||
// of this scroll info layer will pick up the scroll info layer as their scroll handoff
|
||||
// parent. This is intentional because that is what happens for positioned children
|
||||
// of scroll layers, and we want to maintain consistent behaviour between scroll layers
|
||||
// and scroll info layers.
|
||||
nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(
|
||||
aBuilder,
|
||||
shouldBuildLayer && mScrolledFrame->GetContent()
|
||||
? nsLayoutUtils::FindOrCreateIDFor(mScrolledFrame->GetContent())
|
||||
: aBuilder->GetCurrentScrollParentId());
|
||||
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
||||
|
||||
if (usingDisplayport) {
|
||||
|
@ -2585,29 +2618,6 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
}
|
||||
|
||||
// Since making new layers is expensive, only use nsDisplayScrollLayer
|
||||
// if the area is scrollable and we're the content process (unless we're on
|
||||
// B2G, where we support async scrolling for scrollable elements in the
|
||||
// parent process as well).
|
||||
// When a displayport is being used, force building of a layer so that
|
||||
// CompositorParent can always find the scrollable layer for the root content
|
||||
// document.
|
||||
// If the element is marked 'scrollgrab', also force building of a layer
|
||||
// so that APZ can implement scroll grabbing.
|
||||
mShouldBuildScrollableLayer = usingDisplayport || nsContentUtils::HasScrollgrab(mOuter->GetContent());
|
||||
bool shouldBuildLayer = false;
|
||||
if (mShouldBuildScrollableLayer) {
|
||||
shouldBuildLayer = true;
|
||||
} else {
|
||||
shouldBuildLayer =
|
||||
nsLayoutUtils::WantSubAPZC() &&
|
||||
WantAsyncScroll() &&
|
||||
// If we are the root scroll frame for the display root then we don't need a scroll
|
||||
// info layer to make a RecordFrameMetrics call for us as
|
||||
// nsDisplayList::PaintForFrame already calls RecordFrameMetrics for us.
|
||||
(!mIsRoot || aBuilder->RootReferenceFrame()->PresContext() != mOuter->PresContext());
|
||||
}
|
||||
|
||||
if (shouldBuildLayer) {
|
||||
// ScrollLayerWrapper must always be created because it initializes the
|
||||
// scroll layer count. The display lists depend on this.
|
||||
|
|
|
@ -436,6 +436,12 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
|
||||
if (subdocRootFrame) {
|
||||
nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(
|
||||
aBuilder,
|
||||
ignoreViewportScrolling && subdocRootFrame->GetContent()
|
||||
? nsLayoutUtils::FindOrCreateIDFor(subdocRootFrame->GetContent())
|
||||
: aBuilder->GetCurrentScrollParentId());
|
||||
|
||||
aBuilder->SetAncestorHasTouchEventHandler(false);
|
||||
subdocRootFrame->
|
||||
BuildDisplayListForStackingContext(aBuilder, dirty, &childItems);
|
||||
|
|
Загрузка…
Ссылка в новой задаче