Avoid unnecessary copy when invoking drawBitmap(int[])
Bug #6483390

Change-Id: I4d2d725ef50c9401b4bd998b6160128102b40745
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index d2a6a7a..a5f653a 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -162,6 +162,13 @@
     }
     mBitmapResources.clear();
 
+    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
+        SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
+        caches.resourceCache.decrementRefcount(bitmap);
+        caches.resourceCache.destructor(bitmap);
+    }
+    mOwnedBitmapResources.clear();
+
     for (size_t i = 0; i < mFilterResources.size(); i++) {
         caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
     }
@@ -217,44 +224,51 @@
 
     Caches& caches = Caches::getInstance();
 
-    const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
+    const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
     for (size_t i = 0; i < bitmapResources.size(); i++) {
         SkBitmap* resource = bitmapResources.itemAt(i);
         mBitmapResources.add(resource);
         caches.resourceCache.incrementRefcount(resource);
     }
 
-    const Vector<SkiaColorFilter*> &filterResources = recorder.getFilterResources();
+    const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources();
+    for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
+        SkBitmap* resource = ownedBitmapResources.itemAt(i);
+        mOwnedBitmapResources.add(resource);
+        caches.resourceCache.incrementRefcount(resource);
+    }
+
+    const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources();
     for (size_t i = 0; i < filterResources.size(); i++) {
         SkiaColorFilter* resource = filterResources.itemAt(i);
         mFilterResources.add(resource);
         caches.resourceCache.incrementRefcount(resource);
     }
 
-    const Vector<SkiaShader*> &shaders = recorder.getShaders();
+    const Vector<SkiaShader*>& shaders = recorder.getShaders();
     for (size_t i = 0; i < shaders.size(); i++) {
         SkiaShader* resource = shaders.itemAt(i);
         mShaders.add(resource);
         caches.resourceCache.incrementRefcount(resource);
     }
 
-    const Vector<SkPaint*> &paints = recorder.getPaints();
+    const Vector<SkPaint*>& paints = recorder.getPaints();
     for (size_t i = 0; i < paints.size(); i++) {
         mPaints.add(paints.itemAt(i));
     }
 
-    const Vector<SkPath*> &paths = recorder.getPaths();
+    const Vector<SkPath*>& paths = recorder.getPaths();
     for (size_t i = 0; i < paths.size(); i++) {
         mPaths.add(paths.itemAt(i));
     }
 
-    const SortedVector<SkPath*> &sourcePaths = recorder.getSourcePaths();
+    const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
     for (size_t i = 0; i < sourcePaths.size(); i++) {
         mSourcePaths.add(sourcePaths.itemAt(i));
         caches.resourceCache.incrementRefcount(sourcePaths.itemAt(i));
     }
 
-    const Vector<SkMatrix*> &matrices = recorder.getMatrices();
+    const Vector<SkMatrix*>& matrices = recorder.getMatrices();
     for (size_t i = 0; i < matrices.size(); i++) {
         mMatrices.add(matrices.itemAt(i));
     }
@@ -1036,10 +1050,7 @@
                 SkPaint* paint = getPaint(renderer);
                 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
                         bitmap, x, y, paint);
-                if (bitmap) {
-                    renderer.drawBitmap(bitmap, x, y, paint);
-                    delete bitmap;
-                }
+                renderer.drawBitmap(bitmap, x, y, paint);
             }
             break;
             case DrawBitmapMesh: {
@@ -1295,6 +1306,12 @@
     }
     mBitmapResources.clear();
 
+    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
+        SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
+        caches.resourceCache.decrementRefcount(bitmap);
+    }
+    mOwnedBitmapResources.clear();
+
     for (size_t i = 0; i < mFilterResources.size(); i++) {
         caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
     }
@@ -1336,6 +1353,10 @@
     return displayList;
 }
 
+bool DisplayListRenderer::isDeferred() {
+    return true;
+}
+
 void DisplayListRenderer::setViewport(int width, int height) {
     mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
 
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 2f74f5b..93b065d 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -398,7 +398,6 @@
 
 private:
     void init();
-
     void initProperties();
 
     void clearResources();
@@ -424,16 +423,7 @@
     }
 
     SkBitmap* getBitmapData() {
-        SkBitmap* bitmap = new SkBitmap;
-        bitmap->setConfig((SkBitmap::Config) getInt(), getInt(), getInt());
-        if (!bitmap->allocPixels()) {
-            delete bitmap;
-            return NULL;
-        }
-
-        bitmap->setPixels((void*) mReader.skip(bitmap->height() * bitmap->rowBytes()));
-
-        return bitmap;
+        return (SkBitmap*) getInt();
     }
 
     SkiaShader* getShader() {
@@ -497,6 +487,7 @@
     }
 
     Vector<SkBitmap*> mBitmapResources;
+    Vector<SkBitmap*> mOwnedBitmapResources;
     Vector<SkiaColorFilter*> mFilterResources;
 
     Vector<SkPaint*> mPaints;
@@ -552,6 +543,8 @@
 
     ANDROID_API DisplayList* getDisplayList(DisplayList* displayList);
 
+    virtual bool isDeferred();
+
     virtual void setViewport(int width, int height);
     virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
     virtual void finish();
@@ -634,6 +627,10 @@
         return mBitmapResources;
     }
 
+    const Vector<SkBitmap*>& getOwnedBitmapResources() const {
+        return mOwnedBitmapResources;
+    }
+
     const Vector<SkiaColorFilter*>& getFilterResources() const {
         return mFilterResources;
     }
@@ -719,17 +716,6 @@
         mWriter.write(values, count * sizeof(int32_t));
     }
 
-    void addBitmapData(SkBitmap* bitmap) {
-        mWriter.writeInt(bitmap->config());
-        mWriter.writeInt(bitmap->width());
-        mWriter.writeInt(bitmap->height());
-
-        SkAutoLockPixels alp(*bitmap);
-        void* src = bitmap->getPixels();
-
-        mWriter.write(src, bitmap->rowBytes() * bitmap->height());
-    }
-
     void addUInts(const uint32_t* values, int8_t count) {
         mWriter.writeInt(count);
         mWriter.write(values, count * sizeof(uint32_t));
@@ -825,6 +811,12 @@
         Caches::getInstance().resourceCache.incrementRefcount(bitmap);
     }
 
+    void addBitmapData(SkBitmap* bitmap) {
+        addInt((int) bitmap);
+        mOwnedBitmapResources.add(bitmap);
+        Caches::getInstance().resourceCache.incrementRefcount(bitmap);
+    }
+
     inline void addShader(SkiaShader* shader) {
         if (!shader) {
             addInt((int) NULL);
@@ -851,6 +843,7 @@
     }
 
     Vector<SkBitmap*> mBitmapResources;
+    Vector<SkBitmap*> mOwnedBitmapResources;
     Vector<SkiaColorFilter*> mFilterResources;
 
     Vector<SkPaint*> mPaints;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 7f242c3..50f5d57 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -144,6 +144,10 @@
     return STENCIL_BUFFER_SIZE;
 }
 
+bool OpenGLRenderer::isDeferred() {
+    return false;
+}
+
 void OpenGLRenderer::setViewport(int width, int height) {
     mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
 
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 0ea0db7..ab324ff 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -63,6 +63,8 @@
     ANDROID_API OpenGLRenderer();
     virtual ~OpenGLRenderer();
 
+    virtual bool isDeferred();
+
     virtual void setViewport(int width, int height);
 
     ANDROID_API void prepare(bool opaque);
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 9ffad88..cf5f822 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -59,11 +59,11 @@
 void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
     SkSafeRef(bitmapResource->pixelRef());
     SkSafeRef(bitmapResource->getColorTable());
-    incrementRefcount((void*)bitmapResource, kBitmap);
+    incrementRefcount((void*) bitmapResource, kBitmap);
 }
 
 void ResourceCache::incrementRefcount(SkPath* pathResource) {
-    incrementRefcount((void*)pathResource, kPath);
+    incrementRefcount((void*) pathResource, kPath);
 }
 
 void ResourceCache::incrementRefcount(SkiaShader* shaderResource) {