Bug 1409446 - Handle nested display item scenarios. r=mstange

This handles some cases where a nested display item's clip chain
implicitly extends from the wrapper item's clip chain.

MozReview-Commit-ID: DmghxOWi81K

--HG--
extra : rebase_source : 8ec95df64fed247650baf8f5e0c868d1934aa6bc
This commit is contained in:
Kartikaya Gupta 2017-10-24 15:46:00 -04:00
Родитель 4fcc51960c
Коммит 83ac5fdb91
3 изменённых файлов: 31 добавлений и 0 удалений

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

@ -184,6 +184,26 @@ ScrollingLayersHelper::RecurseAndDefineClip(nsDisplayItem* aItem,
// than aChain->mParent.
ancestorIds.second = Nothing();
}
} else {
MOZ_ASSERT(!ancestorIds.second);
// If aChain->mASR is already the topmost scroll layer on the stack, but
// but there was another clip pushed *on top* of that ASR, then that clip
// shares the ASR, and we need to make our clip a child of that clip, which
// in turn will already be a descendant of the correct ASR.
// This covers the cases where e.g. the Gecko display list has nested items,
// and the clip chain on the nested item implicitly extends from the clip
// chain on the containing wrapper item. In this case the aChain->mParent
// pointer will be null for the nested item but the containing wrapper's
// clip will be on the stack already and we can pick it up from there.
// Another way of thinking about this is that if the clip chain were
// "fully completed" then aChain->mParent wouldn't be null but would point
// to the clip corresponding to mBuilder->TopmostClipId(), and we would
// have gone into the |aChain->mParent->mASR == aAsr| branch above.
FrameMetrics::ViewID scrollId = aChain->mASR ? nsLayoutUtils::ViewIDForASR(aChain->mASR) : FrameMetrics::NULL_SCROLL_ID;
if (mBuilder->TopmostScrollId() == scrollId && mBuilder->TopmostIsClip()) {
ancestorIds.first = Nothing();
ancestorIds.second = mBuilder->TopmostClipId();
}
}
// At most one of the ancestor pair should be defined here, and the one that
// is defined will be the parent clip for the new clip that we're defining.

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

@ -1169,5 +1169,14 @@ DisplayListBuilder::TopmostScrollId()
return layers::FrameMetrics::NULL_SCROLL_ID;
}
bool
DisplayListBuilder::TopmostIsClip()
{
if (mClipStack.empty()) {
return false;
}
return mClipStack.back().is<wr::WrClipId>();
}
} // namespace wr
} // namespace mozilla

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

@ -405,6 +405,8 @@ public:
Maybe<wr::WrClipId> TopmostClipId();
// Same as TopmostClipId() but for scroll layers.
layers::FrameMetrics::ViewID TopmostScrollId();
// If the topmost item on the stack is a clip or a scroll layer
bool TopmostIsClip();
// Try to avoid using this when possible.
wr::WrState* Raw() { return mWrState; }