Loading core/jni/android/graphics/Bitmap.cpp +1 −12 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; } } 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; } Loading core/jni/android/graphics/Graphics.cpp +77 −3 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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(); Loading @@ -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); Loading @@ -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 Loading @@ -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) Loading core/jni/android/graphics/GraphicsJNI.h +8 −0 Original line number Diff line number Diff line Loading @@ -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. Loading core/jni/android_graphics_Canvas.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -383,7 +383,8 @@ static void drawBitmapArray(JNIEnv* env, jobject, jlong canvasHandle, hasAlpha ? kN32_SkColorType : kRGB_565_SkColorType, kPremul_SkAlphaType); SkBitmap bitmap; if (!bitmap.tryAllocPixels(info)) { bitmap.setInfo(info); if (!GraphicsJNI::allocatePixels(env, &bitmap, NULL)) { return; } Loading libs/hwui/DisplayList.cpp +0 −7 Original line number Diff line number Diff line Loading @@ -46,12 +46,6 @@ void DisplayListData::cleanupResources() { resourceCache.decrementRefcountLocked(bitmapResources.itemAt(i)); } for (size_t i = 0; i < ownedBitmapResources.size(); i++) { const SkBitmap* bitmap = ownedBitmapResources.itemAt(i); resourceCache.decrementRefcountLocked(bitmap); resourceCache.destructorLocked(bitmap); } for (size_t i = 0; i < patchResources.size(); i++) { resourceCache.decrementRefcountLocked(patchResources.itemAt(i)); } Loading @@ -63,7 +57,6 @@ void DisplayListData::cleanupResources() { resourceCache.unlock(); bitmapResources.clear(); ownedBitmapResources.clear(); patchResources.clear(); sourcePaths.clear(); paints.clear(); Loading Loading
core/jni/android/graphics/Bitmap.cpp +1 −12 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; } } 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; } Loading
core/jni/android/graphics/Graphics.cpp +77 −3 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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(); Loading @@ -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); Loading @@ -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 Loading @@ -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) Loading
core/jni/android/graphics/GraphicsJNI.h +8 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
core/jni/android_graphics_Canvas.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -383,7 +383,8 @@ static void drawBitmapArray(JNIEnv* env, jobject, jlong canvasHandle, hasAlpha ? kN32_SkColorType : kRGB_565_SkColorType, kPremul_SkAlphaType); SkBitmap bitmap; if (!bitmap.tryAllocPixels(info)) { bitmap.setInfo(info); if (!GraphicsJNI::allocatePixels(env, &bitmap, NULL)) { return; } Loading
libs/hwui/DisplayList.cpp +0 −7 Original line number Diff line number Diff line Loading @@ -46,12 +46,6 @@ void DisplayListData::cleanupResources() { resourceCache.decrementRefcountLocked(bitmapResources.itemAt(i)); } for (size_t i = 0; i < ownedBitmapResources.size(); i++) { const SkBitmap* bitmap = ownedBitmapResources.itemAt(i); resourceCache.decrementRefcountLocked(bitmap); resourceCache.destructorLocked(bitmap); } for (size_t i = 0; i < patchResources.size(); i++) { resourceCache.decrementRefcountLocked(patchResources.itemAt(i)); } Loading @@ -63,7 +57,6 @@ void DisplayListData::cleanupResources() { resourceCache.unlock(); bitmapResources.clear(); ownedBitmapResources.clear(); patchResources.clear(); sourcePaths.clear(); paints.clear(); Loading