Bug 1336480 - Part 1. Apply suface limitation in nsFilterInstance::ComputeNeededBoxes. r=mstange
authorcku <cku@mozilla.com>
Tue, 21 Feb 2017 00:08:38 +0800
changeset 373372 f413492608a60e5ea8b0c16fd2f847f3c0a387f0
parent 373371 e4f1979be0d7e681b6ee68ebf4812b1e68c0f9d8
child 373373 d26eb1db5b1c4b9cec29a75c3d2e893dbd3b3e78
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1336480
milestone54.0a1
Bug 1336480 - Part 1. Apply suface limitation in nsFilterInstance::ComputeNeededBoxes. r=mstange There is no need to limit output space bounds in nsFilterInstance::OutputFilterSpaceBounds(), it's just far too early. MozReview-Commit-ID: 9i9huKDGxq6
layout/svg/nsFilterInstance.cpp
layout/svg/nsSVGUtils.cpp
--- 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;