Clip GPU blur against clip bounds.  Clip the size of the FBOs used for blurs
to the bounds of the clipping region, inflated by the blur radius.  This is a
little tricky, since we want the rect we use for downsampling to be an integer
multiple of the scale factor, so we scale down the clip rect to downsampled
space, inflate by the (scaled) kernel width, and intersect the rects there.

Also check the blur radius against 0 and abort early, to prevent the fuzzer
blowing up on a missing uniform.

Review URL:  http://codereview.appspot.com/4841043/



git-svn-id: http://skia.googlecode.com/svn/trunk@2020 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 4294e49..c3754dc 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -843,6 +843,9 @@
     SkScalar radius = info.fIgnoreTransform ? info.fRadius
                                             : matrix.mapRadius(info.fRadius);
     radius = SkMinScalar(radius, MAX_BLUR_RADIUS);
+    if (radius <= 0) {
+        return false;
+    }
     float sigma = SkScalarToFloat(radius) * BLUR_SIGMA_SCALE;
     SkRect srcRect = path.getBounds();
 
@@ -852,15 +855,22 @@
         scaleFactor *= 2;
         sigma *= 0.5f;
     }
-    scaleRect(&srcRect, 1.0f / scaleFactor);
     int halfWidth = static_cast<int>(ceilf(sigma * 3.0f));
     int kernelWidth = halfWidth * 2 + 1;
 
-    SkIRect srcIRect;
-    srcRect.roundOut(&srcIRect);
-    srcRect.set(srcIRect);
+    float invScale = 1.0f / scaleFactor;
+    scaleRect(&srcRect, invScale);
+    srcRect.roundOut();
     srcRect.inset(-halfWidth, -halfWidth);
 
+    SkRect clipBounds;
+    clipBounds.set(clip.getBounds());
+    scaleRect(&clipBounds, invScale);
+    clipBounds.roundOut();
+    clipBounds.inset(-halfWidth, -halfWidth);
+
+    srcRect.intersect(clipBounds);
+
     scaleRect(&srcRect, scaleFactor);
     SkRect finalRect = srcRect;