diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index b213ac489afc..1a4ded46c680 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -6662,7 +6662,10 @@ nsDisplaySVGEffects::PaintAsLayer(nsDisplayListBuilder* aBuilder, borderArea, aBuilder, aManager, mOpacityItemCreated); - nsSVGIntegrationUtils::PaintFramesWithEffects(params); + image::DrawResult result = + nsSVGIntegrationUtils::PaintFramesWithEffects(params); + + nsDisplaySVGEffectsGeometry::UpdateDrawResult(this, result); } LayerState @@ -6802,6 +6805,11 @@ nsDisplaySVGEffects::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, // nothing in the filter input. aInvalidRegion->Or(bounds, geometry->mBounds); } + + if (aBuilder->ShouldSyncDecodeImages() && + geometry->ShouldInvalidateToSyncDecodeImages()) { + aInvalidRegion->Or(*aInvalidRegion, bounds); + } } #ifdef MOZ_DUMP_PAINTING diff --git a/layout/base/nsDisplayListInvalidation.cpp b/layout/base/nsDisplayListInvalidation.cpp index 32fc372befb4..253b914ccc10 100644 --- a/layout/base/nsDisplayListInvalidation.cpp +++ b/layout/base/nsDisplayListInvalidation.cpp @@ -108,6 +108,7 @@ nsDisplayBoxShadowOuterGeometry::nsDisplayBoxShadowOuterGeometry(nsDisplayItem* nsDisplaySVGEffectsGeometry::nsDisplaySVGEffectsGeometry(nsDisplaySVGEffects* aItem, nsDisplayListBuilder* aBuilder) : nsDisplayItemGeometry(aItem, aBuilder) + , nsImageGeometryMixin(aItem, aBuilder) , mBBox(aItem->BBoxInUserSpace()) , mUserSpaceOffset(aItem->UserSpaceOffset()) , mFrameOffsetToReferenceFrame(aItem->ToReferenceFrame()) diff --git a/layout/base/nsDisplayListInvalidation.h b/layout/base/nsDisplayListInvalidation.h index 59404ceba28a..bd2b8d9404e8 100644 --- a/layout/base/nsDisplayListInvalidation.h +++ b/layout/base/nsDisplayListInvalidation.h @@ -242,6 +242,7 @@ public: }; class nsDisplaySVGEffectsGeometry : public nsDisplayItemGeometry + , public nsImageGeometryMixin { public: nsDisplaySVGEffectsGeometry(nsDisplaySVGEffects* aItem, nsDisplayListBuilder* aBuilder); diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index 6003051e14fc..1e2ca33c2752 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -30,6 +30,7 @@ using namespace mozilla; using namespace mozilla::layers; using namespace mozilla::gfx; +using namespace mozilla::image; // ---------------------------------------------------------------------- @@ -474,7 +475,7 @@ ComputeMaskGeometry(const nsSVGIntegrationUtils::PaintFramesParams& aParams, : IntRect(); } -static void +static DrawResult GenerateMaskSurface(const nsSVGIntegrationUtils::PaintFramesParams& aParams, float aOpacity, nsStyleContext* aSC, const nsTArray& aMaskFrames, @@ -497,14 +498,14 @@ GenerateMaskSurface(const nsSVGIntegrationUtils::PaintFramesParams& aParams, cssPxToDevPxMatrix, aOpacity, &aOutMaskTransform, svgReset->mMask.mLayers[0].mMaskMode); - return; + return DrawResult::SUCCESS; } IntRect maskSurfaceRect = ComputeMaskGeometry(aParams, svgReset, aOffsetToUserSpace, aMaskFrames); if (maskSurfaceRect.IsEmpty()) { - return; + return DrawResult::SUCCESS; } // Mask composition result on CoreGraphic::A8 surface is not correct @@ -518,7 +519,7 @@ GenerateMaskSurface(const nsSVGIntegrationUtils::PaintFramesParams& aParams, : ctx.GetDrawTarget()->CreateSimilarDrawTarget(maskSurfaceRect.Size(), SurfaceFormat::A8); if (!maskDT || !maskDT->IsValid()) { - return; + return DrawResult::TEMPORARY_ERROR; } RefPtr maskContext = gfxContext::CreateOrNull(maskDT); @@ -575,21 +576,25 @@ GenerateMaskSurface(const nsSVGIntegrationUtils::PaintFramesParams& aParams, nsCSSRendering::PAINTBG_MASK_IMAGE, i, compositionOp); - // FIXME We should use the return value, see bug 1258510. - Unused << nsCSSRendering::PaintBackgroundWithSC(params, aSC, - *aParams.frame->StyleBorder()); + DrawResult result = + nsCSSRendering::PaintBackgroundWithSC(params, aSC, + *aParams.frame->StyleBorder()); + if (result != DrawResult::SUCCESS) { + return result; + } } } aOutMaskTransform = ToMatrix(maskSurfaceMatrix); if (!aOutMaskTransform.Invert()) { - return; + return DrawResult::SUCCESS; } aOutMaskSurface = maskDT->Snapshot(); + return DrawResult::SUCCESS; } -void +DrawResult nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams) { #ifdef DEBUG @@ -619,16 +624,16 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams) nsISVGChildFrame *svgChildFrame = do_QueryFrame(frame); if (!svgChildFrame || !frame->GetContent()->IsSVGElement()) { NS_ASSERTION(false, "why?"); - return; + return DrawResult::BAD_ARGS; } if (!static_cast(content)->HasValidDimensions()) { - return; // The SVG spec says not to draw _anything_ + return DrawResult::SUCCESS; // The SVG spec says not to draw _anything_ } } float opacity = frame->StyleEffects()->mOpacity; if (opacity == 0.0f) { - return; + return DrawResult::SUCCESS; } if (opacity != 1.0f && (nsSVGUtils::CanOptimizeOpacity(frame) || @@ -709,6 +714,7 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams) IntPoint targetOffset; bool complexEffects = false; + DrawResult result = DrawResult::SUCCESS; /* 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) @@ -724,17 +730,17 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams) *drawTarget)); Matrix maskTransform; RefPtr maskSurface; - if (shouldGenerateMaskLayer) { - GenerateMaskSurface(aParams, opacity, firstFrame->StyleContext(), - maskFrames, offsetToUserSpace, - maskTransform, maskSurface); + result = GenerateMaskSurface(aParams, opacity, + firstFrame->StyleContext(), + maskFrames, offsetToUserSpace, + maskTransform, maskSurface); } if (shouldGenerateMaskLayer && !maskSurface) { // Entire surface is clipped out. context.Restore(); - return; + return result; } if (frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) { @@ -753,7 +759,7 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams) RefPtr targetDT = context.GetDrawTarget()->CreateSimilarDrawTarget(drawRect.Size(), SurfaceFormat::B8G8R8A8); if (!targetDT || !targetDT->IsValid()) { context.Restore(); - return; + return result; } target = gfxContext::CreateOrNull(targetDT); MOZ_ASSERT(target); // already checked the draw target above @@ -815,7 +821,7 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams) /* No more effects, we're done. */ if (!complexEffects) { - return; + return result; } if (opacity != 1.0f || shouldGenerateMaskLayer || @@ -835,6 +841,7 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams) } context.Restore(); + return result; } gfxMatrix diff --git a/layout/svg/nsSVGIntegrationUtils.h b/layout/svg/nsSVGIntegrationUtils.h index 3b5c957b7cdb..8454ae0dbc5c 100644 --- a/layout/svg/nsSVGIntegrationUtils.h +++ b/layout/svg/nsSVGIntegrationUtils.h @@ -37,6 +37,7 @@ struct nsSize; class nsSVGIntegrationUtils final { typedef mozilla::gfx::DrawTarget DrawTarget; + typedef mozilla::image::DrawResult DrawResult; public: /** @@ -145,7 +146,7 @@ public: /** * Paint non-SVG frame with SVG effects. */ - static void + static DrawResult PaintFramesWithEffects(const PaintFramesParams& aParams); /**