diff options
author | Derek Sollenberger <djsollen@google.com> | 2014-12-04 15:20:29 -0500 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2015-01-09 13:56:56 -0500 |
commit | 3d4eed7f1aa99401dabe2e45b82f98fb4fc2d754 (patch) | |
tree | e727b03577a823f638cab2f76a8a1161b73662eb /core/jni/android | |
parent | 83eb4443a9d24f2ae4a1e516354748850c10d06b (diff) | |
download | frameworks_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-x | core/jni/android/graphics/Bitmap.cpp | 13 | ||||
-rw-r--r-- | core/jni/android/graphics/Graphics.cpp | 80 | ||||
-rw-r--r-- | core/jni/android/graphics/GraphicsJNI.h | 8 |
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. |