diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index d957d32edf90..e7391c6b0239 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -6723,6 +6723,17 @@ nsCharClipDisplayItem::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, } } +nsDisplaySVGEffects::nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, + nsIFrame* aFrame, nsDisplayList* aList, + bool aHandleOpacity, + const DisplayItemScrollClip* aScrollClip) + : nsDisplayWrapList(aBuilder, aFrame, aList, aScrollClip) + , mEffectsBounds(aFrame->GetVisualOverflowRectRelativeToSelf()) + , mHandleOpacity(aHandleOpacity) +{ + MOZ_COUNT_CTOR(nsDisplaySVGEffects); +} + nsDisplaySVGEffects::nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, bool aHandleOpacity) @@ -6817,8 +6828,9 @@ bool nsDisplaySVGEffects::ValidateSVGFrame() nsDisplayMask::nsDisplayMask(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, - bool aHandleOpacity) - : nsDisplaySVGEffects(aBuilder, aFrame, aList, aHandleOpacity) + bool aHandleOpacity, + const DisplayItemScrollClip* aScrollClip) + : nsDisplaySVGEffects(aBuilder, aFrame, aList, aHandleOpacity, aScrollClip) { MOZ_COUNT_CTOR(nsDisplayMask); } diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 07ded13087f6..708dd560d90d 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -3839,6 +3839,9 @@ private: class nsDisplaySVGEffects: public nsDisplayWrapList { public: + nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, + nsDisplayList* aList, bool aHandleOpacity, + const DisplayItemScrollClip* aScrollClip); nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, bool aHandleOpacity); #ifdef NS_BUILD_REFCNT_LOGGING @@ -3886,7 +3889,8 @@ protected: class nsDisplayMask : public nsDisplaySVGEffects { public: nsDisplayMask(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, - nsDisplayList* aList, bool aHandleOpacity); + nsDisplayList* aList, bool aHandleOpacity, + const DisplayItemScrollClip* aScrollClip); #ifdef NS_BUILD_REFCNT_LOGGING virtual ~nsDisplayMask(); #endif diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 5184c69c94ca..02e501e0bd5b 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -2183,8 +2183,10 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, } inTransform = true; } + bool usingFilter = StyleEffects()->HasFilters(); + bool usingMask = nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(this); + bool usingSVGEffects = usingFilter || usingMask; - bool usingSVGEffects = nsSVGIntegrationUtils::UsingEffectsForFrame(this); nsRect dirtyRectOutsideSVGEffects = dirtyRect; nsDisplayList hoistedScrollInfoItemsStorage; if (usingSVGEffects) { @@ -2226,7 +2228,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, eTransform, eSeparatorTransforms, eOpacity, - eSVGEffects, + eFilter, eBlendContainer }; @@ -2258,8 +2260,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, } else { clipCapturedBy = ContainerItemType::eTransform; } - } else if (usingSVGEffects) { - clipCapturedBy = ContainerItemType::eSVGEffects; + } else if (usingFilter) { + clipCapturedBy = ContainerItemType::eFilter; } bool clearClip = false; @@ -2407,26 +2409,21 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, * output even if the element being filtered wouldn't otherwise do so. */ if (usingSVGEffects) { - MOZ_ASSERT(StyleEffects()->HasFilters() || - nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(this), + MOZ_ASSERT(usingFilter ||usingMask, "Beside filter & mask/clip-path, what else effect do we have?"); - if (clipCapturedBy == ContainerItemType::eSVGEffects) { + if (clipCapturedBy == ContainerItemType::eFilter) { clipState.ExitStackingContextContents(&containerItemScrollClip); } // Revert to the post-filter dirty rect. buildingDisplayList.SetDirtyRect(dirtyRectOutsideSVGEffects); // Skip all filter effects while generating glyph mask. - bool createFilter = - StyleEffects()->HasFilters() && !aBuilder->IsForGenerateGlyphMask(); - bool createMask = nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(this); - - if (createFilter) { + if (usingFilter && !aBuilder->IsForGenerateGlyphMask()) { // If we are going to create a mask display item, handle opacity effect // in that mask display item; Otherwise, take care of opacity in this // filter display item. - bool handleOpacity = !createMask && !useOpacity; + bool handleOpacity = !usingMask && !useOpacity; /* List now emptied, so add the new list to the top. */ resultList.AppendNewToTop( @@ -2434,11 +2431,13 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, handleOpacity)); } - if (createMask) { + if (usingMask) { + DisplayListClipState::AutoSaveRestore maskClipState(aBuilder); + maskClipState.Clear(); /* List now emptied, so add the new list to the top. */ resultList.AppendNewToTop( new (aBuilder) nsDisplayMask(aBuilder, this, &resultList, - !useOpacity)); + !useOpacity, containerItemScrollClip)); } // Also add the hoisted scroll info items. We need those for APZ scrolling