--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -715,58 +715,16 @@ SetupContextMatrix(nsIFrame* aFrame, con
nsRect clipRect =
aParams.frame->GetVisualOverflowRectRelativeToSelf() + toUserSpace;
context.Clip(NSRectToSnappedRect(clipRect,
aFrame->PresContext()->AppUnitsPerDevPixel(),
*context.GetDrawTarget()));
}
}
-static already_AddRefed<gfxContext>
-CreateBlendTarget(const PaintFramesParams& aParams, IntPoint& aTargetOffset)
-{
- MOZ_ASSERT(aParams.frame->StyleEffects()->mMixBlendMode !=
- NS_STYLE_BLEND_NORMAL);
-
- // Create a temporary context to draw to so we can blend it back with
- // another operator.
- IntRect drawRect = ComputeClipExtsInDeviceSpace(aParams.ctx);
-
- RefPtr<DrawTarget> targetDT = aParams.ctx.GetDrawTarget()->CreateSimilarDrawTarget(drawRect.Size(), SurfaceFormat::B8G8R8A8);
- if (!targetDT || !targetDT->IsValid()) {
- return nullptr;
- }
-
- RefPtr<gfxContext> target = gfxContext::CreateOrNull(targetDT);
- MOZ_ASSERT(target); // already checked the draw target above
- target->SetMatrix(aParams.ctx.CurrentMatrix() *
- gfxMatrix::Translation(-drawRect.TopLeft()));
- aTargetOffset = drawRect.TopLeft();
-
- return target.forget();
-}
-
-static void
-BlendToTarget(const PaintFramesParams& aParams, gfxContext* aTarget,
- const IntPoint& aTargetOffset)
-{
- MOZ_ASSERT(aParams.frame->StyleEffects()->mMixBlendMode !=
- NS_STYLE_BLEND_NORMAL);
-
- RefPtr<DrawTarget> targetDT = aTarget->GetDrawTarget();
- RefPtr<SourceSurface> targetSurf = targetDT->Snapshot();
-
- gfxContext& context = aParams.ctx;
- gfxContextAutoSaveRestore save(&context);
- context.SetMatrix(gfxMatrix()); // This will be restored right after.
- RefPtr<gfxPattern> pattern = new gfxPattern(targetSurf, Matrix::Translation(aTargetOffset.x, aTargetOffset.y));
- context.SetPattern(pattern);
- context.Paint();
-}
-
DrawResult
nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
{
MOZ_ASSERT(UsingMaskOrClipPathForFrame(aParams.frame),
"Should not use this method when no mask or clipPath effect"
"on this frame");
/* SVG defines the following rendering model:
@@ -837,34 +795,16 @@ nsSVGIntegrationUtils::PaintMaskAndClipP
bool shouldApplyClipPath = clipPathFrame && isTrivialClip;
bool shouldApplyBasicShape = !clipPathFrame && svgReset->HasClipPath();
MOZ_ASSERT_IF(shouldGenerateClipMaskLayer,
!shouldApplyClipPath && !shouldApplyBasicShape);
nsPoint offsetToBoundingBox;
nsPoint offsetToUserSpace;
- // These are used if we require a temporary surface for a custom blend mode.
- // Clip the source context first, so that we can generate a smaller temporary
- // surface. (Since we will clip this context in SetupContextMatrix, a pair
- // of save/restore is needed.)
- context.Save();
- SetupContextMatrix(firstFrame, aParams, offsetToBoundingBox,
- offsetToUserSpace, true);
- IntPoint targetOffset;
- RefPtr<gfxContext> target =
- (aParams.frame->StyleEffects()->mMixBlendMode == NS_STYLE_BLEND_NORMAL)
- ? RefPtr<gfxContext>(&aParams.ctx).forget()
- : CreateBlendTarget(aParams, targetOffset);
- context.Restore();
-
- if (!target) {
- return DrawResult::TEMPORARY_ERROR;
- }
-
bool shouldGenerateMask = (opacity != 1.0f || shouldGenerateClipMaskLayer ||
shouldGenerateMaskLayer);
/* Check if we need to do additional operations on this child's
* rendering, which necessitates rendering into another surface. */
if (shouldGenerateMask) {
gfxContextMatrixAutoSaveRestore matSR;
@@ -917,17 +857,17 @@ nsSVGIntegrationUtils::PaintMaskAndClipP
if (!shouldGenerateClipMaskLayer && !shouldGenerateMaskLayer) {
MOZ_ASSERT(opacity != 1.0f);
matSR.SetContext(&context);
SetupContextMatrix(firstFrame, aParams, offsetToBoundingBox,
offsetToUserSpace, true);
}
- target->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity, maskSurface, maskTransform);
+ context.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 (shouldApplyClipPath || shouldApplyBasicShape) {
context.Save();
SetupContextMatrix(firstFrame, aParams, offsetToBoundingBox,
@@ -937,43 +877,38 @@ nsSVGIntegrationUtils::PaintMaskAndClipP
if (shouldApplyClipPath) {
clipPathFrame->ApplyClipPath(context, frame, cssPxToDevPxMatrix);
} else {
nsCSSClipPathInstance::ApplyBasicShapeClip(context, frame);
}
}
/* Paint the child */
- target->SetMatrix(matrixAutoSaveRestore.Matrix());
+ context.SetMatrix(matrixAutoSaveRestore.Matrix());
BasicLayerManager* basic = static_cast<BasicLayerManager*>(aParams.layerManager);
RefPtr<gfxContext> oldCtx = basic->GetTarget();
- basic->SetTarget(target);
+ basic->SetTarget(&context);
aParams.layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer,
aParams.builder);
basic->SetTarget(oldCtx);
if (shouldApplyClipPath || shouldApplyBasicShape) {
context.Restore();
}
if (shouldGenerateMask) {
- target->PopGroupAndBlend();
+ context.PopGroupAndBlend();
if (!shouldGenerateClipMaskLayer && !shouldGenerateMaskLayer) {
MOZ_ASSERT(opacity != 1.0f);
// Pop the clip push by SetupContextMatrix
context.PopClip();
}
}
- if (aParams.frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
- MOZ_ASSERT(target != &aParams.ctx);
- BlendToTarget(aParams, target, targetOffset);
- }
-
return result;
}
DrawResult
nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams)
{
MOZ_ASSERT(!aParams.builder->IsForGenerateGlyphMask(),
"Filter effect is discarded while generating glyph mask.");
@@ -1002,53 +937,35 @@ nsSVGIntegrationUtils::PaintFilter(const
if (!effectProperties.HasValidFilter()) {
return DrawResult::NOT_READY;
}
gfxContext& context = aParams.ctx;
nsPoint offsetToBoundingBox;
nsPoint offsetToUserSpace;
- // These are used if we require a temporary surface for a custom blend mode.
- // Clip the source context first, so that we can generate a smaller temporary
- // surface. (Since we will clip this context in SetupContextMatrix, a pair
- // of save/restore is needed.)
gfxContextAutoSaveRestore autoSR(&context);
SetupContextMatrix(firstFrame, aParams, offsetToBoundingBox,
offsetToUserSpace, true);
- IntPoint targetOffset;
- RefPtr<gfxContext> target =
- (aParams.frame->StyleEffects()->mMixBlendMode == NS_STYLE_BLEND_NORMAL)
- ? RefPtr<gfxContext>(&aParams.ctx).forget()
- : CreateBlendTarget(aParams, targetOffset);
- if (!target) {
- context.Restore();
- return DrawResult::TEMPORARY_ERROR;
- }
if (opacity != 1.0f) {
- target->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity,
+ context.PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity,
nullptr, Matrix());
}
/* Paint the child and apply filters */
RegularFramePaintCallback callback(aParams.builder, aParams.layerManager,
offsetToUserSpace);
nsRegion dirtyRegion = aParams.dirtyRect - offsetToBoundingBox;
gfxMatrix tm = nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(frame);
- nsFilterInstance::PaintFilteredFrame(frame, target->GetDrawTarget(),
+ nsFilterInstance::PaintFilteredFrame(frame, context.GetDrawTarget(),
tm, &callback, &dirtyRegion);
if (opacity != 1.0f) {
- target->PopGroupAndBlend();
- }
-
- if (aParams.frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
- MOZ_ASSERT(target != &aParams.ctx);
- BlendToTarget(aParams, target, targetOffset);
+ context.PopGroupAndBlend();
}
return result;
}
gfxMatrix
nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(nsIFrame* aNonSVGFrame)
{