diff --git a/gfx/layers/wr/WebRenderCommandBuilder.cpp b/gfx/layers/wr/WebRenderCommandBuilder.cpp index eb3c69a4b428..214b73fbad93 100644 --- a/gfx/layers/wr/WebRenderCommandBuilder.cpp +++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp @@ -1543,8 +1543,7 @@ PaintItemByDrawTarget(nsDisplayItem* aItem, switch (aItem->GetType()) { case DisplayItemType::TYPE_MASK: context->SetMatrix(context->CurrentMatrix().PreScale(aScale.width, aScale.height).PreTranslate(-aOffset.x, -aOffset.y)); - static_cast(aItem)->PaintMask(aDisplayListBuilder, context); - isInvalidated = true; + static_cast(aItem)->PaintMask(aDisplayListBuilder, context, &isInvalidated); break; case DisplayItemType::TYPE_SVG_WRAPPER: { diff --git a/gfx/tests/reftest/1461313-ref.html b/gfx/tests/reftest/1461313-ref.html new file mode 100644 index 000000000000..14a5f811ce83 --- /dev/null +++ b/gfx/tests/reftest/1461313-ref.html @@ -0,0 +1,4 @@ + + +
+ diff --git a/gfx/tests/reftest/1461313.html b/gfx/tests/reftest/1461313.html new file mode 100644 index 000000000000..71e492d40de4 --- /dev/null +++ b/gfx/tests/reftest/1461313.html @@ -0,0 +1,9 @@ + + + +
+ diff --git a/gfx/tests/reftest/reftest.list b/gfx/tests/reftest/reftest.list index a19750f46b8a..b29dd3bfae44 100644 --- a/gfx/tests/reftest/reftest.list +++ b/gfx/tests/reftest/reftest.list @@ -14,3 +14,4 @@ fuzzy(100,30) == 1149923.html 1149923-ref.html # use fuzzy due to few distorted == 1444904.html 1444904-ref.html == 1451168.html 1451168-ref.html fuzzy(5-32,21908-26354) fuzzy-if(webrender,0-1,0-3) == 1463802.html 1463802-ref.html +== 1461313.html 1461313-ref.html diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index f0aa8c33efb5..26129baa8431 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -9200,7 +9200,8 @@ nsDisplayMask::BuildLayer(nsDisplayListBuilder* aBuilder, bool nsDisplayMask::PaintMask(nsDisplayListBuilder* aBuilder, - gfxContext* aMaskContext) + gfxContext* aMaskContext, + bool* aMaskPainted) { MOZ_ASSERT(aMaskContext->GetDrawTarget()->GetFormat() == SurfaceFormat::A8); @@ -9214,7 +9215,10 @@ nsDisplayMask::PaintMask(nsDisplayListBuilder* aBuilder, nullptr, mHandleOpacity, imgParmas); ComputeMaskGeometry(params); - nsSVGIntegrationUtils::PaintMask(params); + bool painted = nsSVGIntegrationUtils::PaintMask(params); + if (aMaskPainted) { + *aMaskPainted = painted; + } nsDisplayMaskGeometry::UpdateDrawResult(this, imgParmas.result); diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index b580e2c09661..6bdd81797a08 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -6093,7 +6093,9 @@ public: * Paint mask onto aMaskContext in mFrame's coordinate space and * return whether the mask layer was painted successfully. */ - bool PaintMask(nsDisplayListBuilder* aBuilder, gfxContext* aMaskContext); + bool PaintMask(nsDisplayListBuilder* aBuilder, + gfxContext* aMaskContext, + bool* aMaskPainted = nullptr); const nsTArray& GetDestRects() { diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index d2168eeec7f9..6b7bdbac6a7a 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -593,7 +593,7 @@ CreateAndPaintMaskSurface(const PaintFramesParams& aParams, // For a SVG doc: // SVG 1.1 say that if we fail to resolve a mask, we should draw the // object unmasked. - // Left patinResult.maskSurface empty, the caller should paint all + // Left paintResult.maskSurface empty, the caller should paint all // masked content as if this mask is an opaque white one(no mask). paintResult.transparentBlackMask = !(aParams.frame->GetStateBits() & NS_FRAME_SVG_LAYOUT); @@ -760,16 +760,19 @@ private: gfxContext* mContext; }; -void +bool nsSVGIntegrationUtils::PaintMask(const PaintFramesParams& aParams) { nsSVGUtils::MaskUsage maskUsage; nsSVGUtils::DetermineMaskUsage(aParams.frame, aParams.handleOpacity, maskUsage); + if (!maskUsage.shouldDoSomething()) { + return false; + } nsIFrame* frame = aParams.frame; if (!ValidateSVGFrame(frame)) { - return; + return false; } gfxContext& ctx = aParams.ctx; @@ -819,7 +822,7 @@ nsSVGIntegrationUtils::PaintMask(const PaintFramesParams& aParams) ctx.SetColor(Color(1.0, 1.0, 1.0, 1.0)); ctx.Fill(); - return; + return true; } } @@ -852,6 +855,8 @@ nsSVGIntegrationUtils::PaintMask(const PaintFramesParams& aParams) &clipMaskTransform, maskSurface, ctx.CurrentMatrix()); } + + return true; } void diff --git a/layout/svg/nsSVGIntegrationUtils.h b/layout/svg/nsSVGIntegrationUtils.h index cf75aef3528b..1a74cece2414 100644 --- a/layout/svg/nsSVGIntegrationUtils.h +++ b/layout/svg/nsSVGIntegrationUtils.h @@ -168,9 +168,10 @@ public: /** * Paint mask of non-SVG frame onto a given context, aParams.ctx. - * aParams.ctx must contain an A8 surface. + * aParams.ctx must contain an A8 surface. Returns false if the mask + * didn't get painted and should be ignored at the call site. */ - static void + static bool PaintMask(const PaintFramesParams& aParams); /** diff --git a/layout/svg/nsSVGUtils.h b/layout/svg/nsSVGUtils.h index 705af36b6315..44784ce5d63d 100644 --- a/layout/svg/nsSVGUtils.h +++ b/layout/svg/nsSVGUtils.h @@ -613,6 +613,14 @@ public: : shouldGenerateMaskLayer(false), shouldGenerateClipMaskLayer(false), shouldApplyClipPath(false), shouldApplyBasicShape(false), opacity(0.0) { } + + bool shouldDoSomething() { + return shouldGenerateMaskLayer + || shouldGenerateClipMaskLayer + || shouldApplyClipPath + || shouldApplyBasicShape + || opacity != 1.0; + } }; static void DetermineMaskUsage(nsIFrame* aFrame, bool aHandleOpacity,