Bug 1168629. Always make sure that there is at least one layer with the metrics for the root scroll frame/root element. r=botond,kats

We do this by looking at the layer tree after it has been made to see if the root metrics are in it already.

This is needed to ensure that there is always a root AZPC in a process.
This commit is contained in:
Timothy Nikkel 2015-05-31 00:50:21 -05:00
Родитель f6f47533e7
Коммит 525e5c2132
3 изменённых файлов: 57 добавлений и 19 удалений

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

@ -1547,31 +1547,47 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
// want the root container layer to have metrics. If the parent process is
// using XUL windows, there is no root scrollframe, and without explicitly
// creating metrics there will be no guaranteed top-level APZC.
if (gfxPrefs::LayoutUseContainersForRootFrames() ||
(XRE_IsParentProcess() && !presShell->GetRootScrollFrame()))
{
bool addMetrics = gfxPrefs::LayoutUseContainersForRootFrames() ||
(XRE_IsParentProcess() && !presShell->GetRootScrollFrame());
// Add metrics if there are none in the layer tree with the id (create an id
// if there isn't one already) of the root scroll frame/root content.
bool ensureMetricsForRootId =
gfxPrefs::AsyncPanZoomEnabled() &&
!gfxPrefs::LayoutUseContainersForRootFrames() &&
aBuilder->IsPaintingToWindow() &&
!presContext->GetParentPresContext();
nsIContent* content = nullptr;
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
if (rootScrollFrame) {
content = rootScrollFrame->GetContent();
} else {
// If there is no root scroll frame, pick the document element instead.
// The only case we don't want to do this is in non-APZ fennec, where
// we want the root xul document to get a null scroll id so that the root
// content document gets the first non-null scroll id.
#if !defined(MOZ_WIDGET_ANDROID) || defined(MOZ_ANDROID_APZ)
content = document->GetDocumentElement();
#endif
}
if (ensureMetricsForRootId && content) {
ViewID scrollId = nsLayoutUtils::FindOrCreateIDFor(content);
if (nsLayoutUtils::ContainsMetricsWithId(root, scrollId)) {
ensureMetricsForRootId = false;
}
}
if (addMetrics || ensureMetricsForRootId) {
bool isRoot = presContext->IsRootContentDocument();
nsRect viewport(aBuilder->ToReferenceFrame(frame), frame->GetSize());
nsIFrame* scrollFrame = presShell->GetRootScrollFrame();
nsIContent* content = nullptr;
if (scrollFrame) {
content = scrollFrame->GetContent();
} else {
// If there is no root scroll frame, pick the document element instead.
// The only case we don't want to do this is in non-APZ fennec, where
// we want the root xul document to get a null scroll id so that the root
// content document gets the first non-null scroll id.
#if !defined(MOZ_WIDGET_ANDROID) || defined(MOZ_ANDROID_APZ)
content = document->GetDocumentElement();
#endif
}
root->SetFrameMetrics(
nsLayoutUtils::ComputeFrameMetrics(frame,
presShell->GetRootScrollFrame(),
content,
rootScrollFrame, content,
aBuilder->FindReferenceFrameFor(frame),
root, FrameMetrics::NULL_SCROLL_ID, viewport, Nothing(),
isRoot, containerParameters));

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

@ -8343,6 +8343,22 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame,
return metrics;
}
/* static */ bool
nsLayoutUtils::ContainsMetricsWithId(const Layer* aLayer, const ViewID& aScrollId)
{
for (uint32_t i = aLayer->GetFrameMetricsCount(); i > 0; i--) {
if (aLayer->GetFrameMetrics(i-1).GetScrollId() == aScrollId) {
return true;
}
}
for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) {
if (ContainsMetricsWithId(child, aScrollId)) {
return true;
}
}
return false;
}
/* static */ uint32_t
nsLayoutUtils::GetTouchActionFromFrame(nsIFrame* aFrame)
{

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

@ -2660,6 +2660,12 @@ public:
*/
static nsMargin ScrollbarAreaToExcludeFromCompositionBoundsFor(nsIFrame* aScrollFrame);
/**
* Looks in the layer subtree rooted at aLayer for a metrics with scroll id
* aScrollId. Returns true if such is found.
*/
static bool ContainsMetricsWithId(const Layer* aLayer, const ViewID& aScrollId);
private:
static uint32_t sFontSizeInflationEmPerLine;
static uint32_t sFontSizeInflationMinTwips;