Attempt to solve the double-GC problem

Fix the issue where Bitmap requires two GC passes
to release its byte[] by using some questionable
ref-counting hacks to manage whether or not
native has a strong or weak ref to the byte[]

Change-Id: Ia90a883579f61c0b1904b5549a66bd0ef34b32c5
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index a8355c2..1965cd3 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -23,6 +23,7 @@
 
 #include "android_os_Parcel.h"
 #include "android_util_Binder.h"
+#include "android/graphics/Bitmap.h"
 #include "android/graphics/GraphicsJNI.h"
 #include "android/graphics/Region.h"
 
@@ -168,22 +169,19 @@
         }
     }
 
-    const ssize_t rowBytes =
+    const size_t rowBytes =
             screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
 
-    SkBitmap* bitmap = new SkBitmap();
-    bitmap->setInfo(screenshotInfo, (size_t)rowBytes);
-    if (screenshotInfo.fWidth > 0 && screenshotInfo.fHeight > 0) {
-        // takes ownership of ScreenshotClient
-        SkMallocPixelRef* pixels = SkMallocPixelRef::NewWithProc(screenshotInfo,
-                (size_t) rowBytes, NULL, (void*) screenshot->getPixels(), &DeleteScreenshot,
-                (void*) (screenshot.get()));
-        screenshot.detach();
-        pixels->setImmutable();
-        bitmap->setPixelRef(pixels)->unref();
-        bitmap->lockPixels();
+    if (!screenshotInfo.fWidth || !screenshotInfo.fHeight) {
+        return NULL;
     }
 
+    Bitmap* bitmap = new Bitmap(
+            (void*) screenshot->getPixels(), (void*) screenshot.get(), DeleteScreenshot,
+            screenshotInfo, rowBytes, nullptr);
+    screenshot.detach();
+    bitmap->pixelRef()->setImmutable();
+
     return GraphicsJNI::createBitmap(env, bitmap,
             GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL);
 }