Bug 1336480 - Part 1. Apply suface limitation in nsFilterInstance::ComputeNeededBoxes.
There is no need to limit output space bounds in
nsFilterInstance::OutputFilterSpaceBounds(), it's just far too early.
MozReview-Commit-ID: 9i9huKDGxq6
--- a/layout/svg/nsFilterInstance.cpp
+++ b/layout/svg/nsFilterInstance.cpp
@@ -354,42 +354,58 @@ nsFilterInstance::BuildPrimitivesForFilt
mTargetFrame ? mTargetFrame->StyleColor()->mColor : NS_RGB(0,0,0);
nsCSSFilterInstance cssFilterInstance(aFilter, shadowFallbackColor,
mTargetBounds,
mFrameSpaceInCSSPxToFilterSpaceTransform);
return cssFilterInstance.BuildPrimitives(mPrimitiveDescriptions, aInputIsTainted);
}
+static void
+UpdateNeededBounds(const nsIntRegion& aRegion, nsIntRect& aBounds)
+{
+ aBounds = aRegion.GetBounds();
+
+ bool overflow;
+ IntSize surfaceSize =
+ nsSVGUtils::ConvertToSurfaceSize(aBounds.Size(), &overflow);
+ if (overflow) {
+ aBounds.SizeTo(surfaceSize);
+ }
+}
+
void
nsFilterInstance::ComputeNeededBoxes()
{
if (mPrimitiveDescriptions.IsEmpty())
return;
nsIntRegion sourceGraphicNeededRegion;
nsIntRegion fillPaintNeededRegion;
nsIntRegion strokePaintNeededRegion;
FilterSupport::ComputeSourceNeededRegions(
mFilterDescription, mPostFilterDirtyRegion,
sourceGraphicNeededRegion, fillPaintNeededRegion, strokePaintNeededRegion);
sourceGraphicNeededRegion.And(sourceGraphicNeededRegion, mTargetBounds);
- mSourceGraphic.mNeededBounds = sourceGraphicNeededRegion.GetBounds();
- mFillPaint.mNeededBounds = fillPaintNeededRegion.GetBounds();
- mStrokePaint.mNeededBounds = strokePaintNeededRegion.GetBounds();
+ UpdateNeededBounds(sourceGraphicNeededRegion, mSourceGraphic.mNeededBounds);
+ UpdateNeededBounds(fillPaintNeededRegion, mFillPaint.mNeededBounds);
+ UpdateNeededBounds(strokePaintNeededRegion, mStrokePaint.mNeededBounds);
}
DrawResult
nsFilterInstance::BuildSourcePaint(SourceInfo *aSource)
{
MOZ_ASSERT(mTargetFrame);
nsIntRect neededRect = aSource->mNeededBounds;
+ if (neededRect.IsEmpty()) {
+ return DrawResult::SUCCESS;
+ }
RefPtr<DrawTarget> offscreenDT =
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
neededRect.Size(), SurfaceFormat::B8G8R8A8);
if (!offscreenDT || !offscreenDT->IsValid()) {
return DrawResult::TEMPORARY_ERROR;
}
@@ -570,23 +586,17 @@ nsFilterInstance::ComputeSourceNeededRec
nsIntRect
nsFilterInstance::OutputFilterSpaceBounds() const
{
uint32_t numPrimitives = mPrimitiveDescriptions.Length();
if (numPrimitives <= 0)
return nsIntRect();
- nsIntRect bounds =
- mPrimitiveDescriptions[numPrimitives - 1].PrimitiveSubregion();
- bool overflow;
- IntSize surfaceSize =
- nsSVGUtils::ConvertToSurfaceSize(bounds.Size(), &overflow);
- bounds.SizeTo(surfaceSize);
- return bounds;
+ return mPrimitiveDescriptions[numPrimitives - 1].PrimitiveSubregion();
}
nsIntRect
nsFilterInstance::FrameSpaceToFilterSpace(const nsRect* aRect) const
{
nsIntRect rect = OutputFilterSpaceBounds();
if (aRect) {
if (aRect->IsEmpty()) {
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1002,17 +1002,17 @@ IntSize
nsSVGUtils::ConvertToSurfaceSize(const gfxSize& aSize,
bool *aResultOverflows)
{
IntSize surfaceSize(ClampToInt(ceil(aSize.width)), ClampToInt(ceil(aSize.height)));
*aResultOverflows = surfaceSize.width != ceil(aSize.width) ||
surfaceSize.height != ceil(aSize.height);
- if (!Factory::CheckSurfaceSize(surfaceSize)) {
+ if (!Factory::AllowedSurfaceSize(surfaceSize)) {
surfaceSize.width = std::min(NS_SVG_OFFSCREEN_MAX_DIMENSION,
surfaceSize.width);
surfaceSize.height = std::min(NS_SVG_OFFSCREEN_MAX_DIMENSION,
surfaceSize.height);
*aResultOverflows = true;
}
return surfaceSize;