Make small epsilons more rigorous for gpu gaussian blurs

This also has several other bug fixes and refactorings within it that
I realized were possible while updating every where that had checked
sigma > 0 to be sigma > kEffectivelyZeroSigma.

The big things are that SkBlurPriv.h goes away and its functions are
just moved into SkGpuBlurUtils since they were only used by the GPU.
The implementations of those functions are also collected into
SkGpuBlurUtils.cpp.  I removed the GrMatrixConvolution::MakeGaussian,
in favor of SkGpuBlurUtils filling in the kernel itself and then calling
the regular Make. This let me consolidate two different 1D kernel
computing functions, and remove the 1D fallback code from the 2D kernel
calculation because GaussianBlur() can detect that earlier.

The new GM, BlurSigmaSmall, originally drew incorrectly on the GPU
backend because it's small but non-zero sigma would trick the sigma > 0
checks in various places so we'd do a full 2 pass X/Y blur. However,
when the sigma was too small, the kernel was just filled with 0s so the
Y pass would effectively clear everything. While I could have just fixed
that to be a [0, 1, 0] kernel, updating the blur pipeline to compare
against integer radii seems more robust.

Change-Id: I3c41e0235a27615a9056b25e627ffedd995264bd
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/328797
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/effects/generated/GrRRectBlurEffect.cpp b/src/gpu/effects/generated/GrRRectBlurEffect.cpp
index e93e6f2..0d811f6 100644
--- a/src/gpu/effects/generated/GrRRectBlurEffect.cpp
+++ b/src/gpu/effects/generated/GrRRectBlurEffect.cpp
@@ -13,7 +13,6 @@
 #include "include/gpu/GrDirectContext.h"
 #include "include/gpu/GrRecordingContext.h"
 #include "src/core/SkAutoMalloc.h"
-#include "src/core/SkBlurPriv.h"
 #include "src/core/SkGpuBlurUtils.h"
 #include "src/core/SkRRectPriv.h"
 #include "src/gpu/GrBitmapTextureMaker.h"
@@ -32,6 +31,7 @@
 static void make_blurred_rrect_key(GrUniqueKey* key,
                                    const SkRRect& rrectToDraw,
                                    float xformedSigma) {
+    SkASSERT(!SkGpuBlurUtils::IsEffectivelyZeroSigma(xformedSigma));
     static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
 
     GrUniqueKey::Builder builder(key, kDomain, 9, "RoundRect Blur Mask");
@@ -54,6 +54,7 @@
                                const SkRRect& rrectToDraw,
                                const SkISize& dimensions,
                                float xformedSigma) {
+    SkASSERT(!SkGpuBlurUtils::IsEffectivelyZeroSigma(xformedSigma));
     std::unique_ptr<GrRenderTargetContext> rtc = GrRenderTargetContext::MakeWithFallback(
             dContext, GrColorType::kAlpha_8, nullptr, SkBackingFit::kExact, dimensions, 1,
             GrMipmapped::kNo, GrProtected::kNo, kBlurredRRectMaskOrigin);
@@ -95,12 +96,6 @@
     return true;
 }
 
-// TODO: merge w/ copy in SkGpuBlurUtils.cpp
-static int sigma_radius(float sigma) {
-    SkASSERT(sigma >= 0);
-    return static_cast<int>(ceilf(sigma * 3.0f));
-}
-
 // Evaluate the vertical blur at the specified 'y' value given the location of the top of the
 // rrect.
 static uint8_t eval_V(float top, int y, const uint8_t* integral, int integralSize, float sixSigma) {
@@ -155,7 +150,8 @@
                                              const SkRRect& rrectToDraw,
                                              const SkISize& dimensions,
                                              float xformedSigma) {
-    int radius = sigma_radius(xformedSigma);
+    SkASSERT(!SkGpuBlurUtils::IsEffectivelyZeroSigma(xformedSigma));
+    int radius = SkGpuBlurUtils::SigmaRadius(xformedSigma);
     int kernelSize = 2 * radius + 1;
 
     SkASSERT(kernelSize % 2);
@@ -170,10 +166,10 @@
 
     std::unique_ptr<float[]> kernel(new float[kernelSize]);
 
-    SkFillIn1DGaussianKernel(kernel.get(), xformedSigma, radius);
+    SkGpuBlurUtils::Compute1DGaussianKernel(kernel.get(), xformedSigma, radius);
 
     SkBitmap integral;
-    if (!SkCreateIntegralTable(6 * xformedSigma, &integral)) {
+    if (!SkGpuBlurUtils::CreateIntegralTable(6 * xformedSigma, &integral)) {
         return {};
     }
 
@@ -228,6 +224,7 @@
         const SkRRect& rrectToDraw,
         const SkISize& dimensions,
         float xformedSigma) {
+    SkASSERT(!SkGpuBlurUtils::IsEffectivelyZeroSigma(xformedSigma));
     GrUniqueKey key;
     make_blurred_rrect_key(&key, rrectToDraw, xformedSigma);
 
@@ -308,16 +305,20 @@
         return nullptr;
     }
 
+    if (SkGpuBlurUtils::IsEffectivelyZeroSigma(xformedSigma)) {
+        return inputFP;
+    }
+
     // Make sure we can successfully ninepatch this rrect -- the blur sigma has to be
     // sufficiently small relative to both the size of the corner radius and the
     // width (and height) of the rrect.
     SkRRect rrectToDraw;
     SkISize dimensions;
-    SkScalar ignored[kSkBlurRRectMaxDivisions];
+    SkScalar ignored[SkGpuBlurUtils::kBlurRRectMaxDivisions];
 
-    bool ninePatchable =
-            SkComputeBlurredRRectParams(srcRRect, devRRect, sigma, xformedSigma, &rrectToDraw,
-                                        &dimensions, ignored, ignored, ignored, ignored);
+    bool ninePatchable = SkGpuBlurUtils::ComputeBlurredRRectParams(
+            srcRRect, devRRect, sigma, xformedSigma, &rrectToDraw, &dimensions, ignored, ignored,
+            ignored, ignored);
     if (!ninePatchable) {
         return nullptr;
     }
@@ -376,18 +377,18 @@
                 args.fUniformHandler->getUniformCStr(proxyRectVar),
                 args.fUniformHandler->getUniformCStr(blurRadiusVar),
                 args.fUniformHandler->getUniformCStr(cornerRadiusVar));
-        SkString _sample17184 = this->invokeChild(0, args);
+        SkString _sample17491 = this->invokeChild(0, args);
         fragBuilder->codeAppendf(
                 R"SkSL(
 half4 inputColor = %s;)SkSL",
-                _sample17184.c_str());
-        SkString _coords17232("float2(texCoord)");
-        SkString _sample17232 = this->invokeChild(1, args, _coords17232.c_str());
+                _sample17491.c_str());
+        SkString _coords17539("float2(texCoord)");
+        SkString _sample17539 = this->invokeChild(1, args, _coords17539.c_str());
         fragBuilder->codeAppendf(
                 R"SkSL(
 %s = inputColor * %s;
 )SkSL",
-                args.fOutputColor, _sample17232.c_str());
+                args.fOutputColor, _sample17539.c_str());
     }
 
 private: