SkCanvas::drawImage is the new way for drawing a SkImage to a Canvas

BUG=skia:2947

Committed: https://skia.googlesource.com/skia/+/432789972c1e1f8a66165c75a250dba1853efa08

R=junov@chromium.org, reed@google.com, bsalomon@google.com

Author: piotaixr@chromium.org

Review URL: https://codereview.chromium.org/583453002
diff --git a/gm/dftext.cpp b/gm/dftext.cpp
index 59106f7..5f58cb9 100755
--- a/gm/dftext.cpp
+++ b/gm/dftext.cpp
@@ -176,7 +176,7 @@
         // render offscreen buffer
         if (surface) {
             SkImage* image = surface->newImageSnapshot();
-            image->draw(inputCanvas, 0, 0, NULL);
+            inputCanvas->drawImage(image, 0, 0, NULL);
             image->unref();
         }
 #endif
diff --git a/gm/image.cpp b/gm/image.cpp
index a0959b2..05a3fab 100644
--- a/gm/image.cpp
+++ b/gm/image.cpp
@@ -30,7 +30,7 @@
         SkAutoCanvasRestore acr(canvas, true);
         canvas->scale(size.width() * 1.0f / image->width(),
                       size.height() * 1.0f / image->height());
-        image->draw(canvas, 0, 0, NULL);
+        canvas->drawImage(image, 0, 0, NULL);
         image->unref();
     }
 }
@@ -77,8 +77,8 @@
 //    paint.setFilterBitmap(true);
 //    paint.setAlpha(0x80);
 
-    imgR->draw(canvas, 0, 0, usePaint ? &paint : NULL);
-    imgG->draw(canvas, 0, 80, usePaint ? &paint : NULL);
+    canvas->drawImage(imgR, 0, 0, usePaint ? &paint : NULL);
+    canvas->drawImage(imgG, 0, 80, usePaint ? &paint : NULL);
     surf->draw(canvas, 0, 160, usePaint ? &paint : NULL);
 
     SkRect src1, src2, src3;
@@ -93,10 +93,10 @@
     dst3.set(0, 400, 65, 465);
     dst4.set(0, 480, 65, 545);
 
-    imgR->draw(canvas, &src1, dst1, usePaint ? &paint : NULL);
-    imgG->draw(canvas, &src2, dst2, usePaint ? &paint : NULL);
-    imgR->draw(canvas, &src3, dst3, usePaint ? &paint : NULL);
-    imgG->draw(canvas, NULL, dst4, usePaint ? &paint : NULL);
+    canvas->drawImageRect(imgR, &src1, dst1, usePaint ? &paint : NULL);
+    canvas->drawImageRect(imgG, &src2, dst2, usePaint ? &paint : NULL);
+    canvas->drawImageRect(imgR, &src3, dst3, usePaint ? &paint : NULL);
+    canvas->drawImageRect(imgG, NULL, dst4, usePaint ? &paint : NULL);
 
     imgG->unref();
     imgR->unref();
diff --git a/gm/multipicturedraw.cpp b/gm/multipicturedraw.cpp
index a915acd..75a4c89 100644
--- a/gm/multipicturedraw.cpp
+++ b/gm/multipicturedraw.cpp
@@ -56,7 +56,7 @@
 
     SkPictureRecorder recorder;
 
-    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kPicWidth), 
+    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kPicWidth),
                                                SkIntToScalar(kPicHeight));
 
     SkScalar xPos, yPos = 0;
@@ -138,7 +138,7 @@
 }
 
 // Create a Sierpinkski-like picture that starts with a top row with a picture
-// that just contains a triangle. Subsequent rows take the prior row's picture, 
+// that just contains a triangle. Subsequent rows take the prior row's picture,
 // shrinks it and replicates it 3 times then draws and appropriate number of
 // copies of it.
 static const SkPicture* make_sierpinski_picture() {
@@ -217,7 +217,7 @@
 
     SkRect rect = pictures[0]->cullRect();
     rect.inset(kInset, kInset);
-        
+
     SkRRect rrect;
     rrect.setRectXY(rect, kInset, kInset);
 
@@ -280,7 +280,7 @@
     {
         SkPictureRecorder recorder;
 
-        SkCanvas* pictureCanvas = recorder.beginRecording(SkIntToScalar(kPicWidth), 
+        SkCanvas* pictureCanvas = recorder.beginRecording(SkIntToScalar(kPicWidth),
                                                           SkIntToScalar(kPicHeight));
 
         (*pfGen)(pictureCanvas, pictures);
@@ -291,13 +291,13 @@
     mpd->add(dest, composite, &xform);
 }
 
-typedef void(*PFLayoutMtd)(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd, 
+typedef void(*PFLayoutMtd)(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
                            PFContentMtd pfGen, const SkPicture* pictures[kNumPictures],
                            SkTArray<ComposeStep>* composeSteps);
 
 // Draw the content into a single canvas
-static void simple(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd, 
-                   PFContentMtd pfGen, 
+static void simple(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
+                   PFContentMtd pfGen,
                    const SkPicture* pictures[kNumPictures],
                    SkTArray<ComposeStep> *composeSteps) {
 
@@ -312,7 +312,7 @@
 
 // Draw the content into multiple canvases/tiles
 static void tiled(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
-                  PFContentMtd pfGen, 
+                  PFContentMtd pfGen,
                   const SkPicture* pictures[kNumPictures],
                   SkTArray<ComposeStep> *composeSteps) {
     static const int kNumTilesX = 2;
@@ -324,7 +324,7 @@
     SkASSERT(kPicHeight == kNumTilesY * kTileHeight);
 
     static const SkColor colors[kNumTilesX][kNumTilesY] = {
-        { SK_ColorCYAN,   SK_ColorMAGENTA }, 
+        { SK_ColorCYAN,   SK_ColorMAGENTA },
         { SK_ColorYELLOW, SK_ColorGREEN   }
     };
 
@@ -415,8 +415,8 @@
             SkTArray<ComposeStep> composeSteps;
 
             // Fill up the MultiPictureDraw
-            (*gLayoutMthds[fLayout])(canvas, &mpd, 
-                                     gContentMthds[fContent], 
+            (*gLayoutMthds[fLayout])(canvas, &mpd,
+                                     gContentMthds[fContent],
                                      fPictures, &composeSteps);
 
             mpd.draw();
@@ -427,14 +427,14 @@
 
                 SkAutoTUnref<SkImage> image(step.fSurf->newImageSnapshot());
 
-                image->draw(canvas, step.fX, step.fY, step.fPaint);
+                canvas->drawImage(image, step.fX, step.fY, step.fPaint);
             }
         }
 
         virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(kPicWidth, kPicHeight); }
 
         virtual SkString onShortName() SK_OVERRIDE {
-            static const char* gContentNames[] = { 
+            static const char* gContentNames[] = {
                 "noclip", "rectclip", "rrectclip", "pathclip", "invpathclip", "sierpinski"
             };
             static const char* gLayoutNames[] = { "simple", "tiled" };
@@ -456,28 +456,28 @@
         typedef GM INHERITED;
     };
 
-    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_Content,     
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_Content,
                                                 MultiPictureDraw::kSimple_Layout));)
-    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti_Content,    
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti_Content,
                                                 MultiPictureDraw::kSimple_Layout));)
-    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMulti_Content,   
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMulti_Content,
                                                 MultiPictureDraw::kSimple_Layout));)
-    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti_Content,    
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti_Content,
                                                 MultiPictureDraw::kSimple_Layout));)
-    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMulti_Content, 
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMulti_Content,
                                                 MultiPictureDraw::kSimple_Layout));)
     DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Content,
                                                 MultiPictureDraw::kSimple_Layout));)
 
-    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_Content,     
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_Content,
                                                 MultiPictureDraw::kTiled_Layout));)
-    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti_Content,    
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti_Content,
                                                 MultiPictureDraw::kTiled_Layout));)
-    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMulti_Content,   
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMulti_Content,
                                                 MultiPictureDraw::kTiled_Layout));)
-    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti_Content,    
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti_Content,
                                                 MultiPictureDraw::kTiled_Layout));)
-    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMulti_Content, 
+    DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMulti_Content,
                                                 MultiPictureDraw::kTiled_Layout));)
     DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Content,
                                                 MultiPictureDraw::kTiled_Layout));)
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 77038c3..5828466 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -29,6 +29,7 @@
 class SkBaseDevice;
 class SkDraw;
 class SkDrawFilter;
+class SkImage;
 class SkMetaData;
 class SkPicture;
 class SkRRect;
@@ -811,6 +812,13 @@
     */
     virtual void drawPath(const SkPath& path, const SkPaint& paint);
 
+    virtual void drawImage(const SkImage* image, SkScalar left, SkScalar top,
+                           const SkPaint* paint = NULL);
+
+    virtual void drawImageRect(const SkImage* image, const SkRect* src,
+                               const SkRect& dst,
+                               const SkPaint* paint = NULL);
+
     /** Draw the specified bitmap, with its top/left corner at (x,y), using the
         specified paint, transformed by the current matrix. Note: if the paint
         contains a maskfilter that generates a mask which extends beyond the
@@ -1313,7 +1321,7 @@
     friend class SkSurface_Raster;  // needs getDevice()
     friend class SkRecorder;        // InitFlags
     friend class SkNoSaveLayerCanvas;   // InitFlags
-    
+
     enum InitFlags {
         kDefault_InitFlags                  = 0,
         kConservativeRasterClip_InitFlag    = 1 << 0,
@@ -1324,7 +1332,7 @@
 
     // needs gettotalclip()
     friend SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas*);
-    
+
     SkBaseDevice* createLayerDevice(const SkImageInfo&);
 
     // call this each time we attach ourselves to a device
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index a723aee..5a6c966 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -71,17 +71,6 @@
                                 SkShader::TileMode,
                                 const SkMatrix* localMatrix = NULL) const;
 
-    void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
-
-    /**
-     *  Draw the image, cropped to the src rect, to the dst rect of a canvas.
-     *  If src is larger than the bounds of the image, the rest of the image is
-     *  filled with transparent black pixels.
-     *
-     *  See SkCanvas::drawBitmapRectToRect for similar behavior.
-     */
-    void draw(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*) const;
-
     /**
      *  If the image has direct access to its pixels (i.e. they are in local
      *  RAM) return the (const) address of those pixels, and if not null, return
@@ -103,6 +92,17 @@
     SkData* encode(SkImageEncoder::Type t = SkImageEncoder::kPNG_Type,
                    int quality = 80) const;
 
+    void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
+
+    /**
+     *  Draw the image, cropped to the src rect, to the dst rect of a canvas.
+     *  If src is larger than the bounds of the image, the rest of the image is
+     *  filled with transparent black pixels.
+     *
+     *  See SkCanvas::drawBitmapRectToRect for similar behavior.
+     */
+    void draw(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*) const;
+
 protected:
     SkImage(int width, int height) :
         fWidth(width),
diff --git a/samplecode/SampleTextureDomain.cpp b/samplecode/SampleTextureDomain.cpp
index 926c559..af511c7 100644
--- a/samplecode/SampleTextureDomain.cpp
+++ b/samplecode/SampleTextureDomain.cpp
@@ -71,7 +71,7 @@
 
         srcRect.setXYWH(1, 1, 3, 3);
         dstRect.setXYWH(405, 5, 305, 305);
-        image->draw(canvas, &srcRect, dstRect, &paint);
+        canvas->drawImageRect(image, &srcRect, dstRect, &paint);
 
         // Test that bitmap blurring using a subrect
         // renders correctly
@@ -83,7 +83,7 @@
             SkBlurMaskFilter::kHighQuality_BlurFlag |
             SkBlurMaskFilter::kIgnoreTransform_BlurFlag);
         paint.setMaskFilter(mf)->unref();
-        image->draw(canvas, &srcRect, dstRect, &paint);
+        canvas->drawImageRect(image, &srcRect, dstRect, &paint);
 
         // Blur and a rotation + NULL src rect
         // This should not trigger the texture domain code
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index dcc7047..afd7fbe 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -12,6 +12,7 @@
 #include "SkDraw.h"
 #include "SkDrawFilter.h"
 #include "SkDrawLooper.h"
+#include "SkImage.h"
 #include "SkMetaData.h"
 #include "SkPathOps.h"
 #include "SkPatchUtils.h"
@@ -183,7 +184,7 @@
         fFilter     = NULL;
         fLayer      = NULL;
         fTopLayer   = NULL;
-        
+
         // don't bother initializing fNext
         inc_rec();
     }
@@ -192,7 +193,7 @@
         fFilter = SkSafeRef(prev.fFilter);
         fLayer = NULL;
         fTopLayer = prev.fTopLayer;
-        
+
         // don't bother initializing fNext
         inc_rec();
     }
@@ -292,7 +293,7 @@
             // can we be marked as simple?
             fIsSimple = !fFilter && !fDoClearImageFilter;
         }
-        
+
         uint32_t oldFlags = paint.getFlags();
         fNewPaintFlags = filter_paint_flags(props, oldFlags);
         if (fIsSimple && (fNewPaintFlags != oldFlags)) {
@@ -457,7 +458,7 @@
     SkNoPixelsBitmapDevice(int width, int height) : INHERITED(make_nopixels(width, height)) {}
 
 private:
-    
+
     typedef SkBitmapDevice INHERITED;
 };
 
@@ -466,7 +467,7 @@
     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
 {
     inc_canvas();
-    
+
     this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), kDefault_InitFlags)->unref();
 }
 
@@ -475,7 +476,7 @@
     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
 {
     inc_canvas();
-    
+
     this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unref();
 }
 
@@ -484,7 +485,7 @@
     , fProps(SkSurfacePropsCopyOrDefault(props))
 {
     inc_canvas();
-    
+
     this->init(device, flags);
 }
 
@@ -493,7 +494,7 @@
     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
 {
     inc_canvas();
-    
+
     this->init(device, kDefault_InitFlags);
 }
 
@@ -502,7 +503,7 @@
     , fProps(props)
 {
     inc_canvas();
-    
+
     SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
     this->init(device, kDefault_InitFlags);
 }
@@ -512,7 +513,7 @@
     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
 {
     inc_canvas();
-    
+
     SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
     this->init(device, kDefault_InitFlags);
 }
@@ -1885,6 +1886,17 @@
     LOOPER_END
 }
 
+void SkCanvas::drawImage(const SkImage* image, SkScalar left, SkScalar top,
+                       const SkPaint* paint) {
+    image->draw(this, left, top, paint);
+}
+
+void SkCanvas::drawImageRect(const SkImage* image, const SkRect* src,
+                           const SkRect& dst,
+                           const SkPaint* paint) {
+    image->draw(this, src, dst, paint);
+}
+
 void SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
                           const SkPaint* paint) {
     SkDEBUGCODE(bitmap.validate();)
diff --git a/src/gpu/GrRecordReplaceDraw.cpp b/src/gpu/GrRecordReplaceDraw.cpp
index 932e5be..b0e00b8 100644
--- a/src/gpu/GrRecordReplaceDraw.cpp
+++ b/src/gpu/GrRecordReplaceDraw.cpp
@@ -57,12 +57,12 @@
     SkRect src = SkRect::Make(ri->fSrcRect);
     SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX),
                                   SkIntToScalar(ri->fPos.fY),
-                                  SkIntToScalar(ri->fSrcRect.width()), 
+                                  SkIntToScalar(ri->fSrcRect.width()),
                                   SkIntToScalar(ri->fSrcRect.height()));
 
     canvas->save();
     canvas->setMatrix(initialMatrix);
-    ri->fImage->draw(canvas, &src, dst, ri->fPaint);
+    canvas->drawImageRect(ri->fImage, &src, dst, ri->fPaint);
     canvas->restore();
 }
 
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index 861515d..b10782a 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -76,7 +76,7 @@
 void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
     SkImage* image = this->newImageSnapshot();
     if (image) {
-        image->draw(canvas, x, y, paint);
+        canvas->drawImage(image, x, y, paint);
         image->unref();
     }
 }
diff --git a/src/utils/SkLua.cpp b/src/utils/SkLua.cpp
index d41a8fa..9880fe4 100644
--- a/src/utils/SkLua.cpp
+++ b/src/utils/SkLua.cpp
@@ -456,7 +456,7 @@
         paint.setAlpha(SkScalarRoundToInt(lua2scalar(L, 5) * 255));
         paintPtr = &paint;
     }
-    image->draw(canvas, x, y, paintPtr);
+    canvas->drawImage(image, x, y, paintPtr);
     return 0;
 }
 
diff --git a/tests/CachedDecodingPixelRefTest.cpp b/tests/CachedDecodingPixelRefTest.cpp
index 92e9d78..b3eb532 100644
--- a/tests/CachedDecodingPixelRefTest.cpp
+++ b/tests/CachedDecodingPixelRefTest.cpp
@@ -350,7 +350,7 @@
         SkCanvas canvas(bitmap);
         const SkColor kDefaultColor = 0xffabcdef;
         canvas.clear(kDefaultColor);
-        image->draw(&canvas, 0, 0, NULL);
+        canvas.drawImage(image, 0, 0, NULL);
         if (TestImageGenerator::kSucceedGetPixels_TestType == test) {
             REPORTER_ASSERT(
                     r, TestImageGenerator::Color() == *bitmap.getAddr32(0, 0));