Separate MIP filtering from min/mag filtering.

Does not add kNearest as a mip map mode yet.

Bug: skia:10344

Change-Id: Ida80cbf19e2b1eed5209d0680837fb45e54b4261
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/303481
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index 32a48c9..6760b52 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -336,10 +336,17 @@
 }
 
 // Assumes srcRect and dstRect have already been optimized to fit the proxy
-static void draw_texture(GrRenderTargetContext* rtc, const GrClip* clip, const SkMatrix& ctm,
-                         const SkPaint& paint, const SkRect& srcRect, const SkRect& dstRect,
-                         const SkPoint dstClip[4], GrAA aa, GrQuadAAFlags aaFlags,
-                         SkCanvas::SrcRectConstraint constraint, GrSurfaceProxyView view,
+static void draw_texture(GrRenderTargetContext* rtc,
+                         const GrClip* clip,
+                         const SkMatrix& ctm,
+                         const SkPaint& paint,
+                         const SkRect& srcRect,
+                         const SkRect& dstRect,
+                         const SkPoint dstClip[4],
+                         GrAA aa,
+                         GrQuadAAFlags aaFlags,
+                         SkCanvas::SrcRectConstraint constraint,
+                         GrSurfaceProxyView view,
                          const GrColorInfo& srcColorInfo) {
     const GrColorInfo& dstInfo(rtc->colorInfo());
     auto textureXform =
@@ -378,15 +385,36 @@
         SkPoint srcQuad[4];
         GrMapRectPoints(dstRect, srcRect, dstClip, srcQuad, 4);
 
-        rtc->drawTextureQuad(clip, std::move(view), srcColorInfo.colorType(),
-                             srcColorInfo.alphaType(), filter, paint.getBlendMode(), color, srcQuad,
-                             dstClip, aa, aaFlags,
+        rtc->drawTextureQuad(clip,
+                             std::move(view),
+                             srcColorInfo.colorType(),
+                             srcColorInfo.alphaType(),
+                             filter,
+                             GrSamplerState::MipmapMode::kNone,
+                             paint.getBlendMode(),
+                             color,
+                             srcQuad,
+                             dstClip,
+                             aa,
+                             aaFlags,
                              constraint == SkCanvas::kStrict_SrcRectConstraint ? &srcRect : nullptr,
-                             ctm, std::move(textureXform));
+                             ctm,
+                             std::move(textureXform));
     } else {
-        rtc->drawTexture(clip, std::move(view), srcColorInfo.alphaType(), filter,
-                         paint.getBlendMode(), color, srcRect, dstRect, aa, aaFlags, constraint,
-                         ctm, std::move(textureXform));
+        rtc->drawTexture(clip,
+                         std::move(view),
+                         srcColorInfo.alphaType(),
+                         filter,
+                         GrSamplerState::MipmapMode::kNone,
+                         paint.getBlendMode(),
+                         color,
+                         srcRect,
+                         dstRect,
+                         aa,
+                         aaFlags,
+                         constraint,
+                         ctm,
+                         std::move(textureXform));
     }
 }
 
@@ -404,11 +432,11 @@
                                   GrAA aa,
                                   GrQuadAAFlags aaFlags,
                                   SkCanvas::SrcRectConstraint constraint,
-                                  GrSamplerState::WrapMode wm,
-                                  GrSamplerState::Filter fm,
+                                  GrSamplerState sampler,
                                   bool doBicubic) {
     const SkMatrix& ctm(matrixProvider.localToDevice());
-    if (wm == GrSamplerState::WrapMode::kClamp && !producer->isPlanar() &&
+    if (sampler.wrapModeX() == GrSamplerState::WrapMode::kClamp &&
+        sampler.wrapModeY() == GrSamplerState::WrapMode::kClamp && !producer->isPlanar() &&
         can_use_draw_texture(paint)) {
         // We've done enough checks above to allow us to pass ClampNearest() and not check for
         // scaling adjustments.
@@ -446,8 +474,9 @@
     bool coordsAllInsideSrcRect = aaFlags == GrQuadAAFlags::kNone && !mf;
 
     // Check for optimization to drop the src rect constraint when using linear filtering.
-    if (!doBicubic && fm == GrSamplerState::Filter::kLinear && restrictToSubset &&
-        coordsAllInsideSrcRect && !producer->isPlanar()) {
+    if (!doBicubic && sampler.filter() == GrSamplerState::Filter::kLinear && restrictToSubset &&
+        sampler.mipmapped() == GrMipmapped::kNo && coordsAllInsideSrcRect &&
+        !producer->isPlanar()) {
         SkMatrix combinedMatrix;
         combinedMatrix.setConcat(ctm, srcToDst);
         if (can_ignore_linear_filtering_subset(*producer, src, combinedMatrix, rtc->numSamples())) {
@@ -467,9 +496,10 @@
     const SkRect* domain = coordsAllInsideSrcRect ? &src : nullptr;
     std::unique_ptr<GrFragmentProcessor> fp;
     if (doBicubic) {
-        fp = producer->createBicubicFragmentProcessor(textureMatrix, subset, domain, wm, wm);
+        fp = producer->createBicubicFragmentProcessor(textureMatrix, subset, domain,
+                                                      sampler.wrapModeX(), sampler.wrapModeY());
     } else {
-        fp = producer->createFragmentProcessor(textureMatrix, subset, domain, {wm, fm});
+        fp = producer->createFragmentProcessor(textureMatrix, subset, domain, sampler);
     }
     if (fp) {
         fp = GrXfermodeFragmentProcessor::Make(std::move(fp), nullptr, SkBlendMode::kModulate);
@@ -534,8 +564,7 @@
                        const SkPaint& paint,
                        GrAA aa,
                        SkCanvas::SrcRectConstraint constraint,
-                       GrSamplerState::WrapMode wm,
-                       GrSamplerState::Filter fm,
+                       GrSamplerState sampler,
                        bool doBicubic) {
     SkRect clippedSrcRect = SkRect::Make(clippedSrcIRect);
 
@@ -562,7 +591,7 @@
                                             SkIntToScalar(iTileR.fTop));
             SkRect rectToDraw = tileR;
             srcToDst.mapRect(&rectToDraw);
-            if (fm != GrSamplerState::Filter::kNearest || doBicubic) {
+            if (sampler.filter() != GrSamplerState::Filter::kNearest || doBicubic) {
                 SkIRect iClampRect;
 
                 if (SkCanvas::kFast_SrcRectConstraint == constraint) {
@@ -611,10 +640,9 @@
                 tileR.offset(-offset.fX, -offset.fY);
                 SkMatrix offsetSrcToDst = srcToDst;
                 offsetSrcToDst.preTranslate(offset.fX, offset.fY);
-
                 draw_texture_producer(context, rtc, clip, matrixProvider, paint, &tileProducer,
                                       tileR, rectToDraw, nullptr, offsetSrcToDst, aa, aaFlags,
-                                      constraint, wm, fm, doBicubic);
+                                      constraint, sampler, doBicubic);
             }
         }
     }
@@ -650,10 +678,9 @@
                                              preViewMatrix ? *preViewMatrix : SkMatrix::I());
     const SkMatrix& ctm(matrixProvider.localToDevice());
 
-    bool doBicubic;
-    GrSamplerState::Filter fm = GrSkFilterQualityToGrFilterMode(
-            image->width(), image->height(), paint.getFilterQuality(), ctm, srcToDst,
-            fContext->priv().options().fSharpenMipmappedTextures, &doBicubic);
+    bool sharpenMM = fContext->priv().options().fSharpenMipmappedTextures;
+    auto [fm, mm, bicubic] = GrInterpretFilterQuality(image->dimensions(), paint.getFilterQuality(),
+                                                      ctm, srcToDst, sharpenMM);
 
     auto clip = this->clip();
 
@@ -667,7 +694,7 @@
         GrYUVAImageTextureMaker maker(fContext.get(), image);
         draw_texture_producer(fContext.get(), fRenderTargetContext.get(), clip, matrixProvider,
                               paint, &maker, src, dst, dstClip, srcToDst, aa, aaFlags, constraint,
-                              wrapMode, fm, doBicubic);
+                              {wrapMode, fm, mm}, bicubic);
         return;
     }
 
@@ -691,7 +718,7 @@
         GrTextureAdjuster adjuster(fContext.get(), std::move(view), colorInfo, pinnedUniqueID);
         draw_texture_producer(fContext.get(), fRenderTargetContext.get(), clip, matrixProvider,
                               paint, &adjuster, src, dst, dstClip, srcToDst, aa, aaFlags,
-                              constraint, wrapMode, fm, doBicubic);
+                              constraint, {wrapMode, fm, mm}, bicubic);
         return;
     }
 
@@ -701,7 +728,7 @@
         SkASSERT(!image->isTextureBacked());
 
         int tileFilterPad;
-        if (doBicubic) {
+        if (bicubic) {
             tileFilterPad = GrBicubicEffect::kFilterTexelPad;
         } else if (GrSamplerState::Filter::kNearest == fm) {
             tileFilterPad = 0;
@@ -724,7 +751,7 @@
                 LogDrawScaleFactor(ctm, srcToDst, paint.getFilterQuality());
                 draw_tiled_bitmap(fContext.get(), fRenderTargetContext.get(), clip, bm, tileSize,
                                   matrixProvider, srcToDst, src, clippedSubset, paint, aa,
-                                  constraint, wrapMode, fm, doBicubic);
+                                  constraint, {wrapMode, fm, mm}, bicubic);
                 return;
             }
         }
@@ -740,7 +767,7 @@
         GrImageTextureMaker maker(fContext.get(), image, GrImageTexGenPolicy::kDraw);
         draw_texture_producer(fContext.get(), fRenderTargetContext.get(), clip, matrixProvider,
                               paint, &maker, src, dst, dstClip, srcToDst, aa, aaFlags, constraint,
-                              wrapMode, fm, doBicubic);
+                              {wrapMode, fm, mm}, bicubic);
         return;
     }
 
@@ -749,7 +776,7 @@
         GrBitmapTextureMaker maker(fContext.get(), bm, GrImageTexGenPolicy::kDraw);
         draw_texture_producer(fContext.get(), fRenderTargetContext.get(), clip, matrixProvider,
                               paint, &maker, src, dst, dstClip, srcToDst, aa, aaFlags, constraint,
-                              wrapMode, fm, doBicubic);
+                              {wrapMode, fm, mm}, bicubic);
     }
 
     // Otherwise don't know how to draw it
@@ -799,9 +826,17 @@
             auto textureXform = GrColorSpaceXform::Make(
                     set[base].fImage->colorSpace(), set[base].fImage->alphaType(),
                     fRenderTargetContext->colorInfo().colorSpace(), kPremul_SkAlphaType);
-            fRenderTargetContext->drawTextureSet(this->clip(), textures.get() + base, n, p,
-                                                 filter, mode, GrAA::kYes, constraint,
-                                                 this->localToDevice(), std::move(textureXform));
+            fRenderTargetContext->drawTextureSet(this->clip(),
+                                                 textures.get() + base,
+                                                 n,
+                                                 p,
+                                                 filter,
+                                                 GrSamplerState::MipmapMode::kNone,
+                                                 mode,
+                                                 GrAA::kYes,
+                                                 constraint,
+                                                 this->localToDevice(),
+                                                 std::move(textureXform));
         }
         base = nextBase;
         n = 0;