summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2014-12-04 21:46:39 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2014-12-04 21:46:39 +0000
commit203c8171806a15b83efa9ad56be048281a40693b (patch)
tree6f0192f56d548718f231c275c6d2aa6a5ee64929
parent51347595a3ea7749b2c771ac1e8f8f729a55e1a9 (diff)
parentc1a2f38ce0447b005d0cde6836857f451af84dc6 (diff)
downloadframeworks_base-203c8171806a15b83efa9ad56be048281a40693b.zip
frameworks_base-203c8171806a15b83efa9ad56be048281a40693b.tar.gz
frameworks_base-203c8171806a15b83efa9ad56be048281a40693b.tar.bz2
am c1a2f38c: am 4d9da135: Merge "Update AndroidPixelRef to prevent VM from cleaning up memory prematurely." into lmp-mr1-dev
* commit 'c1a2f38ce0447b005d0cde6836857f451af84dc6': Update AndroidPixelRef to prevent VM from cleaning up memory prematurely.
-rw-r--r--core/java/android/view/GLES20Canvas.java27
-rw-r--r--core/jni/android/graphics/Graphics.cpp106
-rw-r--r--core/jni/android/graphics/GraphicsJNI.h41
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp35
-rw-r--r--graphics/java/android/graphics/Bitmap.java7
5 files changed, 30 insertions, 186 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 9061679..60a489b 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -558,7 +558,7 @@ class GLES20Canvas extends HardwareCanvas {
Bitmap bitmap = patch.getBitmap();
throwIfCannotDraw(bitmap);
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
+ nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
}
@@ -567,32 +567,31 @@ class GLES20Canvas extends HardwareCanvas {
Bitmap bitmap = patch.getBitmap();
throwIfCannotDraw(bitmap);
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
+ nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
}
- private static native void nDrawPatch(long renderer, long bitmap, byte[] buffer, long chunk,
+ private static native void nDrawPatch(long renderer, long bitmap, long chunk,
float left, float top, float right, float bottom, long paint);
@Override
public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
throwIfCannotDraw(bitmap);
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint);
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, nativePaint);
}
- private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer,
- float left, float top, long paint);
+ private static native void nDrawBitmap(long renderer, long bitmap, float left,
+ float top, long paint);
@Override
public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
throwIfCannotDraw(bitmap);
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer,
- matrix.native_instance, nativePaint);
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, matrix.native_instance, nativePaint);
}
- private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer,
+ private static native void nDrawBitmap(long renderer, long bitmap,
long matrix, long paint);
@Override
@@ -612,7 +611,7 @@ class GLES20Canvas extends HardwareCanvas {
bottom = src.bottom;
}
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
}
@@ -633,11 +632,11 @@ class GLES20Canvas extends HardwareCanvas {
bottom = src.bottom;
}
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
}
- private static native void nDrawBitmap(long renderer, long bitmap, byte[] buffer,
+ private static native void nDrawBitmap(long renderer, long bitmap,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float left, float top, float right, float bottom, long paint);
@@ -698,11 +697,11 @@ class GLES20Canvas extends HardwareCanvas {
}
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
+ nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, meshWidth, meshHeight,
verts, vertOffset, colors, colorOffset, nativePaint);
}
- private static native void nDrawBitmapMesh(long renderer, long bitmap, byte[] buffer,
+ private static native void nDrawBitmapMesh(long renderer, long bitmap,
int meshWidth, int meshHeight, float[] verts, int vertOffset,
int[] colors, int colorOffset, long paint);
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 2eccfbd..a51af40 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -492,19 +492,15 @@ AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* sto
SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)),
fWrappedPixelRef(NULL) {
SkASSERT(storage);
+ SkASSERT(storageObj);
SkASSERT(env);
if (env->GetJavaVM(&fVM) != JNI_OK) {
SkDebugf("------ [%p] env->GetJavaVM failed\n", env);
sk_throw();
}
- fStorageObj = storageObj;
- fHasGlobalRef = false;
- fGlobalRefCnt = 0;
-
- // If storageObj is NULL, the memory was NOT allocated on the Java heap
- fOnJavaHeap = (storageObj != NULL);
+ fStorageObj = (jbyteArray) env->NewGlobalRef(storageObj);
}
AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
@@ -516,91 +512,18 @@ AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImage
SkASSERT(fWrappedPixelRef);
SkSafeRef(fWrappedPixelRef);
- // don't need to initialize these, as all the relevant logic delegates to the wrapped ref
+ // don't need to initialize this, as all the relevant logic delegates to the wrapped ref
fStorageObj = NULL;
- fHasGlobalRef = false;
- fGlobalRefCnt = 0;
- fOnJavaHeap = false;
}
AndroidPixelRef::~AndroidPixelRef() {
if (fWrappedPixelRef) {
SkSafeUnref(fWrappedPixelRef);
- } else if (fOnJavaHeap) {
+ } else {
+ SkASSERT(fStorageObj);
JNIEnv* env = vm2env(fVM);
-
- if (fStorageObj && fHasGlobalRef) {
- env->DeleteGlobalRef(fStorageObj);
- }
- fStorageObj = NULL;
- }
-}
-jbyteArray AndroidPixelRef::getStorageObj() {
- if (fWrappedPixelRef) {
- return fWrappedPixelRef->fStorageObj;
- }
- return fStorageObj;
-}
-
-void AndroidPixelRef::setLocalJNIRef(jbyteArray arr) {
- if (fWrappedPixelRef) {
- // delegate java obj management to the wrapped ref
- fWrappedPixelRef->setLocalJNIRef(arr);
- } else if (!fHasGlobalRef) {
- fStorageObj = arr;
- }
-}
-
-void AndroidPixelRef::globalRef(void* localref) {
- if (fWrappedPixelRef) {
- // delegate java obj management to the wrapped ref
- fWrappedPixelRef->globalRef(localref);
-
- // Note: we only ref and unref the wrapped AndroidPixelRef so that
- // bitmap->pixelRef()->globalRef() and globalUnref() can be used in a pair, even if
- // the bitmap has its underlying AndroidPixelRef swapped out/wrapped
- return;
- }
- if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) {
- JNIEnv *env = vm2env(fVM);
-
- // If JNI ref was passed, it is always used
- if (localref) fStorageObj = (jbyteArray) localref;
-
- if (fStorageObj == NULL) {
- SkDebugf("No valid local ref to create a JNI global ref\n");
- sk_throw();
- }
- if (fHasGlobalRef) {
- // This should never happen
- SkDebugf("Already holding a JNI global ref");
- sk_throw();
- }
-
- fStorageObj = (jbyteArray) env->NewGlobalRef(fStorageObj);
- // TODO: Check for failure here
- fHasGlobalRef = true;
- }
- ref();
-}
-
-void AndroidPixelRef::globalUnref() {
- if (fWrappedPixelRef) {
- // delegate java obj management to the wrapped ref
- fWrappedPixelRef->globalUnref();
- return;
- }
- if (fOnJavaHeap && sk_atomic_dec(&fGlobalRefCnt) == 1) {
- JNIEnv *env = vm2env(fVM);
- if (!fHasGlobalRef) {
- SkDebugf("We don't have a global ref!");
- sk_throw();
- }
env->DeleteGlobalRef(fStorageObj);
- fStorageObj = NULL;
- fHasGlobalRef = false;
}
- unref();
}
///////////////////////////////////////////////////////////////////////////////
@@ -657,25 +580,6 @@ bool JavaPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
////////////////////////////////////////////////////////////////////////////////
-JavaHeapBitmapRef::JavaHeapBitmapRef(JNIEnv* env, SkBitmap* nativeBitmap, jbyteArray buffer) {
- fEnv = env;
- fNativeBitmap = nativeBitmap;
- fBuffer = buffer;
-
- // If the buffer is NULL, the backing memory wasn't allocated on the Java heap
- if (fBuffer) {
- ((AndroidPixelRef*) fNativeBitmap->pixelRef())->setLocalJNIRef(fBuffer);
- }
-}
-
-JavaHeapBitmapRef::~JavaHeapBitmapRef() {
- if (fBuffer) {
- ((AndroidPixelRef*) fNativeBitmap->pixelRef())->setLocalJNIRef(NULL);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
static jclass make_globalref(JNIEnv* env, const char classname[])
{
jclass c = env->FindClass(classname);
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 0ce6e49..a48b764 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -123,52 +123,11 @@ public:
virtual ~AndroidPixelRef();
- jbyteArray getStorageObj();
-
- void setLocalJNIRef(jbyteArray arr);
-
- /** Used to hold a ref to the pixels when the Java bitmap may be collected.
- * If specified, 'localref' is a valid JNI local reference to the byte array
- * containing the pixel data.
- *
- * 'localref' may only be NULL if setLocalJNIRef() was already called with
- * a JNI local ref that is still valid.
- */
- virtual void globalRef(void* localref=NULL);
-
- /** Release a ref that was acquired using globalRef(). */
- 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
-
jbyteArray fStorageObj; // The Java byte[] object used as the bitmap backing store
- bool fHasGlobalRef; // If true, fStorageObj holds a JNI global ref
-
- mutable int32_t fGlobalRefCnt;
-};
-
-/** A helper class for accessing Java-heap-allocated bitmaps.
- * This should be used when calling into a JNI method that retains a
- * reference to the bitmap longer than the lifetime of the Java Bitmap.
- *
- * After creating an instance of this class, a call to
- * AndroidPixelRef::globalRef() will allocate a JNI global reference
- * to the backing buffer object.
- */
-class JavaHeapBitmapRef {
-public:
-
- JavaHeapBitmapRef(JNIEnv *env, SkBitmap* nativeBitmap, jbyteArray buffer);
- ~JavaHeapBitmapRef();
-
-private:
- JNIEnv* fEnv;
- SkBitmap* fNativeBitmap;
- jbyteArray fBuffer;
};
/** Allocator which allocates the backing buffer in the Java heap.
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 7a9da7e..da8a9ed 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -341,11 +341,8 @@ static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz,
// ----------------------------------------------------------------------------
static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
- jfloat left, jfloat top, jlong paintPtr) {
+ jlong rendererPtr, jlong bitmapPtr, jfloat left, jfloat top, jlong paintPtr) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
- // This object allows the renderer to allocate a global JNI ref to the buffer object.
- JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
Paint* paint = reinterpret_cast<Paint*>(paintPtr);
@@ -358,12 +355,10 @@ static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
}
static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
+ jlong rendererPtr, jlong bitmapPtr,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
- // This object allows the renderer to allocate a global JNI ref to the buffer object.
- JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
Paint* paint = reinterpret_cast<Paint*>(paintPtr);
@@ -372,11 +367,8 @@ static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
}
static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
- jlong matrixPtr, jlong paintPtr) {
+ jlong rendererPtr, jlong bitmapPtr, jlong matrixPtr, jlong paintPtr) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
- // This object allows the renderer to allocate a global JNI ref to the buffer object.
- JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
@@ -421,12 +413,9 @@ static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz,
}
static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
- jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors,
- jint colorOffset, jlong paintPtr) {
+ jlong rendererPtr, jlong bitmapPtr, jint meshWidth, jint meshHeight,
+ jfloatArray vertices, jint offset, jintArray colors, jint colorOffset, jlong paintPtr) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
- // This object allows the renderer to allocate a global JNI ref to the buffer object.
- JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL;
jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL;
@@ -440,11 +429,9 @@ static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
}
static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, jlong patchPtr,
+ jlong rendererPtr, jlong bitmapPtr, jlong patchPtr,
float left, float top, float right, float bottom, jlong paintPtr) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
- // This object allows the renderer to allocate a global JNI ref to the buffer object.
- JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr);
@@ -914,14 +901,14 @@ static JNINativeMethod gMethods[] = {
{ "nGetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_getMatrix },
{ "nConcatMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_concatMatrix },
- { "nDrawBitmap", "(JJ[BFFJ)V", (void*) android_view_GLES20Canvas_drawBitmap },
- { "nDrawBitmap", "(JJ[BFFFFFFFFJ)V",(void*) android_view_GLES20Canvas_drawBitmapRect },
- { "nDrawBitmap", "(JJ[BJJ)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix },
+ { "nDrawBitmap", "(JJFFJ)V", (void*) android_view_GLES20Canvas_drawBitmap },
+ { "nDrawBitmap", "(JJFFFFFFFFJ)V",(void*) android_view_GLES20Canvas_drawBitmapRect },
+ { "nDrawBitmap", "(JJJJ)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix },
{ "nDrawBitmap", "(J[IIIFFIIZJ)V", (void*) android_view_GLES20Canvas_drawBitmapData },
- { "nDrawBitmapMesh", "(JJ[BII[FI[IIJ)V",(void*) android_view_GLES20Canvas_drawBitmapMesh },
+ { "nDrawBitmapMesh", "(JJII[FI[IIJ)V",(void*) android_view_GLES20Canvas_drawBitmapMesh },
- { "nDrawPatch", "(JJ[BJFFFFJ)V", (void*) android_view_GLES20Canvas_drawPatch },
+ { "nDrawPatch", "(JJJFFFFJ)V", (void*) android_view_GLES20Canvas_drawPatch },
{ "nDrawColor", "(JII)V", (void*) android_view_GLES20Canvas_drawColor },
{ "nDrawRect", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawRect },
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 3090ffd..3f79c2d 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -48,13 +48,8 @@ public final class Bitmap implements Parcelable {
/**
* Backing buffer for the Bitmap.
- * Made public for quick access from drawing methods -- do NOT modify
- * from outside this class
- *
- * @hide
*/
- @SuppressWarnings("UnusedDeclaration") // native code only
- public byte[] mBuffer;
+ private byte[] mBuffer;
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
private final BitmapFinalizer mFinalizer;