drawBitmap() support for extractSubset()

In SkiaCanvasProxy, translate drawBitmap() calls on bitmaps which
are the result of extractSubset() into drawBitmapRect() calls on the
original PixelRef.

If HWUI isn't going to support subsetting, we'll need to do this,
probably at additional entry points, to interoperate with native Skia
bitmaps. This change by itself fixes the extractbitmap GM.

R=djsollen@google.com
BUG=skia:3606

Change-Id: I5744da87d8f16dc1a252f606dfaa4016bd01e66e
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index 8a6c8c5..295ec4b 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -18,6 +18,7 @@
 
 #include <cutils/log.h>
 #include <SkPatchUtils.h>
+#include <SkPixelRef.h>
 
 namespace android {
 namespace uirenderer {
@@ -96,12 +97,31 @@
 
 void SkiaCanvasProxy::onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
         const SkPaint* paint) {
-    mCanvas->drawBitmap(bitmap, left, top, paint);
+    SkPixelRef* pxRef = bitmap.pixelRef();
+
+    // HWUI doesn't support extractSubset(), so convert any subsetted bitmap into
+    // a drawBitmapRect(); pass through an un-subsetted bitmap.
+    if (pxRef && bitmap.dimensions() != pxRef->info().dimensions()) {
+        SkBitmap fullBitmap;
+        fullBitmap.setInfo(pxRef->info());
+        fullBitmap.setPixelRef(pxRef, 0, 0);
+        SkIPoint origin = bitmap.pixelRefOrigin();
+        mCanvas->drawBitmap(fullBitmap, origin.fX, origin.fY,
+                            origin.fX + bitmap.dimensions().width(),
+                            origin.fY + bitmap.dimensions().height(),
+                            left, top,
+                            left + bitmap.dimensions().width(),
+                            top + bitmap.dimensions().height(),
+                            paint);
+    } else {
+        mCanvas->drawBitmap(bitmap, left, top, paint);
+    }
 }
 
 void SkiaCanvasProxy::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* srcPtr,
         const SkRect& dst, const SkPaint* paint, DrawBitmapRectFlags) {
     SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(bitmap.width(), bitmap.height());
+    // TODO: if bitmap is a subset, do we need to add pixelRefOrigin to src?
     mCanvas->drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
                         dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint);
 }
@@ -114,6 +134,7 @@
 
 void SkiaCanvasProxy::onDrawSprite(const SkBitmap& bitmap, int left, int top,
         const SkPaint* paint) {
+    // TODO: if bitmap is a subset, do we need to add pixelRefOrigin to src?
     mCanvas->save(SkCanvas::kMatrixClip_SaveFlag);
     mCanvas->setMatrix(SkMatrix::I());
     mCanvas->drawBitmap(bitmap, left, top, paint);