summaryrefslogtreecommitdiffstats
path: root/core/jni/android
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2014-12-04 15:20:29 -0500
committerDerek Sollenberger <djsollen@google.com>2015-01-09 13:56:56 -0500
commit3d4eed7f1aa99401dabe2e45b82f98fb4fc2d754 (patch)
treee727b03577a823f638cab2f76a8a1161b73662eb /core/jni/android
parent83eb4443a9d24f2ae4a1e516354748850c10d06b (diff)
downloadframeworks_base-3d4eed7f1aa99401dabe2e45b82f98fb4fc2d754.zip
frameworks_base-3d4eed7f1aa99401dabe2e45b82f98fb4fc2d754.tar.gz
frameworks_base-3d4eed7f1aa99401dabe2e45b82f98fb4fc2d754.tar.bz2
Update HWUI to store its own SkBitmap objects
This enables us to... 1) simplify the lifecycle/ownership between Java and HWUI 2) remove DisplayListRenderer::drawBitmapData and associated logic 3) track pixel lifecycle using standard SkPixelRef refcounting 4) Remove uncessary calls to ref/unref the bitmap's pixels and colorTable Change-Id: I3c95078da20995444f6388a029414280fd654318
Diffstat (limited to 'core/jni/android')
-rwxr-xr-xcore/jni/android/graphics/Bitmap.cpp13
-rw-r--r--core/jni/android/graphics/Graphics.cpp80
-rw-r--r--core/jni/android/graphics/GraphicsJNI.h8
3 files changed, 86 insertions, 15 deletions
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 1a29a62..a10cfca 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -19,8 +19,6 @@
#include <jni.h>
-#include <ResourceCache.h>
-
///////////////////////////////////////////////////////////////////////////////
// Conversions to/from SkColor, for get/setPixels, and the create method, which
// is basically like setPixels
@@ -360,20 +358,11 @@ static jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle,
static void Bitmap_destructor(JNIEnv* env, jobject, jlong bitmapHandle) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- if (android::uirenderer::ResourceCache::hasInstance()) {
- android::uirenderer::ResourceCache::getInstance().destructor(bitmap);
- } else {
- delete bitmap;
- }
+ delete bitmap;
}
static jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
- if (android::uirenderer::ResourceCache::hasInstance()) {
- bool result;
- result = android::uirenderer::ResourceCache::getInstance().recycle(bitmap);
- return result ? JNI_TRUE : JNI_FALSE;
- }
bitmap->setPixels(NULL, NULL);
return JNI_TRUE;
}
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 8e1e8d3..9996ce1 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -11,6 +11,9 @@
#include "SkRegion.h"
#include <android_runtime/AndroidRuntime.h>
+#include <Caches.h>
+#include <TextureCache.h>
+
void doThrowNPE(JNIEnv* env) {
jniThrowNullPointerException(env, NULL);
}
@@ -500,10 +503,28 @@ AndroidPixelRef::~AndroidPixelRef() {
JNIEnv* env = vm2env(fVM);
env->DeleteGlobalRef(fStorageObj);
}
+
+ if (android::uirenderer::Caches::hasInstance()) {
+ android::uirenderer::Caches::getInstance().textureCache.releaseTexture(getStableID());
+ }
}
///////////////////////////////////////////////////////////////////////////////
+static bool computeAllocationSize(const SkImageInfo& info, size_t* size, size_t* rowBytes) {
+ int32_t rowBytes32 = SkToS32(info.minRowBytes());
+ int64_t bigSize = (int64_t)info.height() * rowBytes32;
+ if (rowBytes32 < 0 || !sk_64_isS32(bigSize)) {
+ return false; // allocation will be too large
+ }
+
+ *size = sk_64_asS32(bigSize);
+ *rowBytes = rowBytes32;
+
+ SkASSERT(*size >= info.getSafeSize(*rowBytes));
+ return true;
+}
+
jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
SkColorTable* ctable) {
const SkImageInfo& info = bitmap->info();
@@ -512,7 +533,11 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
return NULL;
}
- const size_t size = bitmap->getSize();
+ size_t size, rowBytes;
+ if (!computeAllocationSize(info, &size, &rowBytes)) {
+ return NULL;
+ }
+
jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime,
gVMRuntime_newNonMovableArray,
gByte_class, size);
@@ -525,8 +550,7 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
return NULL;
}
SkASSERT(addr);
- SkPixelRef* pr = new AndroidPixelRef(env, info, (void*) addr,
- bitmap->rowBytes(), arrayObj, ctable);
+ SkPixelRef* pr = new AndroidPixelRef(env, info, (void*) addr, rowBytes, arrayObj, ctable);
bitmap->setPixelRef(pr)->unref();
// since we're already allocated, we lockPixels right away
// HeapAllocator behaves this way too
@@ -535,6 +559,56 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
return arrayObj;
}
+struct AndroidPixelRefContext {
+ int32_t stableID;
+};
+
+static void allocatePixelsReleaseProc(void* ptr, void* ctx) {
+ AndroidPixelRefContext* context = (AndroidPixelRefContext*)ctx;
+ if (android::uirenderer::Caches::hasInstance()) {
+ android::uirenderer::Caches::getInstance().textureCache.releaseTexture(context->stableID);
+ }
+
+ sk_free(ptr);
+ delete context;
+}
+
+bool GraphicsJNI::allocatePixels(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable) {
+ const SkImageInfo& info = bitmap->info();
+ if (info.fColorType == kUnknown_SkColorType) {
+ doThrowIAE(env, "unknown bitmap configuration");
+ return NULL;
+ }
+
+ size_t size, rowBytes;
+ if (!computeAllocationSize(info, &size, &rowBytes)) {
+ return false;
+ }
+
+ void* addr = sk_malloc_flags(size, 0);
+ if (NULL == addr) {
+ return false;
+ }
+
+ AndroidPixelRefContext* context = new AndroidPixelRefContext;
+ SkMallocPixelRef* pr = SkMallocPixelRef::NewWithProc(info, rowBytes, ctable, addr,
+ &allocatePixelsReleaseProc, context);
+ if (!pr) {
+ delete context;
+ return false;
+ }
+
+ // set the stableID in the context so that it can be used later in
+ // allocatePixelsReleaseProc to remove the texture from the cache.
+ context->stableID = pr->getStableID();
+
+ bitmap->setPixelRef(pr)->unref();
+ // since we're already allocated, we can lockPixels right away
+ bitmap->lockPixels();
+
+ return true;
+}
+
///////////////////////////////////////////////////////////////////////////////
JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env)
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 0a70ba2..a202c38 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -95,6 +95,14 @@ public:
static jbyteArray allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
SkColorTable* ctable);
+ /**
+ * Given a bitmap we natively allocate a memory block to store the contents
+ * of that bitmap. The memory is then attached to the bitmap via an
+ * SkPixelRef, which ensures that upon deletion the appropriate caches
+ * are notified.
+ */
+ static bool allocatePixels(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable);
+
/** Copy the colors in colors[] to the bitmap, convert to the correct
format along the way.
Whether to use premultiplied pixels is determined by dstBitmap's alphaType.