Migrate to drawImage w/ sampling

Bug: skia:7650
Change-Id: Icb99ee9f7142fe1ca22f9fa66b1467486ce576a6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/357598
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/fuzz/FuzzCanvas.cpp b/fuzz/FuzzCanvas.cpp
index f6bf6aa..dea7b5d 100644
--- a/fuzz/FuzzCanvas.cpp
+++ b/fuzz/FuzzCanvas.cpp
@@ -1282,18 +1282,8 @@
                 if (usePaint) {
                     fuzz_paint(fuzz, &paint, depth - 1);
                 }
-                canvas->drawImage(img.get(), left, top, usePaint ? &paint : nullptr);
-                break;
-            }
-            case 34: {
-                auto img = make_fuzz_image(fuzz);
-                SkRect src, dst;
-                bool usePaint;
-                fuzz->next(&src, &dst, &usePaint);
-                if (usePaint) {
-                    fuzz_paint(fuzz, &paint, depth - 1);
-                }
-                canvas->drawImageRect(img, src, dst, usePaint ? &paint : nullptr);
+                canvas->drawImage(img.get(), left, top, SkSamplingOptions(),
+                                  usePaint ? &paint : nullptr);
                 break;
             }
             case 35: {
@@ -1308,18 +1298,8 @@
                 SkCanvas::SrcRectConstraint constraint =
                         make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
                                                 : SkCanvas::kFast_SrcRectConstraint;
-                canvas->drawImageRect(img, src, dst, usePaint ? &paint : nullptr, constraint);
-                break;
-            }
-            case 36: {
-                bool usePaint;
-                auto img = make_fuzz_image(fuzz);
-                SkRect dst;
-                fuzz->next(&dst, &usePaint);
-                if (usePaint) {
-                    fuzz_paint(fuzz, &paint, depth - 1);
-                }
-                canvas->drawImageRect(img, dst, usePaint ? &paint : nullptr);
+                canvas->drawImageRect(img.get(), SkRect::Make(src), dst, SkSamplingOptions(),
+                                      usePaint ? &paint : nullptr, constraint);
                 break;
             }
             case 37: {
diff --git a/gm/anisotropic.cpp b/gm/anisotropic.cpp
index fb5f696..995fb5c 100644
--- a/gm/anisotropic.cpp
+++ b/gm/anisotropic.cpp
@@ -65,8 +65,7 @@
     void draw(SkCanvas* canvas, int x, int y, int xSize, int ySize) {
         SkRect r = SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
                                     SkIntToScalar(xSize), SkIntToScalar(ySize));
-        canvas->drawImageRect(fImage.get(), r, fSampling, nullptr,
-                              SkCanvas::kStrict_SrcRectConstraint);
+        canvas->drawImageRect(fImage, r, fSampling);
     }
 
     void onDraw(SkCanvas* canvas) override {
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index d30138c..e1d0ef0 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -1666,7 +1666,16 @@
     void drawImageRect(const SkImage*, const SkRect& src, const SkRect& dst,
                        const SkSamplingOptions&, const SkPaint*, SrcRectConstraint);
     void drawImageRect(const SkImage*, const SkRect& dst, const SkSamplingOptions&,
-                       const SkPaint*, SrcRectConstraint);
+                       const SkPaint* = nullptr);
+    void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
+                       const SkSamplingOptions& sampling, const SkPaint* paint,
+                       SrcRectConstraint constraint) {
+        this->drawImageRect(image.get(), src, dst, sampling, paint, constraint);
+    }
+    void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst,
+                       const SkSamplingOptions& sampling, const SkPaint* paint = nullptr) {
+        this->drawImageRect(image.get(), dst, sampling, paint);
+    }
 
     /** Draws SkImage image stretched proportionally to fit into SkRect dst.
         SkIRect center divides the image into nine sections: four sides, four corners, and
diff --git a/samplecode/SampleAtlas.cpp b/samplecode/SampleAtlas.cpp
index add15bf..8f7f116 100644
--- a/samplecode/SampleAtlas.cpp
+++ b/samplecode/SampleAtlas.cpp
@@ -16,25 +16,27 @@
 #include "src/core/SkPaintPriv.h"
 
 typedef void (*DrawAtlasProc)(SkCanvas*, SkImage*, const SkRSXform[], const SkRect[],
-                              const SkColor[], int, const SkRect*, const SkPaint*);
+                              const SkColor[], int, const SkRect*, const SkSamplingOptions&,
+                              const SkPaint*);
 
 static void draw_atlas(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
                        const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
-                       const SkPaint* paint) {
-    canvas->drawAtlas(atlas, xform, tex, colors, count, SkBlendMode::kModulate, cull, paint);
+                       const SkSamplingOptions& sampling, const SkPaint* paint) {
+    canvas->drawAtlas(atlas, xform, tex, colors, count, SkBlendMode::kModulate,
+                      sampling, cull, paint);
 }
 
 static void draw_atlas_sim(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
                            const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
-                           const SkPaint* paint) {
+                           const SkSamplingOptions& sampling, const SkPaint* paint) {
     for (int i = 0; i < count; ++i) {
         SkMatrix matrix;
         matrix.setRSXform(xform[i]);
 
         canvas->save();
         canvas->concat(matrix);
-        canvas->drawImageRect(atlas, tex[i], tex[i].makeOffset(-tex[i].x(), -tex[i].y()), paint,
-                              SkCanvas::kFast_SrcRectConstraint);
+        canvas->drawImageRect(atlas, tex[i], tex[i].makeOffset(-tex[i].x(), -tex[i].y()),
+                              sampling, paint, SkCanvas::kFast_SrcRectConstraint);
         canvas->restore();
     }
 }
@@ -184,12 +186,11 @@
             }
         }
         SkPaint paint;
-        // TODO: add sampling options to drawAtlas
-        SkPaintPriv::SetFQ(&paint, kLow_SkFilterQuality);
+        SkSamplingOptions sampling(SkFilterMode::kLinear);
 
         const SkRect cull = this->getBounds();
         const SkColor* colorsPtr = fUseColors ? colors : nullptr;
-        fProc(canvas, fAtlas.get(), xform, fTex, colorsPtr, N, &cull, &paint);
+        fProc(canvas, fAtlas.get(), xform, fTex, colorsPtr, N, &cull, sampling, &paint);
     }
 
     SkRect onGetBounds() override {
diff --git a/samplecode/SampleChineseFling.cpp b/samplecode/SampleChineseFling.cpp
index 74c9ebc..081433c 100644
--- a/samplecode/SampleChineseFling.cpp
+++ b/samplecode/SampleChineseFling.cpp
@@ -142,19 +142,23 @@
                 sk_sp<SkImage> image = direct->priv().testingOnly_getFontAtlasImage(
                             GrMaskFormat::kA8_GrMaskFormat, 0);
                 canvas->drawImageRect(image,
-                                      SkRect::MakeXYWH(10.0f, 10.0f, 512.0f, 512.0), &paint);
+                                      SkRect::MakeXYWH(10.0f, 10.0f, 512.0f, 512.0),
+                                      SkSamplingOptions(), &paint);
                 image = direct->priv().testingOnly_getFontAtlasImage(
                         GrMaskFormat::kA8_GrMaskFormat, 1);
                 canvas->drawImageRect(image,
-                                      SkRect::MakeXYWH(522.0f, 10.0f, 512.f, 512.0f), &paint);
+                                      SkRect::MakeXYWH(522.0f, 10.0f, 512.f, 512.0f),
+                                      SkSamplingOptions(), &paint);
                 image = direct->priv().testingOnly_getFontAtlasImage(
                         GrMaskFormat::kA8_GrMaskFormat, 2);
                 canvas->drawImageRect(image,
-                                      SkRect::MakeXYWH(10.0f, 522.0f, 512.0f, 512.0f), &paint);
+                                      SkRect::MakeXYWH(10.0f, 522.0f, 512.0f, 512.0f),
+                                      SkSamplingOptions(), &paint);
                 image = direct->priv().testingOnly_getFontAtlasImage(
                         GrMaskFormat::kA8_GrMaskFormat, 3);
                 canvas->drawImageRect(image,
-                                      SkRect::MakeXYWH(522.0f, 522.0f, 512.0f, 512.0f), &paint);
+                                      SkRect::MakeXYWH(522.0f, 522.0f, 512.0f, 512.0f),
+                                      SkSamplingOptions(), &paint);
             }
 #endif
         }
diff --git a/samplecode/SampleFilterQuality.cpp b/samplecode/SampleFilterQuality.cpp
index adbb0f2..546ff7c 100644
--- a/samplecode/SampleFilterQuality.cpp
+++ b/samplecode/SampleFilterQuality.cpp
@@ -68,7 +68,7 @@
     canvas->scale(S, S);
     canvas->translate(-SkScalarHalf(orig->width()) * (S - D) / S,
                       -SkScalarHalf(orig->height()) * (S - D) / S);
-    canvas->drawImage(orig, 0, 0, nullptr);
+    canvas->drawImage(orig, 0, 0);
 
     if (S > 3) {
         SkPaint paint;
diff --git a/samplecode/SampleLayers.cpp b/samplecode/SampleLayers.cpp
index f7c1818..39282f9 100644
--- a/samplecode/SampleLayers.cpp
+++ b/samplecode/SampleLayers.cpp
@@ -190,7 +190,7 @@
     SkString name() override { return SkString("Backdrop"); }
 
     void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawImage(fImage.get(), 0, 0, nullptr);
+        canvas->drawImage(fImage.get(), 0, 0);
 
         const SkScalar w = 250;
         const SkScalar h = 150;
diff --git a/samplecode/SampleMixer.cpp b/samplecode/SampleMixer.cpp
index aa6d831..aa164b4 100644
--- a/samplecode/SampleMixer.cpp
+++ b/samplecode/SampleMixer.cpp
@@ -40,13 +40,14 @@
     void dodraw(SkCanvas* canvas, sk_sp<SkColorFilter> cf0, sk_sp<SkColorFilter> cf1, float gap) {
         SkPaint paint;
         paint.setColorFilter(cf0);
-        canvas->drawImage(fImg, 0, 0, &paint);
+        canvas->drawImage(fImg, 0, 0, SkSamplingOptions(), &paint);
 
         paint.setColorFilter(SkColorFilters::Lerp(fWeight, cf0, cf1));
-        canvas->drawImage(fImg, fImg->width() + gap * fWeight, 0, &paint);
+        canvas->drawImage(fImg, fImg->width() + gap * fWeight, 0,
+                          SkSamplingOptions(), &paint);
 
         paint.setColorFilter(cf1);
-        canvas->drawImage(fImg, 2*fImg->width() + gap, 0, &paint);
+        canvas->drawImage(fImg, 2*fImg->width() + gap, 0, SkSamplingOptions(), &paint);
     }
 
     void onDrawContent(SkCanvas* canvas) override {
diff --git a/samplecode/SampleTextureUpload.cpp b/samplecode/SampleTextureUpload.cpp
index 026cb4a..4f0757e 100644
--- a/samplecode/SampleTextureUpload.cpp
+++ b/samplecode/SampleTextureUpload.cpp
@@ -107,8 +107,6 @@
 
     void onDrawContent(SkCanvas* canvas) override {
 #if SK_SUPPORT_GPU
-        SkPaint paint;
-
         auto direct = GrAsDirectContext(canvas->recordingContext());
         if (direct) {
             // One-time context-specific setup.
@@ -133,7 +131,7 @@
                     for (int x = 0; x < fTileCols; x++) {
                         int currentIndex = y * fTileCols + x;
                         canvas->drawImage(fTextures[currentIndex]->getImage(),
-                                          x * fTileSize, y * fTileSize, &paint);
+                                          x * fTileSize, y * fTileSize);
                     }
                 }
             }
diff --git a/samplecode/SampleTiming.cpp b/samplecode/SampleTiming.cpp
index 4dce6d1..9e237a0 100644
--- a/samplecode/SampleTiming.cpp
+++ b/samplecode/SampleTiming.cpp
@@ -72,9 +72,12 @@
             for (int y = 0; y < H; y++)
             for (int x = 0; x < W; x++) {
                 auto start = std::chrono::steady_clock::now();
-                offscreen->getCanvas()->drawImageRect(fImg, SkRect::MakeXYWH(x,y,1,1)
-                                                          , SkRect::MakeXYWH(0,0,1024,1024)
-                                                          , /*paint=*/nullptr);
+                offscreen->getCanvas()->drawImageRect(fImg,
+                                                      SkRect::MakeXYWH(x,y,1,1),
+                                                      SkRect::MakeXYWH(0,0,1024,1024),
+                                                      SkSamplingOptions(),
+                                                      /*paint=*/nullptr,
+                                                      SkCanvas::kStrict_SrcRectConstraint);
                 auto elapsed = std::chrono::steady_clock::now() - start;
 
                 cost[y][x] = elapsed.count();
diff --git a/src/c/sk_surface.cpp b/src/c/sk_surface.cpp
index c2c0b99..ca23a7d 100644
--- a/src/c/sk_surface.cpp
+++ b/src/c/sk_surface.cpp
@@ -350,7 +350,7 @@
         canvas->drawImageRect(image, AsRect(*csrcR), dst, sampling, paint,
                               SkCanvas::kStrict_SrcRectConstraint);
     } else {
-        canvas->drawImageRect(image, dst, sampling, paint, SkCanvas::kStrict_SrcRectConstraint);
+        canvas->drawImageRect(image, dst, sampling, paint);
     }
 }
 
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 0d318ca..89e6439 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1852,6 +1852,7 @@
     this->onDrawPath(path, paint);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DRAWIMAGE_NOSAMPLING
 void SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) {
     this->drawImage(image, x, y, paint_to_sampling(paint, this->recordingContext()), paint);
 }
@@ -1880,6 +1881,7 @@
     this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint,
                         kFast_SrcRectConstraint);
 }
+#endif
 
 static SkPaint clean_paint_for_lattice(const SkPaint* paint) {
     SkPaint cleaned;
@@ -2362,11 +2364,10 @@
 }
 
 void SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst,
-                             const SkSamplingOptions& sampling, const SkPaint* paint,
-                             SrcRectConstraint constraint) {
+                             const SkSamplingOptions& sampling, const SkPaint* paint) {
     RETURN_ON_NULL(image);
     this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, sampling,
-                        paint, constraint);
+                        paint, kFast_SrcRectConstraint);
 }
 
 void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index b0c791e..bc9e416 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -357,7 +357,10 @@
             reader->readPoint(&loc);
             BREAK_ON_READ_ERROR(reader);
 
-            canvas->drawImage(image, loc.fX, loc.fY, paint);
+            canvas->drawImage(image, loc.fX, loc.fY,
+                              SkSamplingOptions(paint ? paint->getFilterQuality()
+                                                      : kNone_SkFilterQuality),
+                              paint);
         } break;
         case DRAW_IMAGE2: {
             const SkPaint* paint = fPictureData->optionalPaint(reader);
@@ -422,7 +425,7 @@
             if (src) {
                 canvas->drawImageRect(image, *src, dst, sampling, paint, constraint);
             } else {
-                canvas->drawImageRect(image, dst, sampling, paint, constraint);
+                canvas->drawImageRect(image, dst, sampling, paint);
             }
         } break;
         case DRAW_IMAGE_RECT2: {
diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp
index eef0f6d..2343352 100644
--- a/src/core/SkPixmap.cpp
+++ b/src/core/SkPixmap.cpp
@@ -569,7 +569,7 @@
     SkPaint p;
     p.setBlendMode(SkBlendMode::kSrc);
     surf->getCanvas()->concat(m);
-    surf->getCanvas()->drawImage(SkImage::MakeFromBitmap(bm), 0, 0, &p);
+    surf->getCanvas()->drawImage(SkImage::MakeFromBitmap(bm), 0, 0, SkSamplingOptions(), &p);
     return true;
 }
 
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 0ec1c63..37aa7b6 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -1419,7 +1419,7 @@
     canvas->clear(SK_ColorTRANSPARENT);
     SkPaint paint;
     paint.setColorFilter(sk_ref_sp(colorFilter));
-    canvas->drawImage(image, 0, 0, &paint);
+    canvas->drawImage(image, 0, 0, SkSamplingOptions(), &paint);
     return surface->makeImageSnapshot();
 }
 
diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp
index d997fb6..1f98545 100644
--- a/src/pdf/SkPDFShader.cpp
+++ b/src/pdf/SkPDFShader.cpp
@@ -49,7 +49,7 @@
     SkAutoCanvasRestore acr(canvas, true);
     canvas->concat(matrix);
     SkPaint paint(paintColor);
-    canvas->drawImage(SkImage::MakeFromBitmap(bm), 0, 0, &paint);
+    canvas->drawImage(bm.asImage(), 0, 0, SkSamplingOptions(), &paint);
 }
 
 static void fill_color_from_bitmap(SkCanvas* canvas,
diff --git a/src/utils/SkAnimCodecPlayer.cpp b/src/utils/SkAnimCodecPlayer.cpp
index 8c768ef..5e3f22b 100644
--- a/src/utils/SkAnimCodecPlayer.cpp
+++ b/src/utils/SkAnimCodecPlayer.cpp
@@ -91,7 +91,7 @@
             SkAssertResult(originMatrix.invert(&inverse));
             canvas->concat(inverse);
         }
-        canvas->drawImage(requiredImage, 0, 0, &paint);
+        canvas->drawImage(requiredImage, 0, 0, SkSamplingOptions(), &paint);
         opts.fPriorFrame = requiredFrame;
     }
 
@@ -107,7 +107,7 @@
         data = SkData::MakeUninitialized(size);
         auto canvas = SkCanvas::MakeRasterDirect(imageInfo, data->writable_data(), rb);
         canvas->concat(originMatrix);
-        canvas->drawImage(image, 0, 0, &paint);
+        canvas->drawImage(image, 0, 0, SkSamplingOptions(), &paint);
         image = SkImage::MakeRasterData(imageInfo, std::move(data), rb);
     }
     return fImages[index] = image;
diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp
index 08f19f3..f47011c 100644
--- a/tests/CodecTest.cpp
+++ b/tests/CodecTest.cpp
@@ -1682,7 +1682,7 @@
     bm.eraseColor(SK_ColorTRANSPARENT);
 
     SkCanvas canvas(bm);
-    canvas.drawImage(image, 0, 0, nullptr);
+    canvas.drawImage(image, 0, 0);
 
     for (int i = 0; i < image->width();  ++i)
     for (int j = 0; j < image->height(); ++j) {
@@ -1772,7 +1772,7 @@
     bm.eraseColor(SK_ColorTRANSPARENT);
 
     SkCanvas canvas(bm);
-    canvas.drawImage(image, 0, 0, nullptr);
+    canvas.drawImage(image, 0, 0);
 
     for (int i = 0; i < kWidth;  ++i)
     for (int j = 0; j < kHeight; ++j) {
diff --git a/tests/CompressedBackendAllocationTest.cpp b/tests/CompressedBackendAllocationTest.cpp
index 88b81e0..9fbe996 100644
--- a/tests/CompressedBackendAllocationTest.cpp
+++ b/tests/CompressedBackendAllocationTest.cpp
@@ -73,6 +73,8 @@
 
     SkCanvas* canvas = surf->getCanvas();
 
+    const SkSamplingOptions sampling(SkFilterMode::kLinear,
+                                     SkMipmapMode::kLinear);
     SkPaint p;
     SkPaintPriv::SetFQ(&p, kMedium_SkFilterQuality); // to force mipMapping
     p.setBlendMode(SkBlendMode::kSrc);
@@ -88,7 +90,7 @@
         canvas->clear(SK_ColorTRANSPARENT);
 
         SkRect r = SkRect::MakeWH(rectSize, rectSize);
-        canvas->drawImageRect(img, r, &p);
+        canvas->drawImageRect(img, r, sampling, &p);
 
         SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
                                                    kRGBA_8888_SkColorType,