Bug 1756220 - Always paint the the extra mask with an identity transform. r=gfx-reviewers,nical,bradwerth

Previously, we mostly went to the effort of setting the extra tranform to the
inverse of the context transform except for a case in PaintMask which really
didn't make any sense.

Differential Revision: https://phabricator.services.mozilla.com/D139148
This commit is contained in:
Jeff Muizelaar 2022-02-22 21:16:29 +00:00
parent 5f8b07ff0f
commit 66243c7954
4 changed files with 21 additions and 41 deletions

View File

@ -85,12 +85,11 @@ void SVGClipPathFrame::ApplyClipPath(gfxContext& aContext,
}
}
static void ComposeExtraMask(DrawTarget* aTarget, SourceSurface* aExtraMask,
const Matrix& aExtraMasksTransform) {
static void ComposeExtraMask(DrawTarget* aTarget, SourceSurface* aExtraMask) {
MOZ_ASSERT(aExtraMask);
Matrix origin = aTarget->GetTransform();
aTarget->SetTransform(aExtraMasksTransform * aTarget->GetTransform());
aTarget->SetTransform(Matrix());
aTarget->MaskSurface(ColorPattern(DeviceColor(0.0, 0.0, 0.0, 1.0)),
aExtraMask, Point(0, 0),
DrawOptions(1.0, CompositionOp::OP_IN));
@ -100,8 +99,7 @@ static void ComposeExtraMask(DrawTarget* aTarget, SourceSurface* aExtraMask,
void SVGClipPathFrame::PaintClipMask(gfxContext& aMaskContext,
nsIFrame* aClippedFrame,
const gfxMatrix& aMatrix,
SourceSurface* aExtraMask,
const Matrix& aExtraMasksTransform) {
SourceSurface* aExtraMask) {
static int16_t sRefChainLengthCounter = AutoReferenceChainGuard::noChain;
// A clipPath can reference another clipPath, creating a chain of clipPaths
@ -157,7 +155,7 @@ void SVGClipPathFrame::PaintClipMask(gfxContext& aMaskContext,
}
if (aExtraMask) {
ComposeExtraMask(maskDT, aExtraMask, aExtraMasksTransform);
ComposeExtraMask(maskDT, aExtraMask);
}
}
@ -226,8 +224,7 @@ void SVGClipPathFrame::PaintFrameIntoMask(nsIFrame* aFrame,
already_AddRefed<SourceSurface> SVGClipPathFrame::GetClipMask(
gfxContext& aReferenceContext, nsIFrame* aClippedFrame,
const gfxMatrix& aMatrix, SourceSurface* aExtraMask,
const Matrix& aExtraMasksTransform) {
const gfxMatrix& aMatrix, SourceSurface* aExtraMask) {
RefPtr<DrawTarget> maskDT =
aReferenceContext.GetDrawTarget()->CreateClippedDrawTarget(
Rect(), SurfaceFormat::A8);
@ -242,8 +239,7 @@ already_AddRefed<SourceSurface> SVGClipPathFrame::GetClipMask(
return nullptr;
}
PaintClipMask(*maskContext, aClippedFrame, aMatrix, aExtraMask,
aExtraMasksTransform);
PaintClipMask(*maskContext, aClippedFrame, aMatrix, aExtraMask);
RefPtr<SourceSurface> surface = maskDT->Snapshot();
return surface.forget();

View File

@ -80,13 +80,10 @@ class SVGClipPathFrame final : public SVGContainerFrame {
* current transform.
* @param [in, optional] aExtraMask An extra surface that the returned
* surface should be masked with.
* @param [in, optional] aExtraMasksTransform The transform to use with
* aExtraMask. Should be passed when aExtraMask is passed.
*/
already_AddRefed<SourceSurface> GetClipMask(
gfxContext& aReferenceContext, nsIFrame* aClippedFrame,
const gfxMatrix& aMatrix, SourceSurface* aExtraMask = nullptr,
const Matrix& aExtraMasksTransform = Matrix());
const gfxMatrix& aMatrix, SourceSurface* aExtraMask = nullptr);
/**
* Paint mask directly onto a given context(aMaskContext).
@ -98,12 +95,9 @@ class SVGClipPathFrame final : public SVGContainerFrame {
* current transform.
* @param [in, optional] aExtraMask An extra surface that the returned
* surface should be masked with.
* @param [in, optional] aExtraMasksTransform The transform to use with
* aExtraMask. Should be passed when aExtraMask is passed.
*/
void PaintClipMask(gfxContext& aMaskContext, nsIFrame* aClippedFrame,
const gfxMatrix& aMatrix, SourceSurface* aExtraMask,
const Matrix& aExtraMasksTransform);
const gfxMatrix& aMatrix, SourceSurface* aExtraMask);
/**
* aPoint is expected to be in aClippedFrame's SVG user space.

View File

@ -795,8 +795,7 @@ bool SVGIntegrationUtils::PaintMask(const PaintFramesParams& aParams,
SVGObserverUtils::GetAndObserveClipPath(firstFrame, &clipPathFrame);
RefPtr<SourceSurface> maskSurface =
maskUsage.shouldGenerateMaskLayer ? maskTarget->Snapshot() : nullptr;
clipPathFrame->PaintClipMask(ctx, frame, cssPxToDevPxMatrix, maskSurface,
ctx.CurrentMatrix());
clipPathFrame->PaintClipMask(ctx, frame, cssPxToDevPxMatrix, maskSurface);
}
return true;
@ -860,7 +859,6 @@ void PaintMaskAndClipPathInternal(const PaintFramesParams& aParams,
if (shouldGenerateMask) {
gfxContextMatrixAutoSaveRestore matSR;
Matrix maskTransform;
RefPtr<SourceSurface> maskSurface;
bool opacityApplied = false;
@ -882,10 +880,6 @@ void PaintMaskAndClipPathInternal(const PaintFramesParams& aParams,
maskSurface = paintResult.maskSurface;
if (maskSurface) {
shouldPushMask = true;
// We want the mask to be untransformed so use the inverse of the
// current transform as the maskTransform to compensate.
maskTransform = context.CurrentMatrix();
maskTransform.Invert();
opacityApplied = paintResult.opacityApplied;
}
@ -897,14 +891,10 @@ void PaintMaskAndClipPathInternal(const PaintFramesParams& aParams,
MoveContextOriginToUserSpace(firstFrame, aParams);
RefPtr<SourceSurface> clipMaskSurface = clipPathFrame->GetClipMask(
context, frame, cssPxToDevPxMatrix, maskSurface, maskTransform);
context, frame, cssPxToDevPxMatrix, maskSurface);
if (clipMaskSurface) {
maskSurface = clipMaskSurface;
// We want the mask to be untransformed so use the inverse of the
// current transform as the maskTransform to compensate.
maskTransform = context.CurrentMatrix();
maskTransform.Invert();
} else {
// Either entire surface is clipped out, or gfx buffer allocation
// failure in SVGClipPathFrame::GetClipMask.
@ -925,6 +915,11 @@ void PaintMaskAndClipPathInternal(const PaintFramesParams& aParams,
}
if (shouldPushMask) {
// We want the mask to be untransformed so use the inverse of the
// current transform as the maskTransform to compensate.
Matrix maskTransform = context.CurrentMatrix();
maskTransform.Invert();
context.PushGroupForBlendBack(gfxContentType::COLOR_ALPHA,
opacityApplied ? 1.0 : maskUsage.opacity,
maskSurface, maskTransform);

View File

@ -650,7 +650,6 @@ void SVGUtils::PaintFrameWithEffects(nsIFrame* aFrame, gfxContext& aContext,
bool shouldPushMask = false;
if (shouldGenerateMask) {
Matrix maskTransform;
RefPtr<SourceSurface> maskSurface;
// maskFrame can be nullptr even if maskUsage.shouldGenerateMaskLayer is
@ -665,10 +664,6 @@ void SVGUtils::PaintFrameWithEffects(nsIFrame* aFrame, gfxContext& aContext,
SVGMaskFrame::MaskParams params(aContext.GetDrawTarget(), aFrame,
aTransform, maskUsage.opacity, maskMode,
aImgParams);
// We want the mask to be untransformed so use the inverse of the current
// transform as the maskTransform to compensate.
maskTransform = aContext.CurrentMatrix();
maskTransform.Invert();
maskSurface = maskFrame->GetMaskForMaskedFrame(params);
@ -681,13 +676,9 @@ void SVGUtils::PaintFrameWithEffects(nsIFrame* aFrame, gfxContext& aContext,
}
if (maskUsage.shouldGenerateClipMaskLayer) {
RefPtr<SourceSurface> clipMaskSurface = clipPathFrame->GetClipMask(
aContext, aFrame, aTransform, maskSurface, maskTransform);
RefPtr<SourceSurface> clipMaskSurface =
clipPathFrame->GetClipMask(aContext, aFrame, aTransform, maskSurface);
if (clipMaskSurface) {
// We want the mask to be untransformed so use the inverse of the
// current transform as the maskTransform to compensate.
maskTransform = aContext.CurrentMatrix();
maskTransform.Invert();
maskSurface = clipMaskSurface;
} else {
// Either entire surface is clipped out, or gfx buffer allocation
@ -705,6 +696,10 @@ void SVGUtils::PaintFrameWithEffects(nsIFrame* aFrame, gfxContext& aContext,
// SVG mask multiply opacity into maskSurface already, so we do not bother
// to apply opacity again.
if (shouldPushMask) {
// We want the mask to be untransformed so use the inverse of the
// current transform as the maskTransform to compensate.
Matrix maskTransform = aContext.CurrentMatrix();
maskTransform.Invert();
target->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA,
maskFrame ? 1.0 : maskUsage.opacity,
maskSurface, maskTransform);