A bunch more cleanups

Switch a few places to using android::canvas
instead of SkCanvas as well which eliminated
some JNI

Change-Id: I8f98b56442a06362b82b984cd1bd3a92398d8dbc
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 87d5d9a..5017a38 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -360,7 +360,7 @@
     @Override
     boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
         return nCopyLayerInto(mNativeProxy,
-                layer.getDeferredLayerUpdater(), bitmap.getSkBitmap());
+                layer.getDeferredLayerUpdater(), bitmap);
     }
 
     @Override
@@ -531,7 +531,7 @@
 
     private static native long nCreateTextureLayer(long nativeProxy);
     private static native void nBuildLayer(long nativeProxy, long node);
-    private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap);
+    private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
     private static native void nPushLayerUpdate(long nativeProxy, long layer);
     private static native void nCancelLayerUpdate(long nativeProxy, long layer);
     private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index f0bd5dd..f0bd8d1 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -373,7 +373,7 @@
     return legacyBitmapConfigToColorType(c);
 }
 
-SkCanvas* GraphicsJNI::getNativeCanvas(JNIEnv* env, jobject canvas) {
+android::Canvas* GraphicsJNI::getNativeCanvas(JNIEnv* env, jobject canvas) {
     SkASSERT(env);
     SkASSERT(canvas);
     SkASSERT(env->IsInstanceOf(canvas, gCanvas_class));
@@ -381,9 +381,7 @@
     if (!canvasHandle) {
         return NULL;
     }
-    SkCanvas* c = reinterpret_cast<android::Canvas*>(canvasHandle)->asSkCanvas();
-    SkASSERT(c);
-    return c;
+    return reinterpret_cast<android::Canvas*>(canvasHandle);
 }
 
 SkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region)
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 49def13..8eb43f8 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -8,6 +8,7 @@
 #include "SkPoint.h"
 #include "SkRect.h"
 #include "SkImageDecoder.h"
+#include <Canvas.h>
 #include <jni.h>
 
 class SkBitmapRegionDecoder;
@@ -47,7 +48,7 @@
     static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point);
     static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
 
-    static SkCanvas* getNativeCanvas(JNIEnv*, jobject canvas);
+    static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
     static SkBitmap* getSkBitmapDeprecated(JNIEnv*, jobject bitmap);
     static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap);
     static SkPixelRef* getSkPixelRef(JNIEnv*, jobject bitmap);
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 6591d29..d0f7591 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -80,11 +80,12 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong bitmapHandle,
+static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jobject jbitmap,
                                       jint tileModeX, jint tileModeY)
 {
-    const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
-    SkShader* s = SkShader::CreateBitmapShader(*bitmap,
+    SkBitmap bitmap;
+    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    SkShader* s = SkShader::CreateBitmapShader(bitmap,
                                         (SkShader::TileMode)tileModeX,
                                         (SkShader::TileMode)tileModeY);
 
@@ -249,7 +250,7 @@
 };
 
 static JNINativeMethod gBitmapShaderMethods[] = {
-    { "nativeCreate",     "(JII)J",  (void*)BitmapShader_constructor },
+    { "nativeCreate",     "(Landroid/graphics/Bitmap;II)J",  (void*)BitmapShader_constructor },
 };
 
 static JNINativeMethod gLinearGradientMethods[] = {
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index a2c1609..50a1069 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -39,17 +39,22 @@
 }
 
 // Native wrapper constructor used by Canvas(Bitmap)
-static jlong initRaster(JNIEnv* env, jobject, jlong bitmapHandle) {
-    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
+static jlong initRaster(JNIEnv* env, jobject, jobject jbitmap) {
+    SkBitmap bitmap;
+    if (jbitmap != NULL) {
+        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    }
     return reinterpret_cast<jlong>(Canvas::create_canvas(bitmap));
 }
 
 // Set the given bitmap as the new draw target (wrapped in a new SkCanvas),
 // optionally copying canvas matrix & clip state.
-static void setBitmap(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
-                      jboolean copyState) {
-    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
-    get_canvas(canvasHandle)->setBitmap(bitmap, copyState);
+static void setBitmap(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap) {
+    SkBitmap bitmap;
+    if (jbitmap != NULL) {
+        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    }
+    get_canvas(canvasHandle)->setBitmap(bitmap);
 }
 
 static jboolean isOpaque(JNIEnv*, jobject, jlong canvasHandle) {
@@ -658,8 +663,8 @@
 
 static JNINativeMethod gMethods[] = {
     {"finalizer", "(J)V", (void*) CanvasJNI::finalizer},
-    {"initRaster", "(J)J", (void*) CanvasJNI::initRaster},
-    {"native_setBitmap", "(JJZ)V", (void*) CanvasJNI::setBitmap},
+    {"initRaster", "(Landroid/graphics/Bitmap;)J", (void*) CanvasJNI::initRaster},
+    {"native_setBitmap", "(JLandroid/graphics/Bitmap;)V", (void*) CanvasJNI::setBitmap},
     {"native_isOpaque","(J)Z", (void*) CanvasJNI::isOpaque},
     {"native_getWidth","(J)I", (void*) CanvasJNI::getWidth},
     {"native_getHeight","(J)I", (void*) CanvasJNI::getHeight},
diff --git a/core/jni/android_view_GraphicBuffer.cpp b/core/jni/android_view_GraphicBuffer.cpp
index a12629f..aa79d70 100644
--- a/core/jni/android_view_GraphicBuffer.cpp
+++ b/core/jni/android_view_GraphicBuffer.cpp
@@ -67,11 +67,6 @@
     jfieldID bottom;
 } gRectClassInfo;
 
-static struct {
-    jfieldID mSurfaceFormat;
-    jmethodID setNativeBitmap;
-} gCanvasClassInfo;
-
 #define GET_INT(object, field) \
     env->GetIntField(object, field)
 
@@ -196,13 +191,9 @@
         bitmap.setPixels(NULL);
     }
 
-    SET_INT(canvas, gCanvasClassInfo.mSurfaceFormat, buffer->getPixelFormat());
-    INVOKEV(canvas, gCanvasClassInfo.setNativeBitmap, reinterpret_cast<jlong>(&bitmap));
-
-    SkRect clipRect;
-    clipRect.set(rect.left, rect.top, rect.right, rect.bottom);
-    SkCanvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas);
-    nativeCanvas->clipRect(clipRect);
+    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas);
+    nativeCanvas->setBitmap(bitmap);
+    nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom);
 
     if (dirtyRect) {
         INVOKEV(dirtyRect, gRectClassInfo.set,
@@ -217,7 +208,8 @@
 
     GraphicBufferWrapper* wrapper =
                 reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle);
-    INVOKEV(canvas, gCanvasClassInfo.setNativeBitmap, (jlong)0);
+    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas);
+    nativeCanvas->setBitmap(SkBitmap());
 
     if (wrapper) {
         status_t status = wrapper->buffer->unlock();
@@ -302,10 +294,6 @@
     gRectClassInfo.right = GetFieldIDOrDie(env, clazz, "right", "I");
     gRectClassInfo.bottom = GetFieldIDOrDie(env, clazz, "bottom", "I");
 
-    clazz = FindClassOrDie(env, "android/graphics/Canvas");
-    gCanvasClassInfo.mSurfaceFormat = GetFieldIDOrDie(env, clazz, "mSurfaceFormat", "I");
-    gCanvasClassInfo.setNativeBitmap = GetMethodIDOrDie(env, clazz, "setNativeBitmap", "(J)V");
-
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index f1c90ea..06d1e85 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -74,11 +74,6 @@
     jfieldID bottom;
 } gRectClassInfo;
 
-static struct {
-    jfieldID mSurfaceFormat;
-    jmethodID setNativeBitmap;
-} gCanvasClassInfo;
-
 // ----------------------------------------------------------------------------
 
 // this is just a pointer we use to pass to inc/decStrong
@@ -319,9 +314,6 @@
         return 0;
     }
 
-    // Associate a SkCanvas object to this surface
-    env->SetIntField(canvasObj, gCanvasClassInfo.mSurfaceFormat, outBuffer.format);
-
     SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
                                          convertPixelFormat(outBuffer.format),
                                          kPremul_SkAlphaType);
@@ -339,12 +331,12 @@
         bitmap.setPixels(NULL);
     }
 
-    env->CallVoidMethod(canvasObj, gCanvasClassInfo.setNativeBitmap,
-                        reinterpret_cast<jlong>(&bitmap));
+    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
+    nativeCanvas->setBitmap(bitmap);
 
     if (dirtyRectPtr) {
-        SkCanvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
-        nativeCanvas->clipRect( SkRect::Make(reinterpret_cast<const SkIRect&>(dirtyRect)) );
+        nativeCanvas->clipRect(dirtyRect.left, dirtyRect.top,
+                dirtyRect.right, dirtyRect.bottom);
     }
 
     if (dirtyRectObj) {
@@ -370,7 +362,8 @@
     }
 
     // detach the canvas from the surface
-    env->CallVoidMethod(canvasObj, gCanvasClassInfo.setNativeBitmap, (jlong)0);
+    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
+    nativeCanvas->setBitmap(SkBitmap());
 
     // unlock surface
     status_t err = surface->unlockAndPost();
@@ -565,10 +558,6 @@
             gSurfaceClassInfo.clazz, "mLock", "Ljava/lang/Object;");
     gSurfaceClassInfo.ctor = GetMethodIDOrDie(env, gSurfaceClassInfo.clazz, "<init>", "(J)V");
 
-    clazz = FindClassOrDie(env, "android/graphics/Canvas");
-    gCanvasClassInfo.mSurfaceFormat = GetFieldIDOrDie(env, clazz, "mSurfaceFormat", "I");
-    gCanvasClassInfo.setNativeBitmap = GetMethodIDOrDie(env, clazz, "setNativeBitmap", "(J)V");
-
     clazz = FindClassOrDie(env, "android/graphics/Rect");
     gRectClassInfo.left = GetFieldIDOrDie(env, clazz, "left", "I");
     gRectClassInfo.top = GetFieldIDOrDie(env, clazz, "top", "I");
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index c2bd0b3c4..7e05793 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -48,11 +48,6 @@
 } gRectClassInfo;
 
 static struct {
-    jfieldID mSurfaceFormat;
-    jmethodID setNativeBitmap;
-} gCanvasClassInfo;
-
-static struct {
     jfieldID nativeWindow;
 } gTextureViewClassInfo;
 
@@ -172,13 +167,9 @@
         bitmap.setPixels(NULL);
     }
 
-    SET_INT(canvas, gCanvasClassInfo.mSurfaceFormat, buffer.format);
-    INVOKEV(canvas, gCanvasClassInfo.setNativeBitmap, reinterpret_cast<jlong>(&bitmap));
-
-    SkRect clipRect;
-    clipRect.set(rect.left, rect.top, rect.right, rect.bottom);
-    SkCanvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas);
-    nativeCanvas->clipRect(clipRect);
+    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas);
+    nativeCanvas->setBitmap(bitmap);
+    nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom);
 
     if (dirtyRect) {
         INVOKEV(dirtyRect, gRectClassInfo.set,
@@ -191,7 +182,8 @@
 static void android_view_TextureView_unlockCanvasAndPost(JNIEnv* env, jobject,
         jlong nativeWindow, jobject canvas) {
 
-    INVOKEV(canvas, gCanvasClassInfo.setNativeBitmap, (jlong)0);
+    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas);
+    nativeCanvas->setBitmap(SkBitmap());
 
     if (nativeWindow) {
         sp<ANativeWindow> window((ANativeWindow*) nativeWindow);
@@ -225,10 +217,6 @@
     gRectClassInfo.right = GetFieldIDOrDie(env, clazz, "right", "I");
     gRectClassInfo.bottom = GetFieldIDOrDie(env, clazz, "bottom", "I");
 
-    clazz = FindClassOrDie(env, "android/graphics/Canvas");
-    gCanvasClassInfo.mSurfaceFormat = GetFieldIDOrDie(env, clazz, "mSurfaceFormat", "I");
-    gCanvasClassInfo.setNativeBitmap = GetMethodIDOrDie(env, clazz, "setNativeBitmap", "(J)V");
-
     clazz = FindClassOrDie(env, "android/view/TextureView");
     gTextureViewClassInfo.nativeWindow = GetFieldIDOrDie(env, clazz, "mNativeWindow", "J");
 
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 11b3805..4ccbb41 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -21,6 +21,7 @@
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
 #include "core_jni_helpers.h"
+#include <GraphicsJNI.h>
 #include <ScopedPrimitiveArray.h>
 
 #include <EGL/egl.h>
@@ -347,10 +348,11 @@
 }
 
 static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
-        jlong proxyPtr, jlong layerPtr, jlong bitmapPtr) {
+        jlong proxyPtr, jlong layerPtr, jobject jbitmap) {
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
-    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
+    SkBitmap bitmap;
+    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
     return proxy->copyLayerInto(layer, bitmap);
 }
 
@@ -458,7 +460,7 @@
     { "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
     { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
     { "nBuildLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_buildLayer },
-    { "nCopyLayerInto", "(JJJ)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
+    { "nCopyLayerInto", "(JJLandroid/graphics/Bitmap;)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
     { "nPushLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_pushLayerUpdate },
     { "nCancelLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_cancelLayerUpdate },
     { "nDetachSurfaceTexture", "(JJ)V", (void*) android_view_ThreadedRenderer_detachSurfaceTexture },
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index f2f890e..bd74bc8 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -42,8 +42,7 @@
         mBitmap = bitmap;
         mTileX = tileX;
         mTileY = tileY;
-        final long b = bitmap.getSkBitmap();
-        init(nativeCreate(b, tileX.nativeInt, tileY.nativeInt));
+        init(nativeCreate(bitmap, tileX.nativeInt, tileY.nativeInt));
     }
 
     /**
@@ -56,6 +55,6 @@
         return copy;
     }
 
-    private static native long nativeCreate(long native_bitmap, int shaderTileModeX,
+    private static native long nativeCreate(Bitmap bitmap, int shaderTileModeX,
             int shaderTileModeY);
 }
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 48afcbf..2acb8ba 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -81,10 +81,6 @@
      */
     protected int mScreenDensity = Bitmap.DENSITY_NONE;
 
-    // Used by native code
-    @SuppressWarnings("UnusedDeclaration")
-    private int mSurfaceFormat;
-
     /**
      * Flag for drawTextRun indicating left-to-right run direction.
      * @hide
@@ -137,7 +133,7 @@
     public Canvas() {
         if (!isHardwareAccelerated()) {
             // 0 means no native bitmap
-            mNativeCanvasWrapper = initRaster(0);
+            mNativeCanvasWrapper = initRaster(null);
             mFinalizer = new CanvasFinalizer(mNativeCanvasWrapper);
         } else {
             mFinalizer = null;
@@ -158,7 +154,7 @@
             throw new IllegalStateException("Immutable bitmap passed to Canvas constructor");
         }
         throwIfCannotDraw(bitmap);
-        mNativeCanvasWrapper = initRaster(bitmap.getSkBitmap());
+        mNativeCanvasWrapper = initRaster(bitmap);
         mFinalizer = new CanvasFinalizer(mNativeCanvasWrapper);
         mBitmap = bitmap;
         mDensity = bitmap.mDensity;
@@ -215,7 +211,7 @@
         }
 
         if (bitmap == null) {
-            native_setBitmap(mNativeCanvasWrapper, 0, false);
+            native_setBitmap(mNativeCanvasWrapper, null);
             mDensity = Bitmap.DENSITY_NONE;
         } else {
             if (!bitmap.isMutable()) {
@@ -223,7 +219,7 @@
             }
             throwIfCannotDraw(bitmap);
 
-            native_setBitmap(mNativeCanvasWrapper, bitmap.getSkBitmap(), true);
+            native_setBitmap(mNativeCanvasWrapper, bitmap);
             mDensity = bitmap.mDensity;
         }
 
@@ -231,13 +227,6 @@
     }
 
     /**
-     * setBitmap() variant for native callers with a raw bitmap handle.
-     */
-    private void setNativeBitmap(long bitmapHandle) {
-        native_setBitmap(mNativeCanvasWrapper, bitmapHandle, false);
-    }
-
-    /**
      * Set the viewport dimensions if this canvas is GL based. If it is not,
      * this method is ignored and no exception is thrown.
      *
@@ -1976,10 +1965,9 @@
      */
     public static native void freeTextLayoutCaches();
 
-    private static native long initRaster(long nativeBitmapOrZero);
+    private static native long initRaster(Bitmap bitmap);
     private static native void native_setBitmap(long canvasHandle,
-                                                long bitmapHandle,
-                                                boolean copyState);
+                                                Bitmap bitmap);
     private static native boolean native_isOpaque(long canvasHandle);
     private static native int native_getWidth(long canvasHandle);
     private static native int native_getHeight(long canvasHandle);
diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h
index 7ad0683..aa24673 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -29,7 +29,7 @@
 public:
     virtual ~Canvas() {};
 
-    static Canvas* create_canvas(SkBitmap* bitmap);
+    static Canvas* create_canvas(const SkBitmap& bitmap);
 
     /**
      *  Create a new Canvas object which delegates to an SkCanvas.
@@ -52,7 +52,7 @@
      */
     virtual SkCanvas* asSkCanvas() = 0;
 
-    virtual void setBitmap(SkBitmap* bitmap, bool copyState) = 0;
+    virtual void setBitmap(const SkBitmap& bitmap) = 0;
 
     virtual bool isOpaque() = 0;
     virtual int width() = 0;
@@ -87,7 +87,8 @@
     virtual bool quickRejectRect(float left, float top, float right, float bottom) const = 0;
     virtual bool quickRejectPath(const SkPath& path) const = 0;
 
-    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op) = 0;
+    virtual bool clipRect(float left, float top, float right, float bottom,
+            SkRegion::Op op = SkRegion::kIntersect_Op) = 0;
     virtual bool clipPath(const SkPath* path, SkRegion::Op op) = 0;
     virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) = 0;
 
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 53fd1ad..ff698f5 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -138,7 +138,7 @@
 // ----------------------------------------------------------------------------
     virtual SkCanvas* asSkCanvas() override;
 
-    virtual void setBitmap(SkBitmap* bitmap, bool copyState) override {
+    virtual void setBitmap(const SkBitmap& bitmap) override {
         LOG_ALWAYS_FATAL("DisplayListRenderer is not backed by a bitmap.");
     }
 
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 71088b7..dfa847c 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -31,7 +31,7 @@
 // Holds an SkCanvas reference plus additional native data.
 class SkiaCanvas : public Canvas {
 public:
-    explicit SkiaCanvas(SkBitmap* bitmap);
+    explicit SkiaCanvas(const SkBitmap& bitmap);
 
     /**
      *  Create a new SkiaCanvas.
@@ -49,7 +49,7 @@
         return mCanvas.get();
     }
 
-    virtual void setBitmap(SkBitmap* bitmap, bool copyState) override;
+    virtual void setBitmap(const SkBitmap& bitmap) override;
 
     virtual bool isOpaque() override;
     virtual int width() override;
@@ -145,19 +145,7 @@
     SkAutoTDelete<SkDeque> mSaveStack; // lazily allocated, tracks partial saves.
 };
 
-// Construct an SkCanvas from the bitmap.
-static SkCanvas* createCanvas(SkBitmap* bitmap) {
-    if (bitmap) {
-        return SkNEW_ARGS(SkCanvas, (*bitmap));
-    }
-
-    // Create an empty bitmap device to prevent callers from crashing
-    // if they attempt to draw into this canvas.
-    SkBitmap emptyBitmap;
-    return new SkCanvas(emptyBitmap);
-}
-
-Canvas* Canvas::create_canvas(SkBitmap* bitmap) {
+Canvas* Canvas::create_canvas(const SkBitmap& bitmap) {
     return new SkiaCanvas(bitmap);
 }
 
@@ -165,8 +153,8 @@
     return new SkiaCanvas(skiaCanvas);
 }
 
-SkiaCanvas::SkiaCanvas(SkBitmap* bitmap) {
-    mCanvas.reset(createCanvas(bitmap));
+SkiaCanvas::SkiaCanvas(const SkBitmap& bitmap) {
+    mCanvas.reset(new SkCanvas(bitmap));
 }
 
 // ----------------------------------------------------------------------------
@@ -191,11 +179,11 @@
     SkCanvas* m_dstCanvas;
 };
 
-void SkiaCanvas::setBitmap(SkBitmap* bitmap, bool copyState) {
-    SkCanvas* newCanvas = createCanvas(bitmap);
+void SkiaCanvas::setBitmap(const SkBitmap& bitmap) {
+    SkCanvas* newCanvas = new SkCanvas(bitmap);
     SkASSERT(newCanvas);
 
-    if (copyState) {
+    if (!bitmap.isNull()) {
         // Copy the canvas matrix & clip state.
         newCanvas->setMatrix(mCanvas->getTotalMatrix());
         if (NULL != mCanvas->getDevice() && NULL != newCanvas->getDevice()) {
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index cc87241..d15fa39 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -293,11 +293,11 @@
     return (void*) success;
 }
 
-bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
+bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) {
     SETUP_TASK(copyLayerInto);
     args->context = mContext;
     args->layer = layer;
-    args->bitmap = bitmap;
+    args->bitmap = &bitmap;
     return (bool) postAndWait(task);
 }
 
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 29c6f08..cc475fa 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -83,7 +83,7 @@
 
     ANDROID_API DeferredLayerUpdater* createTextureLayer();
     ANDROID_API void buildLayer(RenderNode* node);
-    ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
+    ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap);
     ANDROID_API void pushLayerUpdate(DeferredLayerUpdater* layer);
     ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer);
     ANDROID_API void detachSurfaceTexture(DeferredLayerUpdater* layer);
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 5b177e5..66d055a 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -42,7 +42,7 @@
     libusbhost \
     libjhead \
     libexif \
-    libstagefright_amrnb_common \
+    libstagefright_amrnb_common
 
 LOCAL_REQUIRED_MODULES := \
     libjhead_jni
@@ -54,6 +54,7 @@
     external/libexif/ \
     external/tremor/Tremor \
     frameworks/base/core/jni \
+    frameworks/base/libs/hwui \
     frameworks/av/media/libmedia \
     frameworks/av/media/libstagefright \
     frameworks/av/media/libstagefright/codecs/amrnb/enc/src \
diff --git a/native/graphics/jni/Android.mk b/native/graphics/jni/Android.mk
index 91c9ac6..f89a5af 100644
--- a/native/graphics/jni/Android.mk
+++ b/native/graphics/jni/Android.mk
@@ -24,7 +24,8 @@
 
 LOCAL_C_INCLUDES += \
     frameworks/base/native/include \
-    frameworks/base/core/jni/android/graphics
+    frameworks/base/core/jni/android/graphics \
+    frameworks/base/libs/hwui
 
 LOCAL_MODULE:= libjnigraphics
 
diff --git a/rs/jni/Android.mk b/rs/jni/Android.mk
index 94f0859..0658620 100644
--- a/rs/jni/Android.mk
+++ b/rs/jni/Android.mk
@@ -25,6 +25,7 @@
     $(JNI_H_INCLUDE) \
     frameworks/rs \
     frameworks/base/core/jni \
+    frameworks/base/libs/hwui \
     $(rs_generated_include_dir)
 
 LOCAL_CFLAGS += -Wno-unused-parameter -std=c++11
diff --git a/services/core/java/com/android/server/AssetAtlasService.java b/services/core/java/com/android/server/AssetAtlasService.java
index 66cc29a..9e28b64 100644
--- a/services/core/java/com/android/server/AssetAtlasService.java
+++ b/services/core/java/com/android/server/AssetAtlasService.java
@@ -199,9 +199,6 @@
         private final ArrayList<Bitmap> mBitmaps;
         private final int mPixelCount;
 
-        private long mNativeBitmap;
-
-        // Used for debugging only
         private Bitmap mAtlasBitmap;
 
         Renderer(ArrayList<Bitmap> bitmaps, int pixelCount) {
@@ -299,9 +296,7 @@
                 }
 
                 final long endRender = System.nanoTime();
-                if (mNativeBitmap != 0) {
-                    result = nUploadAtlas(buffer, mNativeBitmap);
-                }
+                result = nUploadAtlas(buffer, mAtlasBitmap);
 
                 final long endUpload = System.nanoTime();
                 if (DEBUG_ATLAS) {
@@ -326,14 +321,8 @@
          * @param height
          */
         private Canvas acquireCanvas(int width, int height) {
-            if (DEBUG_ATLAS_TEXTURE) {
-                mAtlasBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-                return new Canvas(mAtlasBitmap);
-            } else {
-                Canvas canvas = new Canvas();
-                mNativeBitmap = nAcquireAtlasCanvas(canvas, width, height);
-                return canvas;
-            }
+            mAtlasBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+            return new Canvas(mAtlasBitmap);
         }
 
         /**
@@ -343,8 +332,8 @@
          * to disk in /data/system/atlas.png for debugging.
          */
         private void releaseCanvas(Canvas canvas) {
+            canvas.setBitmap(null);
             if (DEBUG_ATLAS_TEXTURE) {
-                canvas.setBitmap(null);
 
                 File systemDirectory = new File(Environment.getDataDirectory(), "system");
                 File dataFile = new File(systemDirectory, "atlas.png");
@@ -358,18 +347,13 @@
                 } catch (IOException e) {
                     // Ignore
                 }
-
-                mAtlasBitmap.recycle();
-                mAtlasBitmap = null;
-            } else {
-                nReleaseAtlasCanvas(canvas, mNativeBitmap);
             }
+            mAtlasBitmap.recycle();
+            mAtlasBitmap = null;
         }
     }
 
-    private static native long nAcquireAtlasCanvas(Canvas canvas, int width, int height);
-    private static native void nReleaseAtlasCanvas(Canvas canvas, long bitmap);
-    private static native boolean nUploadAtlas(GraphicBuffer buffer, long bitmap);
+    private static native boolean nUploadAtlas(GraphicBuffer buffer, Bitmap bitmap);
 
     @Override
     public boolean isCompatible(int ppid) {
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index 6448de2..d26717c 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -33,6 +33,7 @@
     $(JNI_H_INCLUDE) \
     frameworks/base/services \
     frameworks/base/libs \
+    frameworks/base/libs/hwui \
     frameworks/base/core/jni \
     frameworks/native/services \
     libcore/include \
diff --git a/services/core/jni/com_android_server_AssetAtlasService.cpp b/services/core/jni/com_android_server_AssetAtlasService.cpp
index e4f242e..8f4fb51 100644
--- a/services/core/jni/com_android_server_AssetAtlasService.cpp
+++ b/services/core/jni/com_android_server_AssetAtlasService.cpp
@@ -47,40 +47,9 @@
 #define FENCE_TIMEOUT 2000000000
 
 // ----------------------------------------------------------------------------
-// JNI Helpers
-// ----------------------------------------------------------------------------
-
-static struct {
-    jmethodID setNativeBitmap;
-} gCanvasClassInfo;
-
-#define INVOKEV(object, method, ...) \
-    env->CallVoidMethod(object, method, __VA_ARGS__)
-
-// ----------------------------------------------------------------------------
 // Canvas management
 // ----------------------------------------------------------------------------
 
-static jlong com_android_server_AssetAtlasService_acquireCanvas(JNIEnv* env, jobject,
-        jobject canvas, jint width, jint height) {
-
-    SkBitmap* bitmap = new SkBitmap;
-    bitmap->allocN32Pixels(width, height);
-    bitmap->eraseColor(0);
-    INVOKEV(canvas, gCanvasClassInfo.setNativeBitmap, reinterpret_cast<jlong>(bitmap));
-
-    return reinterpret_cast<jlong>(bitmap);
-}
-
-static void com_android_server_AssetAtlasService_releaseCanvas(JNIEnv* env, jobject,
-        jobject canvas, jlong bitmapHandle) {
-
-    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
-    INVOKEV(canvas, gCanvasClassInfo.setNativeBitmap, (jlong)0);
-
-    delete bitmap;
-}
-
 #define CLEANUP_GL_AND_RETURN(result) \
     if (fence != EGL_NO_SYNC_KHR) eglDestroySyncKHR(display, fence); \
     if (image) eglDestroyImageKHR(display, image); \
@@ -93,9 +62,12 @@
     return result;
 
 static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject,
-        jobject graphicBuffer, jlong bitmapHandle) {
+        jobject graphicBuffer, jobject bitmapHandle) {
 
-    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
+    SkBitmap bitmap;
+    GraphicsJNI::getSkBitmap(env, bitmapHandle, &bitmap);
+    SkAutoLockPixels alp(bitmap);
+
     // The goal of this method is to copy the bitmap into the GraphicBuffer
     // using the GPU to swizzle the texture content
     sp<GraphicBuffer> buffer(graphicBufferForJavaObject(env, graphicBuffer));
@@ -186,9 +158,9 @@
         }
 
         // Upload the content of the bitmap in the GraphicBuffer
-        glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
-        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap->width(), bitmap->height(),
-                GL_RGBA, GL_UNSIGNED_BYTE, bitmap->getPixels());
+        glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap.bytesPerPixel());
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
+                GL_RGBA, GL_UNSIGNED_BYTE, bitmap.getPixels());
         if (glGetError() != GL_NO_ERROR) {
             ALOGW("Could not upload to texture");
             CLEANUP_GL_AND_RETURN(JNI_FALSE);
@@ -233,20 +205,11 @@
 const char* const kClassPathName = "com/android/server/AssetAtlasService";
 
 static JNINativeMethod gMethods[] = {
-    { "nAcquireAtlasCanvas", "(Landroid/graphics/Canvas;II)J",
-            (void*) com_android_server_AssetAtlasService_acquireCanvas },
-    { "nReleaseAtlasCanvas", "(Landroid/graphics/Canvas;J)V",
-            (void*) com_android_server_AssetAtlasService_releaseCanvas },
-    { "nUploadAtlas", "(Landroid/view/GraphicBuffer;J)Z",
+    { "nUploadAtlas", "(Landroid/view/GraphicBuffer;Landroid/graphics/Bitmap;)Z",
             (void*) com_android_server_AssetAtlasService_upload },
 };
 
 int register_android_server_AssetAtlasService(JNIEnv* env) {
-    jclass clazz;
-
-    FIND_CLASS(clazz, "android/graphics/Canvas");
-    GET_METHOD_ID(gCanvasClassInfo.setNativeBitmap, clazz, "setNativeBitmap", "(J)V");
-
     return jniRegisterNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
 }