Bug 1529992 - disable the MergeClipLeaf optimization for all shadows properly. r=kats

Differential Revision: https://phabricator.services.mozilla.com/D27114

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alexis Beingessner 2019-04-15 23:13:49 +00:00
Родитель 92010a39a6
Коммит 99e4403911
3 изменённых файлов: 52 добавлений и 12 удалений

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

@ -155,16 +155,10 @@ wr::WrSpaceAndClipChain ClipManager::SwitchItem(nsDisplayItem* aItem) {
// some overhead further down the pipeline.
bool separateLeaf = false;
if (clip && clip->mASR == asr && clip->mClip.GetRoundedRectCount() == 0) {
if (type == DisplayItemType::TYPE_TEXT) {
// Text with shadows interprets the text display item clip rect and
// clips from the clip chain differently.
separateLeaf = !aItem->Frame()->StyleText()->HasTextShadow();
} else {
// Container display items are not currently supported because the clip
// rect of a stacking context is not handled the same as normal display
// items.
separateLeaf = aItem->GetChildren() == nullptr;
}
// Container display items are not currently supported because the clip
// rect of a stacking context is not handled the same as normal display
// items.
separateLeaf = aItem->GetChildren() == nullptr;
}
ItemClips clips(asr, clip, separateLeaf);

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

@ -1127,11 +1127,48 @@ void DisplayListBuilder::PushShadow(const wr::LayoutRect& aRect,
const wr::LayoutRect& aClip,
bool aIsBackfaceVisible,
const wr::Shadow& aShadow) {
wr_dp_push_shadow(mWrState, aRect, MergeClipLeaf(aClip), aIsBackfaceVisible,
// Local clip_rects are translated inside of shadows, as they are assumed to
// be part of the element drawing itself, and not a parent frame clipping it.
// As such, it is not sound to apply the MergeClipLeaf optimization inside of
// shadows. So we disable the optimization when we encounter a shadow.
// Shadows don't span frames, so we don't have to worry about MergeClipLeaf
// being re-enabled mid-shadow. The optimization is restored in PopAllShadows.
SuspendClipLeafMerging();
wr_dp_push_shadow(mWrState, aRect, aClip, aIsBackfaceVisible,
&mCurrentSpaceAndClipChain, aShadow);
}
void DisplayListBuilder::PopAllShadows() { wr_dp_pop_all_shadows(mWrState); }
void DisplayListBuilder::PopAllShadows() {
wr_dp_pop_all_shadows(mWrState);
ResumeClipLeafMerging();
}
void DisplayListBuilder::SuspendClipLeafMerging() {
if (mClipChainLeaf) {
// No one should reinitialize mClipChainLeaf while we're suspended
MOZ_ASSERT(!mSuspendedClipChainLeaf);
mSuspendedClipChainLeaf = mClipChainLeaf;
mSuspendedSpaceAndClipChain = Some(mCurrentSpaceAndClipChain);
// Clip is implicitly parented by mCurrentSpaceAndClipChain
auto clipId = DefineClip(Nothing(), *mClipChainLeaf);
auto clipChainId = DefineClipChain({ clipId });
mCurrentSpaceAndClipChain.clip_chain = clipChainId.id;
mClipChainLeaf = Nothing();
}
}
void DisplayListBuilder::ResumeClipLeafMerging() {
if (mSuspendedClipChainLeaf) {
mCurrentSpaceAndClipChain = *mSuspendedSpaceAndClipChain;
mClipChainLeaf = mSuspendedClipChainLeaf;
mSuspendedClipChainLeaf = Nothing();
mSuspendedSpaceAndClipChain = Nothing();
}
}
void DisplayListBuilder::PushBoxShadow(
const wr::LayoutRect& aRect, const wr::LayoutRect& aClip,

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

@ -594,6 +594,10 @@ class DisplayListBuilder final {
return aClip;
}
// See the implementation of PushShadow for details on these methods.
void SuspendClipLeafMerging();
void ResumeClipLeafMerging();
wr::WrState* mWrState;
// Track each scroll id that we encountered. We use this structure to
@ -609,6 +613,11 @@ class DisplayListBuilder final {
// there is no clip rect to merge with.
Maybe<wr::LayoutRect> mClipChainLeaf;
// Versions of the above that are on hold while SuspendClipLeafMerging is on
// (see the implementation of PushShadow for details).
Maybe<wr::WrSpaceAndClipChain> mSuspendedSpaceAndClipChain;
Maybe<wr::LayoutRect> mSuspendedClipChainLeaf;
RefPtr<layout::TextDrawTarget> mCachedTextDT;
RefPtr<gfxContext> mCachedContext;