Bug 1323912 - Part 5. Apply opacity in mask layer painting path.
MozReview-Commit-ID: HX2Tcum2smO
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -7346,21 +7346,19 @@ bool nsDisplayMask::ShouldPaintOnMaskLay
{
if (!aManager->IsCompositingCheap()) {
return false;
}
nsSVGUtils::MaskUsage maskUsage;
nsSVGUtils::DetermineMaskUsage(mFrame, mHandleOpacity, maskUsage);
- // XXX Bug 1323912. nsSVGIntegrationUtils::PaintMask can not handle opacity
- // correctly. Turn it off before bug fixed.
// XXX Temporary disable paint clip-path onto mask before figure out
// performance regression(bug 1325550).
- if (maskUsage.opacity != 1.0 || maskUsage.shouldApplyClipPath) {
+ if (maskUsage.shouldApplyClipPath) {
return false;
}
if (!nsSVGIntegrationUtils::IsMaskResourceReady(mFrame)) {
return false;
}
if (gfxPrefs::DrawMaskLayer()) {
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -720,32 +720,47 @@ nsSVGIntegrationUtils::IsMaskResourceRea
return false;
}
}
// Either all mask resources are ready, or no mask resource is needed.
return true;
}
+class AutoPopGroup
+{
+public:
+ AutoPopGroup() : mContext(nullptr) { }
+
+ ~AutoPopGroup() {
+ if (mContext) {
+ mContext->PopGroupAndBlend();
+ }
+ }
+
+ void SetContext(gfxContext* aContext) {
+ mContext = aContext;
+ }
+
+private:
+ gfxContext* mContext;
+};
+
DrawResult
nsSVGIntegrationUtils::PaintMask(const PaintFramesParams& aParams)
{
nsSVGUtils::MaskUsage maskUsage;
nsSVGUtils::DetermineMaskUsage(aParams.frame, aParams.handleOpacity,
maskUsage);
nsIFrame* frame = aParams.frame;
if (!ValidateSVGFrame(frame)) {
return DrawResult::SUCCESS;
}
- // XXX Bug 1323912.
- MOZ_ASSERT(maskUsage.opacity == 1.0,
- "nsSVGIntegrationUtils::PaintMask can not handle opacity now.");
-
gfxContext& ctx = aParams.ctx;
nsIFrame* firstFrame =
nsLayoutUtils::FirstContinuationOrIBSplitSibling(frame);
nsSVGEffects::EffectProperties effectProperties =
nsSVGEffects::GetEffectProperties(firstFrame);
DrawResult result = DrawResult::SUCCESS;
RefPtr<DrawTarget> maskTarget = ctx.GetDrawTarget();
@@ -757,16 +772,25 @@ nsSVGIntegrationUtils::PaintMask(const P
//
// Create one extra draw target for drawing positioned mask, so that we do
// not have to copy the content of maskTarget before painting
// clip-path into it.
maskTarget = maskTarget->CreateSimilarDrawTarget(maskTarget->GetSize(),
SurfaceFormat::A8);
}
+ nsTArray<nsSVGMaskFrame *> maskFrames = effectProperties.GetMaskFrames();
+ AutoPopGroup autoPop;
+ bool shouldPushOpacity = (maskUsage.opacity != 1.0) &&
+ (maskFrames.Length() != 1);
+ if (shouldPushOpacity) {
+ ctx.PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, maskUsage.opacity);
+ autoPop.SetContext(&ctx);
+ }
+
gfxContextMatrixAutoSaveRestore matSR;
nsPoint offsetToBoundingBox;
nsPoint offsetToUserSpace;
// Paint clip-path-basic-shape onto ctx
gfxContextAutoSaveRestore basicShapeSR;
if (maskUsage.shouldApplyBasicShape) {
matSR.SetContext(&ctx);
@@ -788,19 +812,18 @@ nsSVGIntegrationUtils::PaintMask(const P
// Paint mask onto ctx.
if (maskUsage.shouldGenerateMaskLayer) {
matSR.Restore();
matSR.SetContext(&ctx);
SetupContextMatrix(frame, aParams, offsetToBoundingBox,
offsetToUserSpace);
- nsTArray<nsSVGMaskFrame *> maskFrames = effectProperties.GetMaskFrames();
-
- result = PaintMaskSurface(aParams, maskTarget, 1.0,
+ result = PaintMaskSurface(aParams, maskTarget,
+ shouldPushOpacity ? 1.0 : maskUsage.opacity,
firstFrame->StyleContext(), maskFrames,
ctx.CurrentMatrix(), offsetToUserSpace);
if (result != DrawResult::SUCCESS) {
return result;
}
}
// Paint clip-path onto ctx.