Pass samplingoptions to GrArgs

Also, add control over kMedium mapping

Seems like a loss that GrInterpret throws away the cubic coefficients...

A step towards https://skia-review.googlesource.com/c/skia/+/347022

Bug: skia:11105, skia:7650
Change-Id: I2564c29b0eeffd4df92c0baa78e2c04f6348d7d7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/347636
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index e40bf07..b61f805 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -219,10 +219,14 @@
                                            std::unique_ptr<GrFragmentProcessor>* shaderProcessor,
                                            SkBlendMode* primColorMode,
                                            GrPaint* grPaint) {
+    // TODO: take sampling directly
+    SkSamplingOptions sampling(SkPaintPriv::GetFQ(skPaint),
+                               SkSamplingOptions::kMedium_asMipmapLinear);
+
     // Convert SkPaint color to 4f format in the destination color space
     SkColor4f origColor = SkColor4fPrepForDst(skPaint.getColor4f(), dstColorInfo);
 
-    GrFPArgs fpArgs(context, matrixProvider, SkPaintPriv::GetFQ(skPaint), &dstColorInfo);
+    GrFPArgs fpArgs(context, matrixProvider, sampling, &dstColorInfo);
 
     // Setup the initial color considering the shader, the SkPaint color, and the presence or not
     // of per-vertex colors.
@@ -423,11 +427,15 @@
                                  std::unique_ptr<GrFragmentProcessor> fp,
                                  bool textureIsAlphaOnly,
                                  GrPaint* grPaint) {
+    // TODO: take sampling directly
+    SkSamplingOptions sampling(SkPaintPriv::GetFQ(paint),
+                               SkSamplingOptions::kMedium_asMipmapLinear);
+
     std::unique_ptr<GrFragmentProcessor> shaderFP;
     if (textureIsAlphaOnly) {
         if (const auto* shader = as_SB(paint.getShader())) {
             shaderFP = shader->asFragmentProcessor(
-                    GrFPArgs(context, matrixProvider, SkPaintPriv::GetFQ(paint), &dstColorInfo));
+                    GrFPArgs(context, matrixProvider, sampling, &dstColorInfo));
             if (!shaderFP) {
                 return false;
             }
@@ -451,54 +459,56 @@
 
 std::tuple<GrSamplerState::Filter,
            GrSamplerState::MipmapMode,
-           bool /*bicubic*/>
-GrInterpretFilterQuality(SkISize imageDims,
-                         SkFilterQuality paintFilterQuality,
-                         const SkMatrix& viewM,
-                         const SkMatrix& localM,
-                         bool sharpenMipmappedTextures,
-                         bool allowFilterQualityReduction) {
+           SkCubicResampler>
+GrInterpretSamplingOptions(SkISize imageDims,
+                           const SkSamplingOptions& sampling,
+                           const SkMatrix& viewM,
+                           const SkMatrix& localM,
+                           bool sharpenMipmappedTextures,
+                           bool allowFilterQualityReduction) {
     using Filter = GrSamplerState::Filter;
     using MipmapMode = GrSamplerState::MipmapMode;
-    switch (paintFilterQuality) {
-        case kNone_SkFilterQuality:
-            return {Filter::kNearest, MipmapMode::kNone, false};
-        case kLow_SkFilterQuality:
-            return {Filter::kLinear, MipmapMode::kNone, false};
-        case kMedium_SkFilterQuality: {
-            if (allowFilterQualityReduction) {
-                SkMatrix matrix;
-                matrix.setConcat(viewM, localM);
-                // With sharp mips, we bias lookups by -0.5. That means our final LOD is >= 0 until
-                // the computed LOD is >= 0.5. At what scale factor does a texture get an LOD of
-                // 0.5?
-                //
-                // Want:  0       = log2(1/s) - 0.5
-                //        0.5     = log2(1/s)
-                //        2^0.5   = 1/s
-                //        1/2^0.5 = s
-                //        2^0.5/2 = s
-                SkScalar mipScale = sharpenMipmappedTextures ? SK_ScalarRoot2Over2 : SK_Scalar1;
-                if (matrix.getMinScale() >= mipScale) {
-                    return {Filter::kLinear, MipmapMode::kNone, false};
-                }
+
+    if (sampling.useCubic) {
+        SkASSERT(GrValidCubicResampler(sampling.cubic));
+        if (allowFilterQualityReduction) {
+            SkMatrix matrix;
+            matrix.setConcat(viewM, localM);
+            switch (SkMatrixPriv::AdjustHighQualityFilterLevel(matrix)) {
+                case kNone_SkFilterQuality:   return {Filter::kNearest, MipmapMode::kNone  , kInvalidCubicResampler};
+                case kLow_SkFilterQuality:    return {Filter::kLinear , MipmapMode::kNone  , kInvalidCubicResampler};
+                case kMedium_SkFilterQuality: return {Filter::kLinear , MipmapMode::kLinear, kInvalidCubicResampler};
+                case kHigh_SkFilterQuality:   return {Filter::kNearest, MipmapMode::kNone  , sampling.cubic};
             }
-            return {Filter::kLinear, MipmapMode::kLinear, false};
-        }
-        case kHigh_SkFilterQuality: {
-            if (allowFilterQualityReduction) {
-                SkMatrix matrix;
-                matrix.setConcat(viewM, localM);
-                paintFilterQuality = SkMatrixPriv::AdjustHighQualityFilterLevel(matrix);
-            }
-            switch (paintFilterQuality) {
-                case kNone_SkFilterQuality:   return {Filter::kNearest, MipmapMode::kNone  , false};
-                case kLow_SkFilterQuality:    return {Filter::kLinear , MipmapMode::kNone  , false};
-                case kMedium_SkFilterQuality: return {Filter::kLinear , MipmapMode::kLinear, false};
-                case kHigh_SkFilterQuality:   return {Filter::kNearest, MipmapMode::kNone  , true };
-            }
-            SkUNREACHABLE;
+        } else {
+            return {Filter::kNearest, MipmapMode::kNone, sampling.cubic};
         }
     }
-    SkUNREACHABLE;
+
+    Filter f = sampling.filter == SkFilterMode::kNearest ? Filter::kNearest
+                                                         : Filter::kLinear;
+    MipmapMode m = MipmapMode::kNone;
+    if (sampling.mipmap != SkMipmapMode::kNone) {
+        m = MipmapMode::kLinear;
+        if (allowFilterQualityReduction) {
+            SkMatrix matrix;
+            matrix.setConcat(viewM, localM);
+            // With sharp mips, we bias lookups by -0.5. That means our final LOD is >= 0 until
+            // the computed LOD is >= 0.5. At what scale factor does a texture get an LOD of
+            // 0.5?
+            //
+            // Want:  0       = log2(1/s) - 0.5
+            //        0.5     = log2(1/s)
+            //        2^0.5   = 1/s
+            //        1/2^0.5 = s
+            //        2^0.5/2 = s
+            SkScalar mipScale = sharpenMipmappedTextures ? SK_ScalarRoot2Over2 : SK_Scalar1;
+            if (matrix.getMinScale() >= mipScale) {
+                m = MipmapMode::kNone;
+            }
+        } else if (sampling.mipmap == SkMipmapMode::kNearest) {
+            m = MipmapMode::kNearest;
+        }
+    }
+    return {f, m, kInvalidCubicResampler};
 }