Allow containerless scrolling for root scroll frames, too. (bug 1076192, r=tn)

--HG--
extra : rebase_source : 29d74a8734aabc0e583ad5e372f7b04bcc9e2b8f
This commit is contained in:
David Anderson 2014-12-17 15:37:28 -08:00
Родитель 7f2f1073ca
Коммит 9b99c0f6d4
8 изменённых файлов: 73 добавлений и 39 удалений

Просмотреть файл

@ -375,7 +375,7 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
new DisplayPortPropertyData(displayport, aPriority),
nsINode::DeleteProperty<DisplayPortPropertyData>);
if (nsLayoutUtils::UsesAsyncScrolling()) {
if (nsLayoutUtils::UsesAsyncScrolling() && gfxPrefs::LayoutUseContainersForRootFrames()) {
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
if (rootScrollFrame && content == rootScrollFrame->GetContent()) {
// We are setting a root displayport for a document.

Просмотреть файл

@ -330,6 +330,9 @@ private:
DECL_GFX_PREF(Once, "dom.vr.enabled", VREnabled, bool, false);
DECL_GFX_PREF(Once, "dom.vr.add-test-devices", VRAddTestDevices, int32_t, 1);
// This and code dependent on it should be removed once containerless scrolling looks stable.
DECL_GFX_PREF(Once, "layout.scroll.root-frame-containers", LayoutUseContainersForRootFrames, bool, true);
public:
// Manage the singleton:
static gfxPrefs& GetSingleton()

Просмотреть файл

@ -3034,9 +3034,11 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
scrollItem->IsDisplayPortOpaque();
newLayerEntry->mBaseFrameMetrics =
scrollItem->ComputeFrameMetrics(ownLayer, mParameters);
} else if (itemType == nsDisplayItem::TYPE_SUBDOCUMENT ||
itemType == nsDisplayItem::TYPE_ZOOM ||
itemType == nsDisplayItem::TYPE_RESOLUTION) {
} else if ((itemType == nsDisplayItem::TYPE_SUBDOCUMENT ||
itemType == nsDisplayItem::TYPE_ZOOM ||
itemType == nsDisplayItem::TYPE_RESOLUTION) &&
gfxPrefs::LayoutUseContainersForRootFrames())
{
newLayerEntry->mBaseFrameMetrics =
static_cast<nsDisplaySubDocument*>(item)->ComputeFrameMetrics(ownLayer, mParameters);
}

Просмотреть файл

@ -1503,23 +1503,25 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
root->SetPostScale(1.0f/containerParameters.mXScale,
1.0f/containerParameters.mYScale);
bool isRoot = presContext->IsRootContentDocument();
if (gfxPrefs::LayoutUseContainersForRootFrames()) {
bool isRoot = presContext->IsRootContentDocument();
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
nsRect viewport(aBuilder->ToReferenceFrame(frame), frame->GetSize());
nsRect viewport(aBuilder->ToReferenceFrame(frame), frame->GetSize());
root->SetFrameMetrics(
nsDisplayScrollLayer::ComputeFrameMetrics(frame, rootScrollFrame,
aBuilder->FindReferenceFrameFor(frame),
root, FrameMetrics::NULL_SCROLL_ID, viewport,
!isRoot, isRoot, containerParameters));
root->SetFrameMetrics(
nsDisplayScrollLayer::ComputeFrameMetrics(frame, rootScrollFrame,
aBuilder->FindReferenceFrameFor(frame),
root, FrameMetrics::NULL_SCROLL_ID, viewport,
!isRoot, isRoot, containerParameters));
}
// NS_WARNING is debug-only, so don't even bother checking the conditions in
// a release build.
#ifdef DEBUG
bool usingDisplayport = false;
if (rootScrollFrame) {
if (nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame()) {
nsIContent* content = rootScrollFrame->GetContent();
if (content) {
usingDisplayport = nsLayoutUtils::GetDisplayPort(content, nullptr);

Просмотреть файл

@ -1014,7 +1014,7 @@ nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent,
aMargins, aPriority),
nsINode::DeleteProperty<DisplayPortMarginsPropertyData>);
if (nsLayoutUtils::UsesAsyncScrolling()) {
if (nsLayoutUtils::UsesAsyncScrolling() && gfxPrefs::LayoutUseContainersForRootFrames()) {
nsIFrame* rootScrollFrame = aPresShell->GetRootScrollFrame();
if (rootScrollFrame && aContent == rootScrollFrame->GetContent()) {
// We are setting a root displayport for a document.

Просмотреть файл

@ -2847,6 +2847,8 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
mOuter->PresContext()->IsRootContentDocument();
if (aBuilder->GetIgnoreScrollFrame() == mOuter || IsIgnoringViewportClipping()) {
// Root scrollframes have FrameMetrics and clipping on their container
// layers, so don't apply clipping again.
mAddClipRectToLayer = false;
// If we are a root scroll frame that has a display port we want to add
@ -2877,6 +2879,8 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
return;
}
// Root scrollframes have FrameMetrics and clipping on their container
// layers, so don't apply clipping again.
mAddClipRectToLayer =
!(mIsRoot && mOuter->PresContext()->PresShell()->GetIsViewportOverridden());
@ -2895,7 +2899,23 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (aBuilder->IsPaintingToWindow()) {
bool wasUsingDisplayPort = nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), nullptr);
if (!mIsRoot) {
if (mIsRoot) {
if (gfxPrefs::LayoutUseContainersForRootFrames()) {
// For a root frame in a container, just get the value of the existing
// display port if any.
usingDisplayport = nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayPort);
} else {
// Override the value of the display port base rect, and possibly create a
// display port if there isn't one already.
nsRect displayportBase = dirtyRect;
if (mIsRoot && mOuter->PresContext()->IsRootContentDocument()) {
displayportBase =
nsRect(nsPoint(0, 0), nsLayoutUtils::CalculateCompositionSizeForFrame(mOuter));
}
usingDisplayport = nsLayoutUtils::GetOrMaybeCreateDisplayPort(
*aBuilder, mOuter, displayportBase, &displayPort);
}
} else {
// For a non-root scroll frame, override the value of the display port
// base rect, and possibly create a display port if there isn't one
// already. For root scroll frame, nsLayoutUtils::PaintFrame or
@ -2903,10 +2923,6 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsRect displayportBase = dirtyRect;
usingDisplayport = nsLayoutUtils::GetOrMaybeCreateDisplayPort(
*aBuilder, mOuter, displayportBase, &displayPort);
} else {
// For a root frame, just get the value of the existing display port, if
// any.
usingDisplayport = nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayPort);
}
bool usingLowPrecision = gfxPrefs::UseLowPrecisionBuffer();
@ -2968,10 +2984,12 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
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 ComputeFrameMetrics call for us as
// nsDisplayList::PaintForFrame already calls ComputeFrameMetrics for us.
(!mIsRoot || aBuilder->RootReferenceFrame()->PresContext() != mOuter->PresContext());
// If we are using containers for root frames, and we are the root
// scroll frame for the display root, then we don't need a scroll
// info layer. nsDisplayList::PaintForFrame already calls
// ComputeFrameMetrics for us.
(!(gfxPrefs::LayoutUseContainersForRootFrames() && mIsRoot) ||
(aBuilder->RootReferenceFrame()->PresContext() != mOuter->PresContext()));
}
if (aBuilder->IsPaintingToWindow() &&
@ -3119,8 +3137,6 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
{
nsRect scrollport = mScrollPort +
mOuter->GetOffsetToCrossDoc(aContainerReferenceFrame);
// Root scrollframes have FrameMetrics and clipping on their container layers,
// so don't also apply clipping here.
if (mAddClipRectToLayer) {
*aClipRect = scrollport;
}
@ -3131,10 +3147,12 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
MOZ_ASSERT(mScrolledFrame->GetContent());
bool isRoot = mIsRoot && mOuter->PresContext()->IsRootContentDocument();
*aOutput->AppendElement() =
nsDisplayScrollLayer::ComputeFrameMetrics(mScrolledFrame, mOuter,
aContainerReferenceFrame, aLayer, mScrollParentID,
scrollport, false, false, aParameters);
scrollport, false, isRoot, aParameters);
}
bool

Просмотреть файл

@ -450,6 +450,7 @@ public:
// If true, the layer should always be active because we always build a
// scrollable layer. Used for asynchronous scrolling.
bool mShouldBuildScrollableLayer:1;
// If true, add clipping in ScrollFrameHelper::ComputeFrameMetrics.
bool mAddClipRectToLayer:1;

Просмотреть файл

@ -413,16 +413,18 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
dirty = dirty.ConvertAppUnitsRoundOut(parentAPD, subdocAPD);
if (nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame()) {
// for root content documents we want the base to be the composition bounds
nsRect displayportBase = presContext->IsRootContentDocument() ?
nsRect(nsPoint(0,0), nsLayoutUtils::CalculateCompositionSizeForFrame(rootScrollFrame)) :
dirty.Intersect(nsRect(nsPoint(0,0), subdocRootFrame->GetSize()));
nsRect displayPort;
if (aBuilder->IsPaintingToWindow() &&
nsLayoutUtils::GetOrMaybeCreateDisplayPort(
*aBuilder, rootScrollFrame, displayportBase, &displayPort)) {
haveDisplayPort = true;
dirty = displayPort;
if (gfxPrefs::LayoutUseContainersForRootFrames()) {
// for root content documents we want the base to be the composition bounds
nsRect displayportBase = presContext->IsRootContentDocument() ?
nsRect(nsPoint(0,0), nsLayoutUtils::CalculateCompositionSizeForFrame(rootScrollFrame)) :
dirty.Intersect(nsRect(nsPoint(0,0), subdocRootFrame->GetSize()));
nsRect displayPort;
if (aBuilder->IsPaintingToWindow() &&
nsLayoutUtils::GetOrMaybeCreateDisplayPort(
*aBuilder, rootScrollFrame, displayportBase, &displayPort)) {
haveDisplayPort = true;
dirty = displayPort;
}
}
ignoreViewportScrolling = presShell->IgnoringViewportScrolling();
@ -453,9 +455,15 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
bool constructResolutionItem = subdocRootFrame &&
(presShell->GetXResolution() != 1.0 || presShell->GetYResolution() != 1.0);
bool constructZoomItem = subdocRootFrame && parentAPD != subdocAPD;
bool needsOwnLayer = constructResolutionItem || constructZoomItem ||
haveDisplayPort ||
presContext->IsRootContentDocument() || (sf && sf->IsScrollingActive(aBuilder));
bool needsOwnLayer = false;
if (constructResolutionItem ||
constructZoomItem ||
haveDisplayPort ||
presContext->IsRootContentDocument() ||
(sf && sf->IsScrollingActive(aBuilder)))
{
needsOwnLayer = true;
}
nsDisplayList childItems;