Bug 1398706 - Always create new clip ids in ScrollingLayersHelper if it's inside a mask. r=kats

MozReview-Commit-ID: Hhsbgpqddo1

--HG--
extra : rebase_source : 40507644148da5bfe6ca3dd5f1f438ac9e7e10ff
This commit is contained in:
Ethan Lin 2017-09-19 17:05:22 +08:00
parent f7dc9cf879
commit fb32d577e9
4 changed files with 24 additions and 10 deletions

View File

@ -226,7 +226,7 @@ ScrollingLayersHelper::DefineAndPushChain(const DisplayItemClipChain* aChain,
// This item in the chain is a no-op, skip over it
return;
}
if (!clipId) {
if (!clipId || aBuilder.HasMaskClip()) {
// If we don't have a clip id for this chain item yet, define the clip in WR
// and save the id
LayoutDeviceRect clip = LayoutDeviceRect::FromAppUnits(
@ -234,7 +234,9 @@ ScrollingLayersHelper::DefineAndPushChain(const DisplayItemClipChain* aChain,
nsTArray<wr::WrComplexClipRegion> wrRoundedRects;
aChain->mClip.ToWrComplexClipRegions(aAppUnitsPerDevPixel, aStackingContext, wrRoundedRects);
clipId = Some(aBuilder.DefineClip(aStackingContext.ToRelativeLayoutRect(clip), &wrRoundedRects));
aCache[aChain] = clipId.value();
if (!aBuilder.HasMaskClip()) {
aCache[aChain] = clipId.value();
}
}
// Finally, push the clip onto the WR stack
MOZ_ASSERT(clipId);

View File

@ -622,6 +622,7 @@ WebRenderAPI::RunOnRenderThread(UniquePtr<RendererEvent> aEvent)
DisplayListBuilder::DisplayListBuilder(PipelineId aId,
const wr::LayoutSize& aContentSize)
: mMaskClipCount(0)
{
MOZ_COUNT_CTOR(DisplayListBuilder);
mWrState = wr_state_new(aId, aContentSize);
@ -707,21 +708,25 @@ DisplayListBuilder::DefineClip(const wr::LayoutRect& aClipRect,
}
void
DisplayListBuilder::PushClip(const wr::WrClipId& aClipId, bool aRecordInStack)
DisplayListBuilder::PushClip(const wr::WrClipId& aClipId, bool aMask)
{
wr_dp_push_clip(mWrState, aClipId.id);
WRDL_LOG("PushClip id=%" PRIu64 "\n", mWrState, aClipId.id);
if (aRecordInStack) {
if (!aMask) {
mClipIdStack.push_back(aClipId);
} else {
mMaskClipCount++;
}
}
void
DisplayListBuilder::PopClip(bool aRecordInStack)
DisplayListBuilder::PopClip(bool aMask)
{
WRDL_LOG("PopClip id=%" PRIu64 "\n", mWrState, mClipIdStack.back().id);
if (aRecordInStack) {
if (!aMask) {
mClipIdStack.pop_back();
} else {
mMaskClipCount--;
}
wr_dp_pop_clip(mWrState);
}

View File

@ -226,8 +226,8 @@ public:
wr::WrClipId DefineClip(const wr::LayoutRect& aClipRect,
const nsTArray<wr::WrComplexClipRegion>* aComplex = nullptr,
const wr::WrImageMask* aMask = nullptr);
void PushClip(const wr::WrClipId& aClipId, bool aRecordInStack = true);
void PopClip(bool aRecordInStack = true);
void PushClip(const wr::WrClipId& aClipId, bool aMask = false);
void PopClip(bool aMask = false);
wr::WrStickyId DefineStickyFrame(const wr::LayoutRect& aContentRect,
const wr::StickySideConstraint* aTop,
@ -401,6 +401,10 @@ public:
// Try to avoid using this when possible.
wr::WrState* Raw() { return mWrState; }
// Return true if the current clip stack has any mask type clip.
bool HasMaskClip() { return mMaskClipCount > 0; }
protected:
wr::WrState* mWrState;
@ -416,6 +420,9 @@ protected:
// ensure that we don't define a particular scroll layer multiple times.
std::unordered_map<layers::FrameMetrics::ViewID, Maybe<layers::FrameMetrics::ViewID>> mScrollParents;
// The number of mask clips that are in the stack.
uint32_t mMaskClipCount;
friend class WebRenderAPI;
};

View File

@ -9155,13 +9155,13 @@ nsDisplayMask::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder
// Don't record this clip push in aBuilder's internal clip stack, because
// otherwise any nested ScrollingLayersHelper instances that are created
// will get confused about which clips are pushed.
aBuilder.PushClip(clipId, /*aRecordInStack*/ false);
aBuilder.PushClip(clipId, /*aMask*/ true);
}
nsDisplaySVGEffects::CreateWebRenderCommands(aBuilder, aResources, aSc, aManager, aDisplayListBuilder);
if (mask) {
aBuilder.PopClip(/*aRecordInStack*/ false);
aBuilder.PopClip(/*aMask*/ true);
}
return true;