Make bitmap backed by native memory instead of java byte array
Test: refactoring CL. Existing unit tests still pass.
bug:27762775
Change-Id: Ic4e914b3a941c3d545f8ce9e320e638973df0e91
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 18c4ee3..6acb76d 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -127,12 +127,10 @@
}
};
-Bitmap::Bitmap(JNIEnv* env, jbyteArray storageObj, void* address,
- const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
- : mPixelStorageType(PixelStorageType::Java) {
- env->GetJavaVM(&mPixelStorage.java.jvm);
- mPixelStorage.java.jweakRef = env->NewWeakGlobalRef(storageObj);
- mPixelStorage.java.jstrongRef = nullptr;
+Bitmap::Bitmap(void* address, size_t size, const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
+ : mPixelStorageType(PixelStorageType::Heap) {
+ mPixelStorage.heap.address = address;
+ mPixelStorage.heap.size = size;
mPixelRef.reset(new WrappedPixelRef(this, address, info, rowBytes, ctable));
// Note: this will trigger a call to onStrongRefDestroyed(), but
// we want the pixel ref to have a ref count of 0 at this point
@@ -187,12 +185,8 @@
munmap(mPixelStorage.ashmem.address, mPixelStorage.ashmem.size);
close(mPixelStorage.ashmem.fd);
break;
- case PixelStorageType::Java:
- JNIEnv* env = jniEnv();
- LOG_ALWAYS_FATAL_IF(mPixelStorage.java.jstrongRef,
- "Deleting a bitmap wrapper while there are outstanding strong "
- "references! mPinnedRefCount = %d", mPinnedRefCount);
- env->DeleteWeakGlobalRef(mPixelStorage.java.jweakRef);
+ case PixelStorageType::Heap:
+ free(mPixelStorage.heap.address);
break;
}
@@ -219,6 +213,15 @@
}
}
+size_t Bitmap::getAllocationByteCount() const {
+ switch (mPixelStorageType) {
+ case PixelStorageType::Heap:
+ return mPixelStorage.heap.size;
+ default:
+ return rowBytes() * height();
+ }
+}
+
const SkImageInfo& Bitmap::info() const {
return mPixelRef->info();
}
@@ -244,7 +247,6 @@
// We just restored this from 0, pin the pixels and inc the strong count
// Note that there *might be* an incoming onStrongRefDestroyed from whatever
// last unref'd
- pinPixelsLocked();
mPinnedRefCount++;
}
return mPixelRef.get();
@@ -283,13 +285,6 @@
return mPinnedRefCount == 0 && !mAttachedToJava;
}
-JNIEnv* Bitmap::jniEnv() {
- JNIEnv* env;
- auto success = mPixelStorage.java.jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
- LOG_ALWAYS_FATAL_IF(success != JNI_OK,
- "Failed to get JNIEnv* from JVM: %p", mPixelStorage.java.jvm);
- return env;
-}
void Bitmap::onStrongRefDestroyed() {
bool disposeSelf = false;
@@ -298,7 +293,6 @@
if (mPinnedRefCount > 0) {
mPinnedRefCount--;
if (mPinnedRefCount == 0) {
- unpinPixelsLocked();
disposeSelf = shouldDisposeSelfLocked();
}
}
@@ -308,49 +302,6 @@
}
}
-void Bitmap::pinPixelsLocked() {
- switch (mPixelStorageType) {
- case PixelStorageType::Invalid:
- LOG_ALWAYS_FATAL("Cannot pin invalid pixels!");
- break;
- case PixelStorageType::External:
- case PixelStorageType::Ashmem:
- // Nothing to do
- break;
- case PixelStorageType::Java: {
- JNIEnv* env = jniEnv();
- if (!mPixelStorage.java.jstrongRef) {
- mPixelStorage.java.jstrongRef = reinterpret_cast<jbyteArray>(
- env->NewGlobalRef(mPixelStorage.java.jweakRef));
- if (!mPixelStorage.java.jstrongRef) {
- LOG_ALWAYS_FATAL("Failed to acquire strong reference to pixels");
- }
- }
- break;
- }
- }
-}
-
-void Bitmap::unpinPixelsLocked() {
- switch (mPixelStorageType) {
- case PixelStorageType::Invalid:
- LOG_ALWAYS_FATAL("Cannot unpin invalid pixels!");
- break;
- case PixelStorageType::External:
- case PixelStorageType::Ashmem:
- // Don't need to do anything
- break;
- case PixelStorageType::Java: {
- JNIEnv* env = jniEnv();
- if (mPixelStorage.java.jstrongRef) {
- env->DeleteGlobalRef(mPixelStorage.java.jstrongRef);
- mPixelStorage.java.jstrongRef = nullptr;
- }
- break;
- }
- }
-}
-
void Bitmap::getSkBitmap(SkBitmap* outBitmap) {
assertValid();
android::AutoMutex _lock(mLock);
@@ -723,7 +674,7 @@
SkBitmap bitmap;
bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType));
- Bitmap* nativeBitmap = GraphicsJNI::allocateJavaPixelRef(env, &bitmap, NULL);
+ Bitmap* nativeBitmap = GraphicsJNI::allocateHeapPixelRef(&bitmap, NULL);
if (!nativeBitmap) {
return NULL;
}
@@ -742,8 +693,8 @@
SkBitmap src;
reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src);
SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle);
- SkBitmap result;
- JavaPixelAllocator allocator(env);
+ SkBitmap result;
+ HeapAllocator allocator;
if (!src.copyTo(&result, dstCT, &allocator)) {
return NULL;
@@ -798,8 +749,7 @@
}
static void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle,
- jint width, jint height, jint configHandle, jint allocSize,
- jboolean requestPremul) {
+ jint width, jint height, jint configHandle, jboolean requestPremul) {
LocalScopedBitmap bitmap(bitmapHandle);
SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle);
@@ -807,8 +757,8 @@
if (colorType == kARGB_4444_SkColorType) {
colorType = kN32_SkColorType;
}
-
- if (width * height * SkColorTypeBytesPerPixel(colorType) > allocSize) {
+ size_t requestedSize = width * height * SkColorTypeBytesPerPixel(colorType);
+ if (requestedSize > bitmap->getAllocationByteCount()) {
// done in native as there's no way to get BytesPerPixel in Java
doThrowIAE(env, "Bitmap not large enough to support new configuration");
return;
@@ -1053,7 +1003,7 @@
#endif
// Copy the pixels into a new buffer.
- nativeBitmap = GraphicsJNI::allocateJavaPixelRef(env, bitmap.get(), ctable);
+ nativeBitmap = GraphicsJNI::allocateHeapPixelRef(bitmap.get(), ctable);
SkSafeUnref(ctable);
if (!nativeBitmap) {
blob.release();
@@ -1165,7 +1115,7 @@
const android::Paint* paint = reinterpret_cast<android::Paint*>(paintHandle);
SkIPoint offset;
SkBitmap dst;
- JavaPixelAllocator allocator(env);
+ HeapAllocator allocator;
src.extractAlpha(&dst, paint, &allocator, &offset);
// If Skia can't allocate pixels for destination bitmap, it resets
@@ -1370,6 +1320,11 @@
android::uirenderer::renderthread::RenderProxy::prepareToDraw(bitmap);
}
+static jint Bitmap_getAllocationByteCount(JNIEnv* env, jobject, jlong bitmapPtr) {
+ LocalScopedBitmap bitmapHandle(bitmapPtr);
+ return static_cast<jint>(bitmapHandle->getAllocationByteCount());
+}
+
///////////////////////////////////////////////////////////////////////////////
static const JNINativeMethod gBitmapMethods[] = {
@@ -1383,7 +1338,7 @@
(void*)Bitmap_copyAshmemConfig },
{ "nativeGetNativeFinalizer", "()J", (void*)Bitmap_getNativeFinalizer },
{ "nativeRecycle", "(J)Z", (void*)Bitmap_recycle },
- { "nativeReconfigure", "(JIIIIZ)V", (void*)Bitmap_reconfigure },
+ { "nativeReconfigure", "(JIIIZ)V", (void*)Bitmap_reconfigure },
{ "nativeCompress", "(JIILjava/io/OutputStream;[B)Z",
(void*)Bitmap_compress },
{ "nativeErase", "(JI)V", (void*)Bitmap_erase },
@@ -1414,6 +1369,7 @@
{ "nativeSameAs", "(JJ)Z", (void*)Bitmap_sameAs },
{ "nativeRefPixelRef", "(J)J", (void*)Bitmap_refPixelRef },
{ "nativePrepareToDraw", "(J)V", (void*)Bitmap_prepareToDraw },
+ { "nativeGetAllocationByteCount", "(J)I", (void*)Bitmap_getAllocationByteCount },
};
int register_android_graphics_Bitmap(JNIEnv* env)
diff --git a/core/jni/android/graphics/Bitmap.h b/core/jni/android/graphics/Bitmap.h
index aaea178..9ae1f3f 100644
--- a/core/jni/android/graphics/Bitmap.h
+++ b/core/jni/android/graphics/Bitmap.h
@@ -28,7 +28,7 @@
enum class PixelStorageType {
Invalid,
External,
- Java,
+ Heap,
Ashmem,
};
@@ -47,8 +47,8 @@
*/
class Bitmap {
public:
- Bitmap(JNIEnv* env, jbyteArray storageObj, void* address,
- const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
+ Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes,
+ SkColorTable* ctable);
Bitmap(void* address, void* context, FreeFunc freeFunc,
const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info,
@@ -56,12 +56,6 @@
const SkImageInfo& info() const;
- // Returns nullptr if it is not backed by a jbyteArray
- jbyteArray javaByteArray() const {
- return mPixelStorageType == PixelStorageType::Java
- ? mPixelStorage.java.jstrongRef : nullptr;
- }
-
int width() const { return info().width(); }
int height() const { return info().height(); }
size_t rowBytes() const;
@@ -81,6 +75,7 @@
bool hasHardwareMipMap();
void setHasHardwareMipMap(bool hasMipMap);
int getAshmemFd() const;
+ size_t getAllocationByteCount() const;
private:
friend class WrappedPixelRef;
@@ -90,8 +85,6 @@
void onStrongRefDestroyed();
void pinPixelsLocked();
- void unpinPixelsLocked();
- JNIEnv* jniEnv();
bool shouldDisposeSelfLocked();
void assertValid() const;
SkPixelRef* refPixelRefLocked();
@@ -114,10 +107,9 @@
size_t size;
} ashmem;
struct {
- JavaVM* jvm;
- jweak jweakRef;
- jbyteArray jstrongRef;
- } java;
+ void* address;
+ size_t size;
+ } heap;
} mPixelStorage;
};
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 77799d6..5a540ce 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -193,7 +193,7 @@
bitmap->setPixelRef(mBitmap->refPixelRef())->unref();
// since we're already allocated, we lockPixels right away
- // HeapAllocator/JavaPixelAllocator behaves this way too
+ // HeapAllocator behaves this way too
bitmap->lockPixels();
return true;
}
@@ -339,7 +339,7 @@
}
}
- JavaPixelAllocator javaAllocator(env);
+ HeapAllocator defaultAllocator;
RecyclingPixelAllocator recyclingAllocator(reuseBitmap, existingBufferSize);
ScaleCheckingAllocator scaleCheckingAllocator(scale, existingBufferSize);
SkBitmap::HeapAllocator heapAllocator;
@@ -353,10 +353,10 @@
decodeAllocator = &recyclingAllocator;
} else if (willScale) {
// This will allocate pixels using a HeapAllocator, since there will be an extra
- // scaling step that copies these pixels into Java memory.
+ // scaling step.
decodeAllocator = &heapAllocator;
} else {
- decodeAllocator = &javaAllocator;
+ decodeAllocator = &defaultAllocator;
}
// Set the decode colorType. This is necessary because we can't always support
@@ -412,7 +412,7 @@
// Use SkAndroidCodec to perform the decode.
SkAndroidCodec::AndroidOptions codecOptions;
- codecOptions.fZeroInitialized = (decodeAllocator == &javaAllocator) ?
+ codecOptions.fZeroInitialized = decodeAllocator == &defaultAllocator ?
SkCodec::kYes_ZeroInitialized : SkCodec::kNo_ZeroInitialized;
codecOptions.fColorPtr = colorPtr;
codecOptions.fColorCount = colorCount;
@@ -477,7 +477,7 @@
if (javaBitmap != nullptr) {
outputAllocator = &recyclingAllocator;
} else {
- outputAllocator = &javaAllocator;
+ outputAllocator = &defaultAllocator;
}
SkColorType scaledColorType = colorTypeForScaledOutput(decodingBitmap.colorType());
@@ -540,7 +540,7 @@
if (isPremultiplied) bitmapCreateFlags |= GraphicsJNI::kBitmapCreateFlag_Premultiplied;
// now create the java bitmap
- return GraphicsJNI::createBitmap(env, javaAllocator.getStorageObjAndReset(),
+ return GraphicsJNI::createBitmap(env, defaultAllocator.getStorageObjAndReset(),
bitmapCreateFlags, ninePatchChunk, ninePatchInsets, -1);
}
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index 970001a..21850bd 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -161,13 +161,13 @@
// Set up the pixel allocator
SkBRDAllocator* allocator = nullptr;
RecyclingClippingPixelAllocator recycleAlloc(recycledBitmap, recycledBytes);
- JavaPixelAllocator javaAlloc(env);
+ HeapAllocator heapAlloc;
if (javaBitmap) {
allocator = &recycleAlloc;
// We are required to match the color type of the recycled bitmap.
colorType = recycledBitmap->info().colorType();
} else {
- allocator = &javaAlloc;
+ allocator = &heapAlloc;
}
// Decode the region.
@@ -200,7 +200,7 @@
if (!requireUnpremul) {
bitmapCreateFlags |= GraphicsJNI::kBitmapCreateFlag_Premultiplied;
}
- return GraphicsJNI::createBitmap(env, javaAlloc.getStorageObjAndReset(), bitmapCreateFlags);
+ return GraphicsJNI::createBitmap(env, heapAlloc.getStorageObjAndReset(), bitmapCreateFlags);
}
static jint nativeGetHeight(JNIEnv* env, jobject, jlong brdHandle) {
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index c6a51e8..8cee814 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -416,9 +416,8 @@
assert_premultiplied(bitmap->info(), isPremultiplied);
jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
- reinterpret_cast<jlong>(bitmap), bitmap->javaByteArray(),
- bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied,
- ninePatchChunk, ninePatchInsets);
+ reinterpret_cast<jlong>(bitmap), bitmap->width(), bitmap->height(), density, isMutable,
+ isPremultiplied, ninePatchChunk, ninePatchInsets);
hasException(env); // For the side effect of logging.
return obj;
}
@@ -483,37 +482,28 @@
return true;
}
-android::Bitmap* GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
- SkColorTable* ctable) {
+android::Bitmap* GraphicsJNI::allocateHeapPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
const SkImageInfo& info = bitmap->info();
if (info.colorType() == kUnknown_SkColorType) {
- doThrowIAE(env, "unknown bitmap configuration");
- return NULL;
+ LOG_ALWAYS_FATAL("unknown bitmap configuration");
+ return nullptr;
}
size_t size;
if (!computeAllocationSize(*bitmap, &size)) {
- return NULL;
+ return nullptr;
}
// we must respect the rowBytes value already set on the bitmap instead of
// attempting to compute our own.
const size_t rowBytes = bitmap->rowBytes();
- jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime,
- gVMRuntime_newNonMovableArray,
- gByte_class, size);
- if (env->ExceptionCheck() != 0) {
- return NULL;
+ void* addr = calloc(size, 1);
+ if (!addr) {
+ return nullptr;
}
- SkASSERT(arrayObj);
- jbyte* addr = (jbyte*) env->CallLongMethod(gVMRuntime, gVMRuntime_addressOf, arrayObj);
- if (env->ExceptionCheck() != 0) {
- return NULL;
- }
- SkASSERT(addr);
- android::Bitmap* wrapper = new android::Bitmap(env, arrayObj, (void*) addr,
- info, rowBytes, ctable);
+
+ android::Bitmap* wrapper = new android::Bitmap(addr, size, info, rowBytes, ctable);
wrapper->getSkBitmap(bitmap);
// since we're already allocated, we lockPixels right away
// HeapAllocator behaves this way too
@@ -658,21 +648,16 @@
///////////////////////////////////////////////////////////////////////////////
-JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env) {
- LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&mJavaVM) != JNI_OK,
- "env->GetJavaVM failed");
-}
+HeapAllocator::HeapAllocator() {}
-JavaPixelAllocator::~JavaPixelAllocator() {
+HeapAllocator::~HeapAllocator() {
if (mStorage) {
mStorage->detachFromJava();
}
}
-bool JavaPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
- JNIEnv* env = vm2env(mJavaVM);
-
- mStorage = GraphicsJNI::allocateJavaPixelRef(env, bitmap, ctable);
+bool HeapAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
+ mStorage = GraphicsJNI::allocateHeapPixelRef(bitmap, ctable);
return mStorage != nullptr;
}
@@ -830,7 +815,7 @@
gBitmap_class = make_globalref(env, "android/graphics/Bitmap");
gBitmap_nativePtr = getFieldIDCheck(env, gBitmap_class, "mNativePtr", "J");
- gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>", "(J[BIIIZZ[BLandroid/graphics/NinePatch$InsetStruct;)V");
+ gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>", "(JIIIZZ[BLandroid/graphics/NinePatch$InsetStruct;)V");
gBitmap_reinitMethodID = env->GetMethodID(gBitmap_class, "reinit", "(IIZ)V");
gBitmap_getAllocationByteCountMethodID = env->GetMethodID(gBitmap_class, "getAllocationByteCount", "()I");
gBitmapRegionDecoder_class = make_globalref(env, "android/graphics/BitmapRegionDecoder");
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 89636db..738ad54 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -93,8 +93,7 @@
static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap);
- static android::Bitmap* allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
- SkColorTable* ctable);
+ static android::Bitmap* allocateHeapPixelRef(SkBitmap* bitmap, SkColorTable* ctable);
static android::Bitmap* allocateAshmemPixelRef(JNIEnv* env, SkBitmap* bitmap,
SkColorTable* ctable);
@@ -119,15 +118,10 @@
const SkBitmap& dstBitmap);
};
-/** Allocator which allocates the backing buffer in the Java heap.
- * Instances can only be used to perform a single allocation, which helps
- * ensure that the allocated buffer is properly accounted for with a
- * reference in the heap (or a JNI global reference).
- */
-class JavaPixelAllocator : public SkBRDAllocator {
+class HeapAllocator : public SkBRDAllocator {
public:
- explicit JavaPixelAllocator(JNIEnv* env);
- ~JavaPixelAllocator();
+ HeapAllocator();
+ ~HeapAllocator();
virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) override;
@@ -140,14 +134,8 @@
return result;
};
- /**
- * Indicates that this allocator allocates zero initialized
- * memory.
- */
SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kYes_ZeroInitialized; }
-
private:
- JavaVM* mJavaVM;
android::Bitmap* mStorage = nullptr;
};
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 49721cf..7ce750d 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -48,11 +48,6 @@
// pixel data.
private static final long NATIVE_ALLOCATION_SIZE = 32;
- /**
- * Backing buffer for the Bitmap.
- */
- private byte[] mBuffer;
-
// Convenience for JNI access
private final long mNativePtr;
@@ -108,7 +103,7 @@
* int (pointer).
*/
// called from JNI
- Bitmap(long nativeBitmap, byte[] buffer, int width, int height, int density,
+ Bitmap(long nativeBitmap, int width, int height, int density,
boolean isMutable, boolean requestPremultiplied,
byte[] ninePatchChunk, NinePatch.InsetStruct ninePatchInsets) {
if (nativeBitmap == 0) {
@@ -119,7 +114,6 @@
mHeight = height;
mIsMutable = isMutable;
mRequestPremultiplied = requestPremultiplied;
- mBuffer = buffer;
mNinePatchChunk = ninePatchChunk;
mNinePatchInsets = ninePatchInsets;
@@ -128,10 +122,7 @@
}
mNativePtr = nativeBitmap;
- long nativeSize = NATIVE_ALLOCATION_SIZE;
- if (buffer == null) {
- nativeSize += getByteCount();
- }
+ long nativeSize = NATIVE_ALLOCATION_SIZE + getAllocationByteCount();
NativeAllocationRegistry registry = new NativeAllocationRegistry(
Bitmap.class.getClassLoader(), nativeGetNativeFinalizer(), nativeSize);
registry.registerNativeAllocation(this, nativeBitmap);
@@ -256,12 +247,8 @@
if (!isMutable()) {
throw new IllegalStateException("only mutable bitmaps may be reconfigured");
}
- if (mBuffer == null) {
- throw new IllegalStateException("native-backed bitmaps may not be reconfigured");
- }
- nativeReconfigure(mNativePtr, width, height, config.nativeInt,
- mBuffer.length, mRequestPremultiplied);
+ nativeReconfigure(mNativePtr, width, height, config.nativeInt, mRequestPremultiplied);
mWidth = width;
mHeight = height;
}
@@ -343,7 +330,6 @@
// false indicates that it is still in use at the native level and these
// objects should not be collected now. They will be collected later when the
// Bitmap itself is collected.
- mBuffer = null;
mNinePatchChunk = null;
}
mRecycled = true;
@@ -1273,12 +1259,7 @@
* @see #reconfigure(int, int, Config)
*/
public final int getAllocationByteCount() {
- if (mBuffer == null) {
- // native backed bitmaps don't support reconfiguration,
- // so alloc size is always content size
- return getByteCount();
- }
- return mBuffer.length;
+ return nativeGetAllocationByteCount(mNativePtr);
}
/**
@@ -1695,8 +1676,7 @@
private static native long nativeGetNativeFinalizer();
private static native boolean nativeRecycle(long nativeBitmap);
private static native void nativeReconfigure(long nativeBitmap, int width, int height,
- int config, int allocSize,
- boolean isPremultiplied);
+ int config, boolean isPremultiplied);
private static native boolean nativeCompress(long nativeBitmap, int format,
int quality, OutputStream stream,
@@ -1742,4 +1722,5 @@
private static native boolean nativeSameAs(long nativeBitmap0, long nativeBitmap1);
private static native long nativeRefPixelRef(long nativeBitmap);
private static native void nativePrepareToDraw(long nativeBitmap);
+ private static native int nativeGetAllocationByteCount(long nativeBitmap);
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index f1da3a2..bcfe3bf 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -627,7 +627,7 @@
boolean isPremultiplied = createFlags.contains(BitmapCreateFlags.PREMULTIPLIED);
// and create/return a new Bitmap with it
- return new Bitmap(nativeInt, null /* buffer */, width, height, density, isMutable,
+ return new Bitmap(nativeInt, width, height, density, isMutable,
isPremultiplied, null /*ninePatchChunk*/, null /* layoutBounds */);
}