diff --git a/gfx/2d/DrawTargetD2D1.cpp b/gfx/2d/DrawTargetD2D1.cpp index 3467ff8f364a..eb1c22170b62 100644 --- a/gfx/2d/DrawTargetD2D1.cpp +++ b/gfx/2d/DrawTargetD2D1.cpp @@ -255,7 +255,24 @@ DrawTargetD2D1::DrawFilter(FilterNode *aNode, FilterNodeD2D1* node = static_cast(aNode); node->WillDraw(this); - mDC->DrawImage(node->OutputEffect(), D2DPoint(aDestPoint), D2DRect(aSourceRect)); + if (aOptions.mAlpha == 1.0f) { + mDC->DrawImage(node->OutputEffect(), D2DPoint(aDestPoint), D2DRect(aSourceRect)); + } else { + RefPtr image; + node->OutputEffect()->GetOutput(getter_AddRefs(image)); + + Matrix mat = Matrix::Translation(aDestPoint); + + RefPtr imageBrush; + mDC->CreateImageBrush(image, + D2D1::ImageBrushProperties(D2DRect(aSourceRect)), + D2D1::BrushProperties(aOptions.mAlpha, D2DMatrix(mat)), + getter_AddRefs(imageBrush)); + mDC->FillRectangle(D2D1::RectF(aDestPoint.x, aDestPoint.y, + aDestPoint.x + aSourceRect.width, + aDestPoint.y + aSourceRect.height), + imageBrush); + } FinalizeDrawing(aOptions.mCompositionOp, ColorPattern(Color())); } diff --git a/layout/svg/nsFilterInstance.cpp b/layout/svg/nsFilterInstance.cpp index 51202c689be4..daf816e929bf 100644 --- a/layout/svg/nsFilterInstance.cpp +++ b/layout/svg/nsFilterInstance.cpp @@ -65,7 +65,8 @@ nsFilterInstance::PaintFilteredFrame(nsIFrame *aFilteredFrame, gfxContext* aCtx, nsSVGFilterPaintCallback *aPaintCallback, const nsRegion *aDirtyArea, - imgDrawingParams& aImgParams) + imgDrawingParams& aImgParams, + float aOpacity) { auto& filterChain = aFilteredFrame->StyleEffects()->mFilters; UniquePtr metrics = UserSpaceMetricsForFrame(aFilteredFrame); @@ -97,7 +98,7 @@ nsFilterInstance::PaintFilteredFrame(nsIFrame *aFilteredFrame, aPaintCallback, scaleMatrixInDevUnits, aDirtyArea, nullptr, nullptr, nullptr); if (instance.IsInitialized()) { - instance.Render(aCtx, aImgParams); + instance.Render(aCtx, aImgParams, aOpacity); } } @@ -493,7 +494,7 @@ nsFilterInstance::BuildSourceImage(DrawTarget *aDest, imgDrawingParams& aImgPara } void -nsFilterInstance::Render(gfxContext* aCtx, imgDrawingParams& aImgParams) +nsFilterInstance::Render(gfxContext* aCtx, imgDrawingParams& aImgParams, float aOpacity) { MOZ_ASSERT(mTargetFrame, "Need a frame for rendering"); @@ -521,7 +522,7 @@ nsFilterInstance::Render(gfxContext* aCtx, imgDrawingParams& aImgParams) mSourceGraphic.mSourceSurface, mSourceGraphic.mSurfaceRect, mFillPaint.mSourceSurface, mFillPaint.mSurfaceRect, mStrokePaint.mSourceSurface, mStrokePaint.mSurfaceRect, - mInputImages, Point(0, 0)); + mInputImages, Point(0, 0), DrawOptions(aOpacity)); } nsRegion diff --git a/layout/svg/nsFilterInstance.h b/layout/svg/nsFilterInstance.h index b38e7a334e12..3a26dd7988e0 100644 --- a/layout/svg/nsFilterInstance.h +++ b/layout/svg/nsFilterInstance.h @@ -88,7 +88,8 @@ public: gfxContext* aCtx, nsSVGFilterPaintCallback *aPaintCallback, const nsRegion* aDirtyArea, - imgDrawingParams& aImgParams); + imgDrawingParams& aImgParams, + float aOpacity = 1.0f); /** * Returns the post-filter area that could be dirtied when the given @@ -168,7 +169,7 @@ private: * by passing it as the aPostFilterDirtyRegion argument to the * nsFilterInstance constructor. */ - void Render(gfxContext* aCtx, imgDrawingParams& aImgParams); + void Render(gfxContext* aCtx, imgDrawingParams& aImgParams, float aOpacity = 1.0f); const FilterDescription& ExtractDescriptionAndAdditionalImages(nsTArray>& aOutAdditionalImages) { diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index 6b7bdbac6a7a..b225d7dc0797 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -1089,22 +1089,13 @@ nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams) gfxContextAutoSaveRestore autoSR(&context); EffectOffsets offsets = MoveContextOriginToUserSpace(firstFrame, aParams); - if (opacity != 1.0f) { - context.PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity, - nullptr, Matrix()); - } - /* Paint the child and apply filters */ RegularFramePaintCallback callback(aParams.builder, aParams.layerManager, offsets.offsetToUserSpaceInDevPx); nsRegion dirtyRegion = aParams.dirtyRect - offsets.offsetToBoundingBox; nsFilterInstance::PaintFilteredFrame(frame, &context, &callback, - &dirtyRegion, aParams.imgParams); - - if (opacity != 1.0f) { - context.PopGroupAndBlend(); - } + &dirtyRegion, aParams.imgParams, opacity); } class PaintFrameCallback : public gfxDrawingCallback {