plumb cubic params into gpu backend

Tiny diffs seen, but not sure how to avoid those and keep the code
path simple -- so just plan/hope to rebaseline as needed.

Change-Id: Id8ff7e85a6e70785592f76118a32def2d61599ec
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/314076
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp
index bc8b675..3cd01df 100755
--- a/src/shaders/SkImageShader.cpp
+++ b/src/shaders/SkImageShader.cpp
@@ -23,13 +23,28 @@
 #include "src/shaders/SkEmptyShader.h"
 
 SkM44 SkImageShader::CubicResamplerMatrix(float B, float C) {
-    const float scale = 1.0f/18;
-    B *= scale;
-    C *= scale;
-    return SkM44(    3*B, -9*B - 18*C,       9*B + 36*C,      -3*B - 18*C,
-                 1 - 6*B,           0, -3 + 36*B + 18*C,  2 - 27*B - 18*C,
-                     3*B,  9*B + 18*C,  3 - 45*B - 36*C, -2 + 27*B + 18*C,
-                       0,           0,            -18*C,       3*B + 18*C);
+#if 0
+    constexpr SkM44 kMitchell = SkM44( 1.f/18.f, -9.f/18.f,  15.f/18.f,  -7.f/18.f,
+                                      16.f/18.f,  0.f/18.f, -36.f/18.f,  21.f/18.f,
+                                       1.f/18.f,  9.f/18.f,  27.f/18.f, -21.f/18.f,
+                                       0.f/18.f,  0.f/18.f,  -6.f/18.f,   7.f/18.f);
+
+    constexpr SkM44 kCatmull = SkM44(0.0f, -0.5f,  1.0f, -0.5f,
+                                     1.0f,  0.0f, -2.5f,  1.5f,
+                                     0.0f,  0.5f,  2.0f, -1.5f,
+                                     0.0f,  0.0f, -0.5f,  0.5f);
+
+    if (B == 1.0f/3 && C == 1.0f/3) {
+        return kMitchell;
+    }
+    if (B == 0 && C == 0.5f) {
+        return kCatmull;
+    }
+#endif
+    return SkM44(    (1.f/6)*B, -(3.f/6)*B - C,       (3.f/6)*B + 2*C,    - (1.f/6)*B - C,
+                 1 - (2.f/6)*B,              0, -3 + (12.f/6)*B +   C,  2 - (9.f/6)*B - C,
+                     (1.f/6)*B,  (3.f/6)*B + C,  3 - (15.f/6)*B - 2*C, -2 + (9.f/6)*B + C,
+                             0,              0,                    -C,      (1.f/6)*B + C);
 }
 
 /**
@@ -378,29 +393,41 @@
     GrSamplerState::Filter fm;
     GrSamplerState::MipmapMode mm;
     bool bicubic;
-    if (fFilterEnum == kUseFilterOptions) {
-        bicubic = false;
-        switch (fFilterOptions.fSampling) {
-            case SkSamplingMode::kNearest: fm = GrSamplerState::Filter::kNearest; break;
-            case SkSamplingMode::kLinear : fm = GrSamplerState::Filter::kLinear ; break;
-        }
-        switch (fFilterOptions.fMipmap) {
-            case SkMipmapMode::kNone   : mm = GrSamplerState::MipmapMode::kNone   ; break;
-            case SkMipmapMode::kNearest: mm = GrSamplerState::MipmapMode::kNearest; break;
-            case SkMipmapMode::kLinear : mm = GrSamplerState::MipmapMode::kLinear ; break;
-        }
-    } else {
-        std::tie(fm, mm, bicubic) =
-                GrInterpretFilterQuality(fImage->dimensions(),
-                                         this->resolveFiltering(args.fFilterQuality),
-                                         args.fMatrixProvider.localToDevice(),
-                                         *lm,
-                                         sharpen,
-                                         args.fAllowFilterQualityReduction);
+    SkImage::CubicResampler kernel = GrBicubicEffect::gMitchell;
+
+    switch (fFilterEnum) {
+        case FilterEnum::kUseFilterOptions:
+            bicubic = false;
+            switch (fFilterOptions.fSampling) {
+                case SkSamplingMode::kNearest: fm = GrSamplerState::Filter::kNearest; break;
+                case SkSamplingMode::kLinear : fm = GrSamplerState::Filter::kLinear ; break;
+            }
+            switch (fFilterOptions.fMipmap) {
+                case SkMipmapMode::kNone   : mm = GrSamplerState::MipmapMode::kNone   ; break;
+                case SkMipmapMode::kNearest: mm = GrSamplerState::MipmapMode::kNearest; break;
+                case SkMipmapMode::kLinear : mm = GrSamplerState::MipmapMode::kLinear ; break;
+            }
+            break;
+        case FilterEnum::kUseCubicResampler:
+            bicubic = true;
+            kernel = fCubic;
+            fm = GrSamplerState::Filter::kNearest;
+            mm = GrSamplerState::MipmapMode::kNone;
+            break;
+        case FilterEnum::kInheritFromPaint:
+        default: // none, low, medium, high
+            std::tie(fm, mm, bicubic) =
+                    GrInterpretFilterQuality(fImage->dimensions(),
+                                             this->resolveFiltering(args.fFilterQuality),
+                                             args.fMatrixProvider.localToDevice(),
+                                             *lm,
+                                             sharpen,
+                                             args.fAllowFilterQualityReduction);
+            break;
     }
     std::unique_ptr<GrFragmentProcessor> fp;
     if (bicubic) {
-        fp = producer->createBicubicFragmentProcessor(lmInverse, nullptr, nullptr, wmX, wmY);
+        fp = producer->createBicubicFragmentProcessor(lmInverse, nullptr, nullptr, wmX, wmY, kernel);
     } else {
         fp = producer->createFragmentProcessor(lmInverse, nullptr, nullptr, {wmX, wmY, fm, mm});
     }