diff options
| -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 16beb022de0b..f9bb2331482d 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 ef5b7c91e67a..1ff0d635c576 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 5a2a6f826fbc..f4590b956d78 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  |