add src-rect-constraint to drawImageRect

Follow-on work
- unify around SrcRectConstraint (i.e. drawBitmapRect)
- remove silly drawBitmapRectToRect alias
- clean-up (possibly remove) alias problems around drawBitmapRect + IRect parameter

BUG=skia:

Review URL: https://codereview.chromium.org/1228083004
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index b94daef..388708d 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -237,8 +237,7 @@
 
 void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
                                     const SkRect* src, const SkRect& dst,
-                                    const SkPaint& paint,
-                                    SkCanvas::DrawBitmapRectFlags flags) {
+                                    const SkPaint& paint, SK_VIRTUAL_CONSTRAINT_TYPE) {
     SkMatrix    matrix;
     SkRect      bitmapBounds, tmpSrc, tmpDst;
     SkBitmap    tmpBitmap;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 09bfa45..35551e7 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1765,11 +1765,11 @@
 }
 
 void SkCanvas::drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
-                             const SkPaint* paint) {
+                             const SkPaint* paint, SrcRectConstraint constraint) {
     if (dst.isEmpty()) {
         return;
     }
-    this->onDrawImageRect(image, src, dst, paint);
+    this->onDrawImageRect(image, src, dst, paint SRC_RECT_CONSTRAINT_ARG(constraint));
 }
 
 void SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
@@ -1795,7 +1795,15 @@
     if (bitmap.drawsNothing() || dst.isEmpty()) {
         return;
     }
-    this->onDrawBitmapRect(bitmap, src, dst, paint, flags);
+    this->onDrawBitmapRect(bitmap, src, dst, paint, (SK_VIRTUAL_CONSTRAINT_TYPE)flags);
+}
+
+void SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
+                              const SkPaint* paint, SrcRectConstraint constraint) {
+    if (bitmap.drawsNothing() || dst.isEmpty()) {
+        return;
+    }
+    this->onDrawBitmapRect(bitmap, src, dst, paint, (SK_VIRTUAL_CONSTRAINT_TYPE)constraint);
 }
 
 void SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
@@ -1804,7 +1812,7 @@
         return;
     }
     if (!SkNinePatchIter::Valid(bitmap.width(), bitmap.height(), center)) {
-        this->drawBitmapRectToRect(bitmap, NULL, dst, paint);
+        this->drawBitmapRect(bitmap, dst, paint);
     }
     this->onDrawBitmapNine(bitmap, center, dst, paint);
 }
@@ -2042,8 +2050,9 @@
 }
 
 void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
-                               const SkPaint* paint) {
+                               const SkPaint* paint SRC_RECT_CONSTRAINT_PARAM(constraint)) {
     TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()");
+    SRC_RECT_CONSTRAINT_LOCAL_DEFAULT(constraint)
     SkRect storage;
     const SkRect* bounds = &dst;
     if (NULL == paint || paint->canComputeFastBounds()) {
@@ -2062,7 +2071,7 @@
     LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds)
     
     while (iter.next()) {
-        iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint());
+        iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint);
     }
     
     LOOPER_END
@@ -2094,7 +2103,7 @@
 // this one is non-virtual, so it can be called safely by other canvas apis
 void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
                                       const SkRect& dst, const SkPaint* paint,
-                                      DrawBitmapRectFlags flags) {
+                                      SrcRectConstraint constraint) {
     if (bitmap.drawsNothing() || dst.isEmpty()) {
         return;
     }
@@ -2118,17 +2127,18 @@
     LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds)
 
     while (iter.next()) {
-        iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), flags);
+        iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(),
+                                     (SK_VIRTUAL_CONSTRAINT_TYPE)constraint);
     }
 
     LOOPER_END
 }
 
 void SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
-                                const SkPaint* paint, DrawBitmapRectFlags flags) {
+                                const SkPaint* paint, SK_VIRTUAL_CONSTRAINT_TYPE constraint) {
     TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()");
     SkDEBUGCODE(bitmap.validate();)
-    this->internalDrawBitmapRect(bitmap, src, dst, paint, flags);
+    this->internalDrawBitmapRect(bitmap, src, dst, paint, (SrcRectConstraint)constraint);
 }
 
 void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 90161b4..6922e0d 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -154,11 +154,12 @@
 }
 
 void SkBaseDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
-                                 const SkRect& dst, const SkPaint& paint) {
+                                 const SkRect& dst, const SkPaint& paint,
+                                 SkCanvas::SrcRectConstraint constraint) {
     // Default impl : turns everything into raster bitmap
     SkBitmap bm;
     if (as_IB(image)->getROPixels(&bm)) {
-        this->drawBitmapRect(draw, bm, src, dst, paint, SkCanvas::kNone_DrawBitmapRectFlag);
+        this->drawBitmapRect(draw, bm, src, dst, paint, (SK_VIRTUAL_CONSTRAINT_TYPE)constraint);
     }
 }
 
@@ -168,7 +169,7 @@
 
     SkRect srcR, dstR;
     while (iter.next(&srcR, &dstR)) {
-        this->drawImageRect(draw, image, &srcR, dstR, paint);
+        this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
     }
 }
 
@@ -178,7 +179,8 @@
     
     SkRect srcR, dstR;
     while (iter.next(&srcR, &dstR)) {
-        this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kNone_DrawBitmapRectFlag);
+        this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint,
+                             (SK_VIRTUAL_CONSTRAINT_TYPE)SkCanvas::kStrict_SrcRectConstraint);
     }
 }
 
diff --git a/src/core/SkMiniRecorder.cpp b/src/core/SkMiniRecorder.cpp
index 538db08..916c477 100644
--- a/src/core/SkMiniRecorder.cpp
+++ b/src/core/SkMiniRecorder.cpp
@@ -72,8 +72,8 @@
     new (fBuffer.get()) Type(__VA_ARGS__);         \
     return true
 
-bool SkMiniRecorder::drawBitmapRectToRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst,
-                                          const SkPaint* p, SkCanvas::DrawBitmapRectFlags flags) {
+bool SkMiniRecorder::drawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst,
+                                    const SkPaint* p, SkCanvas::SrcRectConstraint constraint) {
     SkRect bounds;
     if (!src) {
         bm.getBounds(&bounds);
@@ -83,7 +83,7 @@
     if (!p) {
         p = defaultPaint.init();
     }
-    TRY_TO_STORE(DrawBitmapRectToRectFixedSize, *p, bm, *src, dst, flags);
+    TRY_TO_STORE(DrawBitmapRectFixedSize, *p, bm, *src, dst, constraint);
 }
 
 bool SkMiniRecorder::drawRect(const SkRect& rect, const SkPaint& paint) {
@@ -108,7 +108,7 @@
 
     switch (fState) {
         case State::kEmpty: return SkRef(gEmptyPicture.get());
-        CASE(DrawBitmapRectToRectFixedSize);
+        CASE(DrawBitmapRectFixedSize);
         CASE(DrawPath);
         CASE(DrawRect);
         CASE(DrawTextBlob);
@@ -129,7 +129,7 @@
 
     switch (fState) {
         case State::kEmpty: return;
-        CASE(DrawBitmapRectToRectFixedSize);
+        CASE(DrawBitmapRectFixedSize);
         CASE(DrawPath);
         CASE(DrawRect);
         CASE(DrawTextBlob);
diff --git a/src/core/SkMiniRecorder.h b/src/core/SkMiniRecorder.h
index 023e2ad..5b68fc2 100644
--- a/src/core/SkMiniRecorder.h
+++ b/src/core/SkMiniRecorder.h
@@ -20,8 +20,8 @@
     ~SkMiniRecorder();
 
     // Try to record an op.  Returns false on failure.
-    bool drawBitmapRectToRect(const SkBitmap&, const SkRect* src, const SkRect& dst,
-                              const SkPaint*, SkCanvas::DrawBitmapRectFlags);
+    bool drawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst,
+                        const SkPaint*, SkCanvas::SrcRectConstraint);
     bool drawPath(const SkPath&, const SkPaint&);
     bool drawRect(const SkRect&, const SkPaint&);
     bool drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y, const SkPaint&);
@@ -38,7 +38,7 @@
 private:
     enum class State {
         kEmpty,
-        kDrawBitmapRectToRectFixedSize,
+        kDrawBitmapRectFixedSize,
         kDrawPath,
         kDrawRect,
         kDrawTextBlob,
@@ -50,7 +50,7 @@
     struct Max { static const size_t val = A > B ? A : B; };
 
     static const size_t kInlineStorage =
-        Max<sizeof(SkRecords::DrawBitmapRectToRectFixedSize),
+        Max<sizeof(SkRecords::DrawBitmapRectFixedSize),
         Max<sizeof(SkRecords::DrawPath),
         Max<sizeof(SkRecords::DrawRect),
             sizeof(SkRecords::DrawTextBlob)>::val>::val>::val;
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index af6c1b4..64e51b7 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -29,7 +29,7 @@
     DRAW_BITMAP,
     DRAW_BITMAP_MATRIX, // deprecated, M41 was last Chromium version to write this to an .skp
     DRAW_BITMAP_NINE,
-    DRAW_BITMAP_RECT_TO_RECT,
+    DRAW_BITMAP_RECT,
     DRAW_CLEAR,
     DRAW_DATA,
     DRAW_OVAL,
@@ -70,11 +70,12 @@
     DRAW_PICTURE_MATRIX_PAINT,
     DRAW_TEXT_BLOB,
     DRAW_IMAGE,
-    DRAW_IMAGE_RECT,
+    DRAW_IMAGE_RECT_STRICT, // deprecated (M45)
     DRAW_ATLAS,
     DRAW_IMAGE_NINE,
+    DRAW_IMAGE_RECT,
 
-    LAST_DRAWTYPE_ENUM = DRAW_IMAGE_NINE
+    LAST_DRAWTYPE_ENUM = DRAW_IMAGE_RECT
 };
 
 // In the 'match' method, this constant will match any flavor of DRAW_BITMAP*
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 1cf1a1b..2338374 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -182,14 +182,13 @@
             const SkPoint& loc = reader->skipT<SkPoint>();
             canvas->drawBitmap(bitmap, loc.fX, loc.fY, paint);
         } break;
-        case DRAW_BITMAP_RECT_TO_RECT: {
+        case DRAW_BITMAP_RECT: {
             const SkPaint* paint = fPictureData->getPaint(reader);
             const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader));
             const SkRect* src = get_rect_ptr(reader);   // may be null
             const SkRect& dst = reader->skipT<SkRect>();     // required
-            SkCanvas::DrawBitmapRectFlags flags;
-            flags = (SkCanvas::DrawBitmapRectFlags) reader->readInt();
-            canvas->drawBitmapRectToRect(bitmap, src, dst, paint, flags);
+            SkCanvas::SrcRectConstraint constraint = (SkCanvas::SrcRectConstraint)reader->readInt();
+            canvas->drawBitmapRect(bitmap, src, dst, paint, constraint);
         } break;
         case DRAW_BITMAP_MATRIX: {
             const SkPaint* paint = fPictureData->getPaint(reader);
@@ -249,12 +248,19 @@
             const SkRect& dst = reader->skipT<SkRect>();
             canvas->drawImageNine(image, center, dst, paint);
         } break;
+        case DRAW_IMAGE_RECT_STRICT:
         case DRAW_IMAGE_RECT: {
             const SkPaint* paint = fPictureData->getPaint(reader);
             const SkImage* image = fPictureData->getImage(reader);
             const SkRect* src = get_rect_ptr(reader);   // may be null
             const SkRect& dst = reader->skipT<SkRect>();     // required
-            canvas->drawImageRect(image, src, dst, paint);
+            // DRAW_IMAGE_RECT_STRICT assumes this constraint, and doesn't store it
+            SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint;
+            if (DRAW_IMAGE_RECT == op) {
+                // newer op-code stores the constraint explicitly
+                constraint = (SkCanvas::SrcRectConstraint)reader->readInt();
+            }
+            canvas->drawImageRect(image, src, dst, paint, constraint);
         } break;
         case DRAW_OVAL: {
             const SkPaint& paint = *fPictureData->getPaint(reader);
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 5f85b47..60996db 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -61,7 +61,7 @@
         1,  // DRAW_BITMAP - right after op code
         1,  // DRAW_BITMAP_MATRIX - right after op code, deprecated
         1,  // DRAW_BITMAP_NINE - right after op code
-        1,  // DRAW_BITMAP_RECT_TO_RECT - right after op code
+        1,  // DRAW_BITMAP_RECT - right after op code
         0,  // DRAW_CLEAR - no paint
         0,  // DRAW_DATA - no paint
         1,  // DRAW_OVAL - right after op code
@@ -99,9 +99,10 @@
         1,  // DRAW_PICTURE_MATRIX_PAINT - right after op code
         1,  // DRAW_TEXT_BLOB- right after op code
         1,  // DRAW_IMAGE - right after op code
-        1,  // DRAW_IMAGE_RECT - right after op code
+        1,  // DRAW_IMAGE_RECT_STRICT - right after op code
         1,  // DRAW_ATLAS - right after op code
         1,  // DRAW_IMAGE_NINE - right after op code
+        1,  // DRAW_IMAGE_RECT - right after op code
     };
 
     SK_COMPILE_ASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1,
@@ -551,7 +552,8 @@
 }
 
 void SkPictureRecord::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
-                                       const SkPaint* paint, DrawBitmapRectFlags flags) {
+                                       const SkPaint* paint,
+                                       SK_VIRTUAL_CONSTRAINT_TYPE constraint) {
     // id + paint index + bitmap index + bool for 'src' + flags
     size_t size = 5 * kUInt32Size;
     if (src) {
@@ -559,14 +561,13 @@
     }
     size += sizeof(dst);        // + rect
 
-    size_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size);
-    SkASSERT(initialOffset+get_paint_offset(DRAW_BITMAP_RECT_TO_RECT, size)
-             == fWriter.bytesWritten());
+    size_t initialOffset = this->addDraw(DRAW_BITMAP_RECT, &size);
+    SkASSERT(initialOffset+get_paint_offset(DRAW_BITMAP_RECT, size) == fWriter.bytesWritten());
     this->addPaintPtr(paint);
     this->addBitmap(bitmap);
     this->addRectPtr(src);  // may be null
     this->addRect(dst);
-    this->addInt(flags);
+    this->addInt(constraint);
     this->validate(initialOffset, size);
 }
 
@@ -584,9 +585,10 @@
 }
 
 void SkPictureRecord::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
-                                      const SkPaint* paint) {
-    // id + paint_index + image_index + bool_for_src
-    size_t size = 4 * kUInt32Size;
+                                      const SkPaint* paint SRC_RECT_CONSTRAINT_PARAM(constraint)) {
+    SRC_RECT_CONSTRAINT_LOCAL_DEFAULT(constraint)
+    // id + paint_index + image_index + bool_for_src + constraint
+    size_t size = 5 * kUInt32Size;
     if (src) {
         size += sizeof(*src);   // + rect
     }
@@ -599,6 +601,7 @@
     this->addImage(image);
     this->addRectPtr(src);  // may be null
     this->addRect(dst);
+    this->addInt(constraint);
     this->validate(initialOffset, size);
 }
 
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index ed5d065..cb6f324 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -182,10 +182,10 @@
     void onDrawPath(const SkPath&, const SkPaint&) override;
     void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override;
     void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*,
-                          DrawBitmapRectFlags flags) override;
+                          SK_VIRTUAL_CONSTRAINT_TYPE) override;
     void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override;
     void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
-                         const SkPaint*) override;
+                         const SkPaint* SRC_RECT_CONSTRAINT_PARAM(constraint)) override;
     void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
                          const SkPaint*) override;
     void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index 7ef2eaf..8ceb9c1 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -88,14 +88,14 @@
 
 DRAW(DrawBitmap, drawBitmap(r.bitmap.shallowCopy(), r.left, r.top, r.paint));
 DRAW(DrawBitmapNine, drawBitmapNine(r.bitmap.shallowCopy(), r.center, r.dst, r.paint));
-DRAW(DrawBitmapRectToRect,
-        drawBitmapRectToRect(r.bitmap.shallowCopy(), r.src, r.dst, r.paint,
-                             SkCanvas::kNone_DrawBitmapRectFlag));
-DRAW(DrawBitmapRectToRectBleed,
-        drawBitmapRectToRect(r.bitmap.shallowCopy(), r.src, r.dst, r.paint,
-                             SkCanvas::kBleed_DrawBitmapRectFlag));
-DRAW(DrawBitmapRectToRectFixedSize,
-        drawBitmapRectToRect(r.bitmap.shallowCopy(), &r.src, r.dst, &r.paint, r.flags));
+DRAW(DrawBitmapRect,
+        drawBitmapRect(r.bitmap.shallowCopy(), r.src, r.dst, r.paint,
+                             SkCanvas::kStrict_SrcRectConstraint));
+DRAW(DrawBitmapRectFast,
+        drawBitmapRect(r.bitmap.shallowCopy(), r.src, r.dst, r.paint,
+                       SkCanvas::kFast_SrcRectConstraint));
+DRAW(DrawBitmapRectFixedSize,
+        drawBitmapRect(r.bitmap.shallowCopy(), &r.src, r.dst, &r.paint, r.constraint));
 DRAW(DrawDRRect, drawDRRect(r.outer, r.inner, r.paint));
 DRAW(DrawImage, drawImage(r.image, r.left, r.top, r.paint));
 DRAW(DrawImageRect, drawImageRect(r.image, r.src, r.dst, r.paint));
@@ -419,13 +419,13 @@
     Bounds bounds(const DrawImageNine& op) const {
         return this->adjustAndMap(op.dst, op.paint);
     }
-    Bounds bounds(const DrawBitmapRectToRect& op) const {
+    Bounds bounds(const DrawBitmapRect& op) const {
         return this->adjustAndMap(op.dst, op.paint);
     }
-    Bounds bounds(const DrawBitmapRectToRectBleed& op) const {
+    Bounds bounds(const DrawBitmapRectFast& op) const {
         return this->adjustAndMap(op.dst, op.paint);
     }
-    Bounds bounds(const DrawBitmapRectToRectFixedSize& op) const {
+    Bounds bounds(const DrawBitmapRectFixedSize& op) const {
         return this->adjustAndMap(op.dst, &op.paint);
     }
     Bounds bounds(const DrawBitmapNine& op) const {
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index 0413860..41164bd 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -186,7 +186,9 @@
                                   const SkRect* src,
                                   const SkRect& dst,
                                   const SkPaint* paint,
-                                  DrawBitmapRectFlags flags) {
+                                  SK_VIRTUAL_CONSTRAINT_TYPE legacyConstraint) {
+    SrcRectConstraint constraint = (SrcRectConstraint)legacyConstraint;
+
 #ifdef WRAP_BITMAP_AS_IMAGE
     // TODO: need a way to support the flags for images...
     SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap));
@@ -194,15 +196,13 @@
         this->onDrawImageRect(image, src, dst, paint);
     }
 #else
-    TRY_MINIRECORDER(drawBitmapRectToRect, bitmap, src, dst, paint, flags);
-    if (kBleed_DrawBitmapRectFlag == flags) {
-        APPEND(DrawBitmapRectToRectBleed,
-               this->copy(paint), bitmap, this->copy(src), dst);
+    TRY_MINIRECORDER(drawBitmapRect, bitmap, src, dst, paint, constraint);
+    if (kFast_SrcRectConstraint == constraint) {
+        APPEND(DrawBitmapRectFast, this->copy(paint), bitmap, this->copy(src), dst);
         return;
     }
-    SkASSERT(kNone_DrawBitmapRectFlag == flags);
-    APPEND(DrawBitmapRectToRect,
-           this->copy(paint), bitmap, this->copy(src), dst);
+    SkASSERT(kStrict_SrcRectConstraint == constraint);
+    APPEND(DrawBitmapRect, this->copy(paint), bitmap, this->copy(src), dst);
 #endif
 }
 
@@ -227,8 +227,11 @@
 
 void SkRecorder::onDrawImageRect(const SkImage* image, const SkRect* src,
                                  const SkRect& dst,
-                                 const SkPaint* paint) {
-    APPEND(DrawImageRect, this->copy(paint), image, this->copy(src), dst);
+                                 const SkPaint* paint SRC_RECT_CONSTRAINT_PARAM(constraint)) {
+#ifdef SK_SUPPORT_LEGACY_ONDRAWIMAGERECT
+    SrcRectConstraint constraint = kStrict_SrcRectConstraint;
+#endif
+    APPEND(DrawImageRect, this->copy(paint), image, this->copy(src), dst, constraint);
 }
 
 void SkRecorder::onDrawImageNine(const SkImage* image, const SkIRect& center,
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index b151578..404d54c 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -98,10 +98,10 @@
     void onDrawPath(const SkPath&, const SkPaint&) override;
     void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override;
     void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*,
-                          DrawBitmapRectFlags flags) override;
+                          SK_VIRTUAL_CONSTRAINT_TYPE) override;
     void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override;
     void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
-                         const SkPaint*) override;
+                         const SkPaint* SRC_RECT_CONSTRAINT_PARAM(constraint)) override;
     void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
                          const SkPaint*) override;
     void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h
index 074a560..9ab04c9 100644
--- a/src/core/SkRecords.h
+++ b/src/core/SkRecords.h
@@ -40,9 +40,9 @@
     M(ClipRegion)                                                   \
     M(DrawBitmap)                                                   \
     M(DrawBitmapNine)                                               \
-    M(DrawBitmapRectToRect)                                         \
-    M(DrawBitmapRectToRectBleed)                                    \
-    M(DrawBitmapRectToRectFixedSize)                                \
+    M(DrawBitmapRect)                                               \
+    M(DrawBitmapRectFast)                                           \
+    M(DrawBitmapRectFixedSize)                                      \
     M(DrawDrawable)                                                 \
     M(DrawImage)                                                    \
     M(DrawImageRect)                                                \
@@ -276,29 +276,30 @@
                         ImmutableBitmap, bitmap,
                         SkIRect, center,
                         SkRect, dst);
-RECORD4(DrawBitmapRectToRect, Optional<SkPaint>, paint,
-                              ImmutableBitmap, bitmap,
-                              Optional<SkRect>, src,
-                              SkRect, dst);
-RECORD4(DrawBitmapRectToRectBleed, Optional<SkPaint>, paint,
-                                   ImmutableBitmap, bitmap,
-                                   Optional<SkRect>, src,
-                                   SkRect, dst);
-RECORD5(DrawBitmapRectToRectFixedSize, SkPaint, paint,
-                                       ImmutableBitmap, bitmap,
-                                       SkRect, src,
-                                       SkRect, dst,
-                                       SkCanvas::DrawBitmapRectFlags, flags);
+RECORD4(DrawBitmapRect, Optional<SkPaint>, paint,
+                        ImmutableBitmap, bitmap,
+                        Optional<SkRect>, src,
+                        SkRect, dst);
+RECORD4(DrawBitmapRectFast, Optional<SkPaint>, paint,
+                            ImmutableBitmap, bitmap,
+                            Optional<SkRect>, src,
+                            SkRect, dst);
+RECORD5(DrawBitmapRectFixedSize, SkPaint, paint,
+                                 ImmutableBitmap, bitmap,
+                                 SkRect, src,
+                                 SkRect, dst,
+                                 SkCanvas::SrcRectConstraint, constraint);
 RECORD3(DrawDRRect, SkPaint, paint, SkRRect, outer, SkRRect, inner);
 RECORD3(DrawDrawable, Optional<SkMatrix>, matrix, SkRect, worstCaseBounds, int32_t, index);
 RECORD4(DrawImage, Optional<SkPaint>, paint,
                    RefBox<const SkImage>, image,
                    SkScalar, left,
                    SkScalar, top);
-RECORD4(DrawImageRect, Optional<SkPaint>, paint,
+RECORD5(DrawImageRect, Optional<SkPaint>, paint,
                        RefBox<const SkImage>, image,
                        Optional<SkRect>, src,
-                       SkRect, dst);
+                       SkRect, dst,
+                       SkCanvas::SrcRectConstraint, constraint);
 RECORD4(DrawImageNine, Optional<SkPaint>, paint,
                        RefBox<const SkImage>, image,
                        SkIRect, center,
diff --git a/src/effects/SkBitmapSource.cpp b/src/effects/SkBitmapSource.cpp
index ed9521f..859e8af 100644
--- a/src/effects/SkBitmapSource.cpp
+++ b/src/effects/SkBitmapSource.cpp
@@ -79,12 +79,12 @@
     // Subtract off the integer component of the translation (will be applied in loc, below).
     dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop));
     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
-    // FIXME: this probably shouldn't be necessary, but drawBitmapRectToRect asserts
+    // FIXME: this probably shouldn't be necessary, but drawBitmapRect asserts
     // None filtering when it's translate-only
     paint.setFilterQuality(
         fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ?
                kNone_SkFilterQuality : fFilterQuality);
-    canvas.drawBitmapRectToRect(fBitmap, &fSrcRect, dstRect, &paint);
+    canvas.drawBitmapRect(fBitmap, &fSrcRect, dstRect, &paint, SkCanvas::kStrict_SrcRectConstraint);
 
     *result = device.get()->accessBitmap(false);
     offset->fX = dstIRect.fLeft;
diff --git a/src/gpu/GrRecordReplaceDraw.cpp b/src/gpu/GrRecordReplaceDraw.cpp
index 6f05206..e3936de 100644
--- a/src/gpu/GrRecordReplaceDraw.cpp
+++ b/src/gpu/GrRecordReplaceDraw.cpp
@@ -43,7 +43,7 @@
 
         canvas->save();
         canvas->setMatrix(SkMatrix::I());
-        canvas->drawBitmapRectToRect(bm, &src, dst, layer->paint());
+        canvas->drawBitmapRect(bm, &src, dst, layer->paint(), SkCanvas::kStrict_SrcRectConstraint);
         canvas->restore();
     } else {
         canvas->drawSprite(bm,
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index e0658b3..9cf5b25 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -791,7 +791,7 @@
         concat.setConcat(*draw->fMatrix, m);
         draw.writable()->fMatrix = &concat;
     }
-    this->drawBitmapCommon(*draw, bitmap, NULL, NULL, paint, SkCanvas::kNone_DrawBitmapRectFlag);
+    this->drawBitmapCommon(*draw, bitmap, NULL, NULL, paint, SkCanvas::kStrict_SrcRectConstraint);
 }
 
 // This method outsets 'iRect' by 'outset' all around and then clamps its extents to
@@ -903,7 +903,7 @@
                                    const SkRect* srcRectPtr,
                                    const SkSize* dstSizePtr,
                                    const SkPaint& paint,
-                                   SkCanvas::DrawBitmapRectFlags flags) {
+                                   SkCanvas::SrcRectConstraint constraint) {
     CHECK_SHOULD_DRAW(draw);
 
     SkRect srcRect;
@@ -926,7 +926,7 @@
     int height = tex ? tex->height() : bitmap.height();
     if (srcRect.fLeft <= 0 && srcRect.fTop <= 0 &&
         srcRect.fRight >= width && srcRect.fBottom >= height) {
-        flags = (SkCanvas::DrawBitmapRectFlags) (flags | SkCanvas::kBleed_DrawBitmapRectFlag);
+        constraint = SkCanvas::kFast_SrcRectConstraint;
     }
 
     // If the render target is not msaa and draw is antialiased, we call
@@ -976,7 +976,7 @@
             // already accounted for in 'm' and 'srcRect'. In clamp mode we need to chop out
             // the desired portion of the bitmap and then update 'm' and 'srcRect' to
             // compensate.
-            if (!(SkCanvas::kBleed_DrawBitmapRectFlag & flags)) {
+            if (SkCanvas::kStrict_SrcRectConstraint == constraint) {
                 SkIRect iSrc;
                 srcRect.roundOut(&iSrc);
 
@@ -1064,7 +1064,7 @@
     SkIRect clippedSrcRect;
     if (this->shouldTileBitmap(bitmap, viewM, params, srcRectPtr, maxTileSize, &tileSize,
                                &clippedSrcRect)) {
-        this->drawTiledBitmap(bitmap, viewM, srcRect, clippedSrcRect, params, paint, flags,
+        this->drawTiledBitmap(bitmap, viewM, srcRect, clippedSrcRect, params, paint, constraint,
                               tileSize, doBicubic);
     } else {
         // take the simple case
@@ -1078,7 +1078,7 @@
                                  srcRect,
                                  params,
                                  paint,
-                                 flags,
+                                 constraint,
                                  doBicubic,
                                  needsTextureDomain);
     }
@@ -1092,7 +1092,7 @@
                                   const SkIRect& clippedSrcIRect,
                                   const GrTextureParams& params,
                                   const SkPaint& paint,
-                                  SkCanvas::DrawBitmapRectFlags flags,
+                                  SkCanvas::SrcRectConstraint constraint,
                                   int tileSize,
                                   bool bicubic) {
     // The following pixel lock is technically redundant, but it is desirable
@@ -1135,7 +1135,7 @@
             if (GrTextureParams::kNone_FilterMode != params.filterMode() || bicubic) {
                 SkIRect iClampRect;
 
-                if (SkCanvas::kBleed_DrawBitmapRectFlag & flags) {
+                if (SkCanvas::kFast_SrcRectConstraint == constraint) {
                     // In bleed mode we want to always expand the tile on all edges
                     // but stay within the bitmap bounds
                     iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.height());
@@ -1163,7 +1163,7 @@
                                          tileR,
                                          paramsTemp,
                                          paint,
-                                         flags,
+                                         constraint,
                                          bicubic,
                                          needsTextureDomain);
             }
@@ -1184,7 +1184,7 @@
                                      const SkRect& srcRect,
                                      const GrTextureParams& params,
                                      const SkPaint& paint,
-                                     SkCanvas::DrawBitmapRectFlags flags,
+                                     SkCanvas::SrcRectConstraint constraint,
                                      bool bicubic,
                                      bool needsTextureDomain) {
     SkASSERT(bitmap.width() <= fContext->caps()->maxTextureSize() &&
@@ -1212,7 +1212,7 @@
     GrPaint grPaint;
     SkAutoTUnref<GrFragmentProcessor> fp;
 
-    if (needsTextureDomain && !(flags & SkCanvas::kBleed_DrawBitmapRectFlag)) {
+    if (needsTextureDomain && (SkCanvas::kStrict_SrcRectConstraint == constraint)) {
         // Use a constrained texture domain to avoid color bleeding
         SkScalar left, top, right, bottom;
         if (srcRect.width() > SK_Scalar1) {
@@ -1351,7 +1351,9 @@
 void SkGpuDevice::drawBitmapRect(const SkDraw& origDraw, const SkBitmap& bitmap,
                                  const SkRect* src, const SkRect& dst,
                                  const SkPaint& paint,
-                                 SkCanvas::DrawBitmapRectFlags flags) {
+                                 SK_VIRTUAL_CONSTRAINT_TYPE legacyConstraint) {
+    SkCanvas::SrcRectConstraint constraint = (SkCanvas::SrcRectConstraint)legacyConstraint;
+
     SkMatrix    matrix;
     SkRect      bitmapBounds, tmpSrc;
 
@@ -1391,7 +1393,7 @@
     dstSize.fWidth = tmpDst.width();
     dstSize.fHeight = tmpDst.height();
 
-    this->drawBitmapCommon(*draw, bitmap, &tmpSrc, &dstSize, paint, flags);
+    this->drawBitmapCommon(*draw, bitmap, &tmpSrc, &dstSize, paint, constraint);
 }
 
 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
@@ -1512,10 +1514,11 @@
 }
 
 void SkGpuDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
-                                const SkRect& dst, const SkPaint& paint) {
+                                const SkRect& dst, const SkPaint& paint,
+                                SkCanvas::SrcRectConstraint constraint) {
     SkBitmap bm;
     if (wrap_as_bm(image, &bm)) {
-        this->drawBitmapRect(draw, bm, src, dst, paint, SkCanvas::kNone_DrawBitmapRectFlag);
+        this->drawBitmapRect(draw, bm, src, dst, paint, (SK_VIRTUAL_CONSTRAINT_TYPE)constraint);
     }
 }
 
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 8650765..ec3bfbd 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -96,7 +96,7 @@
     virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
                                 const SkRect* srcOrNull, const SkRect& dst,
                                 const SkPaint& paint,
-                                SkCanvas::DrawBitmapRectFlags flags) override;
+                                SK_VIRTUAL_CONSTRAINT_TYPE) override;
     virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
                             int x, int y, const SkPaint& paint) override;
     virtual void drawText(const SkDraw&, const void* text, size_t len,
@@ -117,7 +117,7 @@
                             const SkPaint&) override;
     void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&) override;
     void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst,
-                       const SkPaint&) override;
+                       const SkPaint&, SkCanvas::SrcRectConstraint) override;
 
     void flush() override;
 
@@ -187,7 +187,7 @@
                           const SkRect* srcRectPtr,
                           const SkSize* dstSizePtr,      // ignored iff srcRectPtr == NULL
                           const SkPaint&,
-                          SkCanvas::DrawBitmapRectFlags flags);
+                          SkCanvas::SrcRectConstraint);
 
     /**
      * Helper functions called by drawBitmapCommon. By the time these are called the SkDraw's
@@ -207,7 +207,7 @@
                             const SkRect&,
                             const GrTextureParams& params,
                             const SkPaint& paint,
-                            SkCanvas::DrawBitmapRectFlags flags,
+                            SkCanvas::SrcRectConstraint,
                             bool bicubic,
                             bool needsTextureDomain);
     void drawTiledBitmap(const SkBitmap& bitmap,
@@ -216,7 +216,7 @@
                          const SkIRect& clippedSrcRect,
                          const GrTextureParams& params,
                          const SkPaint& paint,
-                         SkCanvas::DrawBitmapRectFlags flags,
+                         SkCanvas::SrcRectConstraint,
                          int tileSize,
                          bool bicubic);
 
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 422a895..7ca6c22 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -1001,7 +1001,7 @@
 void SkPDFDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
                                  const SkRect* src, const SkRect& dst,
                                  const SkPaint& srcPaint,
-                                 SkCanvas::DrawBitmapRectFlags flags) {
+                                 SK_VIRTUAL_CONSTRAINT_TYPE) {
     SkPaint paint = srcPaint;
     if (bitmap.isOpaque()) {
         replace_srcmode_on_opaque_paint(&paint);
diff --git a/src/pdf/SkPDFDevice.h b/src/pdf/SkPDFDevice.h
index f58e74c..bb12a3f 100644
--- a/src/pdf/SkPDFDevice.h
+++ b/src/pdf/SkPDFDevice.h
@@ -96,7 +96,7 @@
     void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
                         const SkRect* src, const SkRect& dst,
                         const SkPaint& paint,
-                        SkCanvas::DrawBitmapRectFlags flags) override;
+                        SK_VIRTUAL_CONSTRAINT_TYPE) override;
     void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
                     const SkMatrix& matrix, const SkPaint&) override;
     void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
diff --git a/src/pipe/SkGPipePriv.h b/src/pipe/SkGPipePriv.h
index 614853d..c86e6fb 100644
--- a/src/pipe/SkGPipePriv.h
+++ b/src/pipe/SkGPipePriv.h
@@ -42,7 +42,7 @@
     kDrawAtlas_DrawOp,
     kDrawBitmap_DrawOp,
     kDrawBitmapNine_DrawOp,
-    kDrawBitmapRectToRect_DrawOp,
+    kDrawBitmapRect_DrawOp,
     kDrawDRRect_DrawOp,
     kDrawImage_DrawOp,
     kDrawImageRect_DrawOp,
diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp
index 48e0c06..ef1eeb3 100644
--- a/src/pipe/SkGPipeRead.cpp
+++ b/src/pipe/SkGPipeRead.cpp
@@ -643,15 +643,14 @@
     } else {
         src = NULL;
     }
-    SkCanvas::DrawBitmapRectFlags dbmrFlags = SkCanvas::kNone_DrawBitmapRectFlag;
+    SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint;
     if (flags & kDrawBitmap_Bleed_DrawOpFlag) {
-        dbmrFlags = (SkCanvas::DrawBitmapRectFlags)(dbmrFlags|SkCanvas::kBleed_DrawBitmapRectFlag);
+        constraint = SkCanvas::kFast_SrcRectConstraint;
     }
     const SkRect* dst = skip<SkRect>(reader);
     const SkBitmap* bitmap = holder.getBitmap();
     if (state->shouldDraw()) {
-        canvas->drawBitmapRectToRect(*bitmap, src, *dst,
-                                     hasPaint ? &state->paint() : NULL, dbmrFlags);
+        canvas->drawBitmapRect(*bitmap, src, *dst, hasPaint ? &state->paint() : NULL, constraint);
     }
 }
 
@@ -689,9 +688,11 @@
         src = skip<SkRect>(reader);
     }
     const SkRect* dst = skip<SkRect>(reader);
+    SkCanvas::SrcRectConstraint constraint = (SkCanvas::SrcRectConstraint)reader->readInt();
+
     const SkImage* image = state->getImage(slot);
     if (state->shouldDraw()) {
-        canvas->drawImageRect(image, src, *dst, hasPaint ? &state->paint() : NULL);
+        canvas->drawImageRect(image, src, *dst, hasPaint ? &state->paint() : NULL, constraint);
     }
 }
 
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index 4dbb5b5..60a63b0 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -276,10 +276,10 @@
     void onDrawPath(const SkPath&, const SkPaint&) override;
     void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override;
     void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*,
-                          DrawBitmapRectFlags flags) override;
+                          SK_VIRTUAL_CONSTRAINT_TYPE) override;
     void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override;
     void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
-                         const SkPaint*) override;
+                         const SkPaint* SRC_RECT_CONSTRAINT_PARAM(constraint)) override;
     void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
                          const SkPaint*) override;
     void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
@@ -791,7 +791,10 @@
 }
 
 void SkGPipeCanvas::onDrawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst,
-                                     const SkPaint* paint, DrawBitmapRectFlags dbmrFlags) {
+                                     const SkPaint* paint,
+                                     SK_VIRTUAL_CONSTRAINT_TYPE legacyConstraint) {
+    SrcRectConstraint constraint = (SrcRectConstraint)legacyConstraint;
+
     NOTIFY_SETUP(this);
     size_t opBytesNeeded = sizeof(SkRect);
     bool hasSrc = src != NULL;
@@ -802,11 +805,11 @@
     } else {
         flags = 0;
     }
-    if (dbmrFlags & kBleed_DrawBitmapRectFlag) {
+    if (kFast_SrcRectConstraint == constraint) {
         flags |= kDrawBitmap_Bleed_DrawOpFlag;
     }
 
-    if (this->commonDrawBitmap(bm, kDrawBitmapRectToRect_DrawOp, flags, opBytesNeeded, paint)) {
+    if (this->commonDrawBitmap(bm, kDrawBitmapRect_DrawOp, flags, opBytesNeeded, paint)) {
         if (hasSrc) {
             fWriter.writeRect(*src);
         }
@@ -869,8 +872,10 @@
 }
 
 void SkGPipeCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
-                                    const SkPaint* paint) {
+                                    const SkPaint* paint SRC_RECT_CONSTRAINT_PARAM(constraint)) {
     NOTIFY_SETUP(this);
+
+    SRC_RECT_CONSTRAINT_LOCAL_DEFAULT(constraint)
     unsigned flags = 0;
     size_t opBytesNeeded = sizeof(SkRect);  // dst
     if (src) {
@@ -882,6 +887,7 @@
             fWriter.writeRect(*src);
         }
         fWriter.writeRect(dst);
+        fWriter.writeInt(constraint);
     }
 }
 
diff --git a/src/svg/SkSVGDevice.cpp b/src/svg/SkSVGDevice.cpp
index 6038353..af565a0 100644
--- a/src/svg/SkSVGDevice.cpp
+++ b/src/svg/SkSVGDevice.cpp
@@ -716,7 +716,7 @@
 
 void SkSVGDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bm, const SkRect* srcOrNull,
                                  const SkRect& dst, const SkPaint& paint,
-                                 SkCanvas::DrawBitmapRectFlags) {
+                                 SK_VIRTUAL_CONSTRAINT_TYPE) {
     SkMatrix adjustedMatrix;
     adjustedMatrix.setRectToRect(srcOrNull ? *srcOrNull : SkRect::Make(bm.bounds()),
                                  dst,
diff --git a/src/svg/SkSVGDevice.h b/src/svg/SkSVGDevice.h
index e3691a9..58fb5d4 100644
--- a/src/svg/SkSVGDevice.h
+++ b/src/svg/SkSVGDevice.h
@@ -37,7 +37,7 @@
     void drawBitmapRect(const SkDraw&, const SkBitmap&,
                         const SkRect* srcOrNull, const SkRect& dst,
                         const SkPaint& paint,
-                        SkCanvas::DrawBitmapRectFlags flags) override;
+                        SK_VIRTUAL_CONSTRAINT_TYPE) override;
 
     void drawText(const SkDraw&, const void* text, size_t len,
                   SkScalar x, SkScalar y, const SkPaint& paint) override;
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index 8e34235..343d0c4 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -219,7 +219,7 @@
         {SkASSERT(0);}
     void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*,
                         const SkRect&, const SkPaint&,
-                        SkCanvas::DrawBitmapRectFlags) override
+                        SK_VIRTUAL_CONSTRAINT_TYPE) override
         {SkASSERT(0);}
     void drawSprite(const SkDraw&, const SkBitmap& bitmap,
                     int x, int y, const SkPaint& paint) override
@@ -227,7 +227,7 @@
     void drawImage(const SkDraw&, const SkImage*, SkScalar, SkScalar, const SkPaint&) override
         {SkASSERT(0);}
     void drawImageRect(const SkDraw&, const SkImage*, const SkRect*, const SkRect&,
-                       const SkPaint&) override
+                       const SkPaint&, SkCanvas::SrcRectConstraint) override
         {SkASSERT(0);}
     void drawImageNine(const SkDraw&, const SkImage*, const SkIRect&, const SkRect&,
                        const SkPaint&) override
@@ -865,8 +865,8 @@
 }
 
 void SkDeferredCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
-                                        const SkRect& dst,
-                                        const SkPaint* paint, DrawBitmapRectFlags flags) {
+                                        const SkRect& dst, const SkPaint* paint,
+                                        SK_VIRTUAL_CONSTRAINT_TYPE constraint) {
     if (fDeferredDrawing &&
         this->isFullFrame(&dst, paint) &&
         isPaintOpaque(paint, &bitmap)) {
@@ -874,7 +874,7 @@
     }
 
     AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
-    this->drawingCanvas()->drawBitmapRectToRect(bitmap, src, dst, paint, flags);
+    this->drawingCanvas()->drawBitmapRect(bitmap, src, dst, paint, (SrcRectConstraint)constraint);
     this->recordedDrawCommand();
 }
 
@@ -894,7 +894,7 @@
     this->recordedDrawCommand();
 }
 void SkDeferredCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
-                                       const SkPaint* paint) {
+                                       const SkPaint* paint SRC_RECT_CONSTRAINT_PARAM(constraint)) {
     if (fDeferredDrawing &&
         this->isFullFrame(&dst, paint) &&
         isPaintOpaque(paint, image)) {
@@ -902,7 +902,8 @@
     }
     
     AutoImmediateDrawIfNeeded autoDraw(*this, image, paint);
-    this->drawingCanvas()->drawImageRect(image, src, dst, paint);
+    this->drawingCanvas()->drawImageRect(image, src, dst, paint
+                                         SRC_RECT_CONSTRAINT_ARG(constraint));
     this->recordedDrawCommand();
 }
 
diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp
index 5cbf2f4..e20aea4 100644
--- a/src/utils/SkDumpCanvas.cpp
+++ b/src/utils/SkDumpCanvas.cpp
@@ -346,7 +346,7 @@
 }
 
 void SkDumpCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
-                                    const SkPaint* paint, DrawBitmapRectFlags flags) {
+                                    const SkPaint* paint, SK_VIRTUAL_CONSTRAINT_TYPE) {
     SkString bs, rs;
     bitmap.toString(&bs);
     toString(dst, &rs);
@@ -359,8 +359,7 @@
         rs.prependf("%s ", ss.c_str());
     }
 
-    this->dump(kDrawBitmap_Verb, paint, "drawBitmapRectToRect(%s %s)",
-               bs.c_str(), rs.c_str());
+    this->dump(kDrawBitmap_Verb, paint, "drawBitmapRect(%s %s)", bs.c_str(), rs.c_str());
 }
 
 void SkDumpCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
@@ -381,7 +380,7 @@
 }
 
 void SkDumpCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
-                                   const SkPaint* paint) {
+                                   const SkPaint* paint SRC_RECT_CONSTRAINT_PARAM(constraint)) {
     SkString bs, rs;
     image->toString(&bs);
     toString(dst, &rs);
diff --git a/src/utils/SkLuaCanvas.cpp b/src/utils/SkLuaCanvas.cpp
index 68094f2..b892131 100644
--- a/src/utils/SkLuaCanvas.cpp
+++ b/src/utils/SkLuaCanvas.cpp
@@ -215,7 +215,7 @@
 }
 
 void SkLuaCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
-                                   const SkPaint* paint, DrawBitmapRectFlags flags) {
+                                   const SkPaint* paint, SK_VIRTUAL_CONSTRAINT_TYPE) {
     AUTO_LUA("drawBitmapRect");
     if (paint) {
         lua.pushPaint(*paint, "paint");
@@ -238,7 +238,7 @@
 }
 
 void SkLuaCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
-                                  const SkPaint* paint) {
+                                  const SkPaint* paint SRC_RECT_CONSTRAINT_PARAM(constraint)) {
     AUTO_LUA("drawImageRect");
     if (paint) {
         lua.pushPaint(*paint, "paint");
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index 8ae8422..706c769 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -170,8 +170,7 @@
     }
 }
 
-void SkNWayCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
-                                const SkPaint& paint) {
+void SkNWayCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
     Iter iter(fList);
     while (iter.next()) {
         iter->drawDRRect(outer, inner, paint);
@@ -194,10 +193,10 @@
 }
 
 void SkNWayCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
-                                    const SkPaint* paint, DrawBitmapRectFlags flags) {
+                                    const SkPaint* paint, SK_VIRTUAL_CONSTRAINT_TYPE constraint) {
     Iter iter(fList);
     while (iter.next()) {
-        iter->drawBitmapRectToRect(bitmap, src, dst, paint, flags);
+        iter->drawBitmapRect(bitmap, src, dst, paint, (SrcRectConstraint)constraint);
     }
 }
 
@@ -218,10 +217,10 @@
 }
 
 void SkNWayCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
-                                   const SkPaint* paint) {
+                                   const SkPaint* paint SRC_RECT_CONSTRAINT_PARAM(constraint)) {
     Iter iter(fList);
     while (iter.next()) {
-        iter->drawImageRect(image, src, dst, paint);
+        iter->drawImageRect(image, src, dst, paint SRC_RECT_CONSTRAINT_ARG(constraint));
     }
 }
 
diff --git a/src/utils/SkPaintFilterCanvas.cpp b/src/utils/SkPaintFilterCanvas.cpp
index 1abebef..3e589e6 100644
--- a/src/utils/SkPaintFilterCanvas.cpp
+++ b/src/utils/SkPaintFilterCanvas.cpp
@@ -74,9 +74,10 @@
 }
 
 void SkPaintFilterCanvas::onDrawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst,
-                                           const SkPaint* paint, DrawBitmapRectFlags flags) {
+                                           const SkPaint* paint,
+                                           SK_VIRTUAL_CONSTRAINT_TYPE constraint) {
     AutoPaintFilter apf(this, kBitmap_Type, paint);
-    this->INHERITED::onDrawBitmapRect(bm, src, dst, apf.paint(), flags);
+    this->INHERITED::onDrawBitmapRect(bm, src, dst, apf.paint(), constraint);
 }
 
 void SkPaintFilterCanvas::onDrawImage(const SkImage* image, SkScalar left, SkScalar top,
@@ -86,9 +87,11 @@
 }
 
 void SkPaintFilterCanvas::onDrawImageRect(const SkImage* image, const SkRect* src,
-                                          const SkRect& dst, const SkPaint* paint) {
+                                          const SkRect& dst, const SkPaint* paint
+                                          SRC_RECT_CONSTRAINT_PARAM(constraint)) {
     AutoPaintFilter apf(this, kBitmap_Type, paint);
-    this->INHERITED::onDrawImageRect(image, src, dst, apf.paint());
+    this->INHERITED::onDrawImageRect(image, src, dst, apf.paint()
+                                     SRC_RECT_CONSTRAINT_ARG(constraint));
 }
 
 void SkPaintFilterCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center,
diff --git a/src/utils/android/SkAndroidSDKCanvas.cpp b/src/utils/android/SkAndroidSDKCanvas.cpp
index 26baaf2..2f98891 100644
--- a/src/utils/android/SkAndroidSDKCanvas.cpp
+++ b/src/utils/android/SkAndroidSDKCanvas.cpp
@@ -143,9 +143,10 @@
                                                    const SkRect* src,
                                                    const SkRect& dst,
                                                    const SkPaint* paint,
-                                                   DrawBitmapRectFlags flags) {
+                                                   SK_VIRTUAL_CONSTRAINT_TYPE constraint) {
     FILTER_PTR(paint);
-    fProxyTarget->drawBitmapRectToRect(bitmap, src, dst, filteredPaint, flags);
+    fProxyTarget->drawBitmapRect(bitmap, src, dst, filteredPaint,
+                                 (SrcRectConstraint)constraint);
 }
 void SkAndroidSDKCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
                                                    const SkIRect& center,
diff --git a/src/utils/android/SkAndroidSDKCanvas.h b/src/utils/android/SkAndroidSDKCanvas.h
index a54315d..d22931d 100644
--- a/src/utils/android/SkAndroidSDKCanvas.h
+++ b/src/utils/android/SkAndroidSDKCanvas.h
@@ -43,7 +43,7 @@
     void onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
                       const SkPaint* paint) override;
     void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
-                          const SkPaint* paint, DrawBitmapRectFlags flags) override;
+                          const SkPaint* paint, SK_VIRTUAL_CONSTRAINT_TYPE) override;
     void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
                           const SkRect& dst, const SkPaint* paint) override;
     void onDrawSprite(const SkBitmap& bitmap, int left, int top,
diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp
index 3c166b7..00923db 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -415,8 +415,9 @@
 }
 
 void SkDebugCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
-                                     const SkPaint* paint, DrawBitmapRectFlags flags) {
-    this->addDrawCommand(new SkDrawBitmapRectCommand(bitmap, src, dst, paint, flags));
+                                     const SkPaint* paint, SK_VIRTUAL_CONSTRAINT_TYPE constraint) {
+    this->addDrawCommand(new SkDrawBitmapRectCommand(bitmap, src, dst, paint,
+                                                     (SrcRectConstraint)constraint));
 }
 
 void SkDebugCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
@@ -430,7 +431,7 @@
 }
 
 void SkDebugCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
-                                    const SkPaint* paint) {
+                                    const SkPaint* paint SRC_RECT_CONSTRAINT_PARAM(constraint)) {
     SkDebugf("SkDebugCanvas::onDrawImageRect unimplemented\n");
 }
 
diff --git a/src/utils/debugger/SkDebugCanvas.h b/src/utils/debugger/SkDebugCanvas.h
index ceaaa78..4f5f226 100644
--- a/src/utils/debugger/SkDebugCanvas.h
+++ b/src/utils/debugger/SkDebugCanvas.h
@@ -198,10 +198,10 @@
     void onDrawPath(const SkPath&, const SkPaint&) override;
     void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override;
     void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*,
-                          DrawBitmapRectFlags flags) override;
+                          SK_VIRTUAL_CONSTRAINT_TYPE) override;
     void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override;
     void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
-                         const SkPaint*) override;
+                         const SkPaint* SRC_RECT_CONSTRAINT_PARAM(constraint)) override;
     void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
                           const SkPaint*) override;
     void onDrawSprite(const SkBitmap&, int left, int top, const SkPaint*) override;
diff --git a/src/utils/debugger/SkDrawCommand.cpp b/src/utils/debugger/SkDrawCommand.cpp
index 7e2af08..5f0f74f 100644
--- a/src/utils/debugger/SkDrawCommand.cpp
+++ b/src/utils/debugger/SkDrawCommand.cpp
@@ -320,7 +320,7 @@
 
 SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
                                                  const SkRect& dst, const SkPaint* paint,
-                                                 SkCanvas::DrawBitmapRectFlags flags)
+                                                 SkCanvas::SrcRectConstraint constraint)
     : INHERITED(kDrawBitmapRect_OpType) {
     fBitmap = bitmap;
     if (src) {
@@ -336,7 +336,7 @@
     } else {
         fPaintPtr = NULL;
     }
-    fFlags = flags;
+    fConstraint = constraint;
 
     fInfo.push(SkObjectParser::BitmapToString(bitmap));
     if (src) {
@@ -346,11 +346,11 @@
     if (paint) {
         fInfo.push(SkObjectParser::PaintToString(*paint));
     }
-    fInfo.push(SkObjectParser::IntToString(fFlags, "Flags: "));
+    fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
 }
 
 void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
-    canvas->drawBitmapRectToRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fFlags);
+    canvas->drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint);
 }
 
 bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
diff --git a/src/utils/debugger/SkDrawCommand.h b/src/utils/debugger/SkDrawCommand.h
index 307599f..99e3eea 100644
--- a/src/utils/debugger/SkDrawCommand.h
+++ b/src/utils/debugger/SkDrawCommand.h
@@ -229,7 +229,7 @@
 public:
     SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
                             const SkRect& dst, const SkPaint* paint,
-                            SkCanvas::DrawBitmapRectFlags flags);
+                            SkCanvas::SrcRectConstraint);
     void execute(SkCanvas* canvas) const override;
     bool render(SkCanvas* canvas) const override;
 
@@ -250,8 +250,8 @@
     const SkRect& dstRect() const { return fDst; }
     void setDstRect(const SkRect& dst) { fDst = dst; }
 
-    SkCanvas::DrawBitmapRectFlags flags() const { return fFlags; }
-    void setFlags(SkCanvas::DrawBitmapRectFlags flags) { fFlags = flags; }
+    SkCanvas::SrcRectConstraint constraint() const { return fConstraint; }
+    void setConstraint(SkCanvas::SrcRectConstraint constraint) { fConstraint = constraint; }
 
 private:
     SkBitmap                      fBitmap;
@@ -259,7 +259,7 @@
     SkRect                        fDst;
     SkPaint                       fPaint;
     SkPaint*                      fPaintPtr;
-    SkCanvas::DrawBitmapRectFlags fFlags;
+    SkCanvas::SrcRectConstraint   fConstraint;
 
     typedef SkDrawCommand INHERITED;
 };