diff options
author | Chris Craik <ccraik@google.com> | 2013-09-09 23:00:48 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-09-09 23:00:49 +0000 |
commit | 932e59fc2aae145a8930e4a2da4885f607fd47aa (patch) | |
tree | 739d6ad79c04b6844f1ce251ef2fd63d9c4e9740 | |
parent | 440f4dfac89c113b41f1a7259306b90b0cde8768 (diff) | |
parent | cd0ba71aa942f35fcdb26808b86f20073b8aff92 (diff) | |
download | frameworks_base-932e59fc2aae145a8930e4a2da4885f607fd47aa.zip frameworks_base-932e59fc2aae145a8930e4a2da4885f607fd47aa.tar.gz frameworks_base-932e59fc2aae145a8930e4a2da4885f607fd47aa.tar.bz2 |
Merge "Create a pixelref wrapper for reused bitmaps" into klp-dev
-rw-r--r-- | core/jni/android/graphics/BitmapFactory.cpp | 8 | ||||
-rw-r--r-- | core/jni/android/graphics/Graphics.cpp | 43 | ||||
-rw-r--r-- | core/jni/android/graphics/GraphicsJNI.h | 11 |
3 files changed, 55 insertions, 7 deletions
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index 16beb02..f9bb233 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -189,7 +189,13 @@ public: mSize, bitmap->getSize()); return false; } - bitmap->setPixelRef(mPixelRef); + + // Create a new pixelref with the new ctable that wraps the previous pixelref + SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef), ctable); + + bitmap->setPixelRef(pr)->unref(); + // since we're already allocated, we lockPixels right away + // HeapAllocator/JavaPixelAllocator behaves this way too bitmap->lockPixels(); return true; } diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index ef5b7c9..1ff0d63 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -414,7 +414,8 @@ static JNIEnv* vm2env(JavaVM* vm) /////////////////////////////////////////////////////////////////////////////// AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj, - SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)) { + SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)), + fWrappedPixelRef(NULL) { SkASSERT(storage); SkASSERT(env); @@ -431,8 +432,25 @@ AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteA } +AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable) : + SkMallocPixelRef(wrappedPixelRef.getAddr(), wrappedPixelRef.getSize(), ctable, false), + fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ? + wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef) +{ + SkASSERT(fWrappedPixelRef); + SkSafeRef(fWrappedPixelRef); + + // don't need to initialize these, as all the relevant logic delegates to the wrapped ref + fStorageObj = NULL; + fHasGlobalRef = false; + fGlobalRefCnt = 0; + fOnJavaHeap = false; +} + AndroidPixelRef::~AndroidPixelRef() { - if (fOnJavaHeap) { + if (fWrappedPixelRef) { + SkSafeUnref(fWrappedPixelRef); + } else if (fOnJavaHeap) { JNIEnv* env = vm2env(fVM); if (fStorageObj && fHasGlobalRef) { @@ -441,15 +459,27 @@ AndroidPixelRef::~AndroidPixelRef() { fStorageObj = NULL; } } +jbyteArray AndroidPixelRef::getStorageObj() { + if (fWrappedPixelRef) { + return fWrappedPixelRef->fStorageObj; + } + return fStorageObj; +} void AndroidPixelRef::setLocalJNIRef(jbyteArray arr) { - if (!fHasGlobalRef) { + if (fWrappedPixelRef) { + // delegate java obj management to the wrapped ref + fWrappedPixelRef->setLocalJNIRef(arr); + } else if (!fHasGlobalRef) { fStorageObj = arr; } } void AndroidPixelRef::globalRef(void* localref) { - if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) { + if (fWrappedPixelRef) { + // delegate java obj management to the wrapped ref + fWrappedPixelRef->globalRef(localref); + } else if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) { JNIEnv *env = vm2env(fVM); // If JNI ref was passed, it is always used @@ -473,7 +503,10 @@ void AndroidPixelRef::globalRef(void* localref) { } void AndroidPixelRef::globalUnref() { - if (fOnJavaHeap && sk_atomic_dec(&fGlobalRefCnt) == 1) { + if (fWrappedPixelRef) { + // delegate java obj management to the wrapped ref + fWrappedPixelRef->globalUnref(); + } else if (fOnJavaHeap && sk_atomic_dec(&fGlobalRefCnt) == 1) { JNIEnv *env = vm2env(fVM); if (!fHasGlobalRef) { SkDebugf("We don't have a global ref!"); diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h index 5a2a6f8..f4590b9 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -91,9 +91,16 @@ public: AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj, SkColorTable* ctable); + /** + * Creates an AndroidPixelRef that wraps (and refs) another to reuse/share + * the same storage and java byte array refcounting, yet have a different + * color table. + */ + AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable); + virtual ~AndroidPixelRef(); - jbyteArray getStorageObj() { return fStorageObj; } + jbyteArray getStorageObj(); void setLocalJNIRef(jbyteArray arr); @@ -110,6 +117,8 @@ public: virtual void globalUnref(); private: + AndroidPixelRef* const fWrappedPixelRef; // if set, delegate memory management calls to this + JavaVM* fVM; bool fOnJavaHeap; // If true, the memory was allocated on the Java heap |