Bug 1245499 - Composite mask only if has drawable mask source.
MozReview-Commit-ID: P0QMPHgwI0
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -510,46 +510,56 @@ nsSVGIntegrationUtils::PaintFramesWithEf
gfxMatrix cssPxToDevPxMatrix = GetCSSPxToDevPxMatrix(aFrame);
const nsStyleSVGReset *svgReset = firstFrame->StyleSVGReset();
// Keep moving forward even if svgMaskFrame is nullptr or isOK is false.
// This source is not a svg mask, but it still can be a correct mask image.
nsSVGMaskFrame *svgMaskFrame = effectProperties.GetMaskFrame(&isOK);
- bool complexEffects = false;
- bool hasValidLayers = svgReset->mMask.HasLayerWithImage();
// These are used if we require a temporary surface for a custom blend mode.
RefPtr<gfxContext> target = &aContext;
IntPoint targetOffset;
+ bool hasMaskToDraw = svgMaskFrame ? true : false;
+ if (!hasMaskToDraw) {
+ NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, svgReset->mMask) {
+ if (!svgReset->mMask.mLayers[i].mImage.IsEmpty()) {
+ hasMaskToDraw = true;
+ break;
+ }
+ }
+ }
+
+ bool complexEffects = false;
/* Check if we need to do additional operations on this child's
* rendering, which necessitates rendering into another surface. */
if (opacity != 1.0f || (clipPathFrame && !isTrivialClip)
|| aFrame->StyleDisplay()->mMixBlendMode != NS_STYLE_BLEND_NORMAL
- || svgMaskFrame || hasValidLayers) {
+ || hasMaskToDraw) {
complexEffects = true;
aContext.Save();
nsRect clipRect =
aFrame->GetVisualOverflowRectRelativeToSelf() + toUserSpace;
aContext.Clip(NSRectToSnappedRect(clipRect,
aFrame->PresContext()->AppUnitsPerDevPixel(),
*drawTarget));
Matrix maskTransform;
RefPtr<SourceSurface> maskSurface;
+
if (svgMaskFrame) {
maskSurface = svgMaskFrame->GetMaskForMaskedFrame(&aContext,
- aFrame,
- cssPxToDevPxMatrix,
- opacity,
- &maskTransform);
- } else if (hasValidLayers) {
+ aFrame,
+ cssPxToDevPxMatrix,
+ opacity,
+ &maskTransform);
+ } else if (hasMaskToDraw) {
gfxRect clipRect = aContext.GetClipExtents();
{
gfxContextMatrixAutoSaveRestore matRestore(&aContext);
aContext.SetMatrix(gfxMatrix());
clipRect = aContext.GetClipExtents();
}
IntRect drawRect = RoundedOut(ToRect(clipRect));
@@ -579,17 +589,17 @@ nsSVGIntegrationUtils::PaintFramesWithEf
maskSurface = targetDT->Snapshot();
// Compute mask transform.
Matrix mat = ToMatrix(aContext.CurrentMatrix());
mat.Invert();
maskTransform = Matrix::Translation(drawRect.x, drawRect.y) * mat;
}
- if ((svgMaskFrame || hasValidLayers) && !maskSurface) {
+ if (hasMaskToDraw && !maskSurface) {
// Entire surface is clipped out.
aContext.Restore();
return;
}
if (aFrame->StyleDisplay()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
// Create a temporary context to draw to so we can blend it back with
// another operator.
@@ -619,18 +629,17 @@ nsSVGIntegrationUtils::PaintFramesWithEf
&clippedMaskTransform, maskSurface, maskTransform);
if (clipMaskSurface) {
maskSurface = clipMaskSurface;
maskTransform = clippedMaskTransform;
}
}
- if (opacity != 1.0f || svgMaskFrame || hasValidLayers ||
- (clipPathFrame && !isTrivialClip)) {
+ if (opacity != 1.0f || hasMaskToDraw || (clipPathFrame && !isTrivialClip)) {
target->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity, maskSurface, maskTransform);
}
}
/* If this frame has only a trivial clipPath, set up cairo's clipping now so
* we can just do normal painting and get it clipped appropriately.
*/
if (clipPathFrame && isTrivialClip) {
@@ -664,18 +673,17 @@ nsSVGIntegrationUtils::PaintFramesWithEf
aContext.Restore();
}
/* No more effects, we're done. */
if (!complexEffects) {
return;
}
- if (opacity != 1.0f || svgMaskFrame || hasValidLayers ||
- (clipPathFrame && !isTrivialClip)) {
+ if (opacity != 1.0f || hasMaskToDraw || (clipPathFrame && !isTrivialClip)) {
target->PopGroupAndBlend();
}
if (aFrame->StyleDisplay()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
RefPtr<DrawTarget> targetDT = target->GetDrawTarget();
target = nullptr;
RefPtr<SourceSurface> targetSurf = targetDT->Snapshot();