Add onDrawBitmapLattice(), avoid unnecessary bitmap->image copy

out/Release/nanobench --match Lattice --config gpu --ms 3000
3.42ms -> 17.2us

For reference, a loop over drawBitmapRects (which is what
Android currently does) is about 13us.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2205273003

Review-Url: https://codereview.chromium.org/2205273003
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 80ff34d..539fd36 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -2057,6 +2057,19 @@
     }
 }
 
+void SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
+                                const SkPaint* paint) {
+    RETURN_ON_NULL(image);
+    if (dst.isEmpty()) {
+        return;
+    }
+    if (SkLatticeIter::Valid(image->width(), image->height(), lattice)) {
+        this->onDrawImageLattice(image, lattice, dst, paint);
+    } else {
+        this->drawImageRect(image, dst, paint);
+    }
+}
+
 void SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) {
     if (bitmap.drawsNothing()) {
         return;
@@ -2093,25 +2106,17 @@
     } else {
         this->drawBitmapRect(bitmap, dst, paint);
     }
-
 }
 
 void SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
                                  const SkPaint* paint) {
-    sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
-    this->drawImageLattice(image.get(), lattice, dst, paint);
-}
-
-void SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
-                                const SkPaint* paint) {
-    RETURN_ON_NULL(image);
-    if (dst.isEmpty()) {
+    if (bitmap.drawsNothing() || dst.isEmpty()) {
         return;
     }
-    if (SkLatticeIter::Valid(image->width(), image->height(), lattice)) {
-        this->onDrawImageLattice(image, lattice, dst, paint);
+    if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), lattice)) {
+        this->onDrawBitmapLattice(bitmap, lattice, dst, paint);
     } else {
-        this->drawImageRect(image, dst, paint);
+        this->drawBitmapRect(bitmap, dst, paint);
     }
 }
 
@@ -2419,29 +2424,6 @@
     LOOPER_END
 }
 
-void SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
-                                  const SkPaint* paint) {
-    if (nullptr == paint || paint->canComputeFastBounds()) {
-        SkRect storage;
-        if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) {
-            return;
-        }
-    }
-
-    SkLazyPaint lazy;
-    if (nullptr == paint) {
-        paint = lazy.init();
-    }
-
-    LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
-
-    while (iter.next()) {
-        iter.fDevice->drawImageLattice(iter, image, lattice, dst, looper.paint());
-    }
-
-    LOOPER_END
-}
-
 void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
                                const SkPaint* paint, SrcRectConstraint constraint) {
     TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()");
@@ -2612,6 +2594,52 @@
     LOOPER_END
 }
 
+void SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
+                                  const SkPaint* paint) {
+    if (nullptr == paint || paint->canComputeFastBounds()) {
+        SkRect storage;
+        if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) {
+            return;
+        }
+    }
+
+    SkLazyPaint lazy;
+    if (nullptr == paint) {
+        paint = lazy.init();
+    }
+
+    LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
+
+    while (iter.next()) {
+        iter.fDevice->drawImageLattice(iter, image, lattice, dst, looper.paint());
+    }
+
+    LOOPER_END
+}
+
+void SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
+                                   const SkRect& dst, const SkPaint* paint) {
+    if (nullptr == paint || paint->canComputeFastBounds()) {
+        SkRect storage;
+        if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) {
+            return;
+        }
+    }
+
+    SkLazyPaint lazy;
+    if (nullptr == paint) {
+        paint = lazy.init();
+    }
+
+    LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
+
+    while (iter.next()) {
+        iter.fDevice->drawBitmapLattice(iter, bitmap, lattice, dst, looper.paint());
+    }
+
+    LOOPER_END
+}
+
 class SkDeviceFilteredPaint {
 public:
     SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) {