Skip to content

Commit 74261d8

Browse files
chethaaseAndroid (Google) Code Review
authored andcommitted
Merge "Don't null the reference to Bitmap pixels until we're really ready" into jb-mr1-dev
2 parents 5be5967 + 547e665 commit 74261d8

File tree

4 files changed

+31
-15
lines changed

4 files changed

+31
-15
lines changed

core/jni/android/graphics/Bitmap.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,14 @@ static void Bitmap_destructor(JNIEnv* env, jobject, SkBitmap* bitmap) {
261261
delete bitmap;
262262
}
263263

264-
static void Bitmap_recycle(JNIEnv* env, jobject, SkBitmap* bitmap) {
264+
static jboolean Bitmap_recycle(JNIEnv* env, jobject, SkBitmap* bitmap) {
265265
#ifdef USE_OPENGL_RENDERER
266266
if (android::uirenderer::Caches::hasInstance()) {
267-
android::uirenderer::Caches::getInstance().resourceCache.recycle(bitmap);
268-
return;
267+
return android::uirenderer::Caches::getInstance().resourceCache.recycle(bitmap);
269268
}
270269
#endif // USE_OPENGL_RENDERER
271270
bitmap->setPixels(NULL, NULL);
271+
return true;
272272
}
273273

274274
// These must match the int values in Bitmap.java
@@ -665,7 +665,7 @@ static JNINativeMethod gBitmapMethods[] = {
665665
{ "nativeCopy", "(IIZ)Landroid/graphics/Bitmap;",
666666
(void*)Bitmap_copy },
667667
{ "nativeDestructor", "(I)V", (void*)Bitmap_destructor },
668-
{ "nativeRecycle", "(I)V", (void*)Bitmap_recycle },
668+
{ "nativeRecycle", "(I)Z", (void*)Bitmap_recycle },
669669
{ "nativeCompress", "(IIILjava/io/OutputStream;[B)Z",
670670
(void*)Bitmap_compress },
671671
{ "nativeErase", "(II)V", (void*)Bitmap_erase },

graphics/java/android/graphics/Bitmap.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,14 @@ public void setLayoutBounds(int[] bounds) {
201201
*/
202202
public void recycle() {
203203
if (!mRecycled) {
204-
mBuffer = null;
205-
nativeRecycle(mNativeBitmap);
206-
mNinePatchChunk = null;
204+
if (nativeRecycle(mNativeBitmap)) {
205+
// return value indicates whether native pixel object was actually recycled.
206+
// false indicates that it is still in use at the native level and these
207+
// objects should not be collected now. They will be collected later when the
208+
// Bitmap itself is collected.
209+
mBuffer = null;
210+
mNinePatchChunk = null;
211+
}
207212
mRecycled = true;
208213
}
209214
}
@@ -1391,7 +1396,7 @@ private static native Bitmap nativeCreate(int[] colors, int offset,
13911396
private static native Bitmap nativeCopy(int srcBitmap, int nativeConfig,
13921397
boolean isMutable);
13931398
private static native void nativeDestructor(int nativeBitmap);
1394-
private static native void nativeRecycle(int nativeBitmap);
1399+
private static native boolean nativeRecycle(int nativeBitmap);
13951400

13961401
private static native boolean nativeCompress(int nativeBitmap, int format,
13971402
int quality, OutputStream stream,

libs/hwui/ResourceCache.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,27 +265,38 @@ void ResourceCache::destructorLocked(SkiaColorFilter* resource) {
265265
}
266266
}
267267

268-
void ResourceCache::recycle(SkBitmap* resource) {
268+
/**
269+
* Return value indicates whether resource was actually recycled, which happens when RefCnt
270+
* reaches 0.
271+
*/
272+
bool ResourceCache::recycle(SkBitmap* resource) {
269273
Mutex::Autolock _l(mLock);
270-
recycleLocked(resource);
274+
return recycleLocked(resource);
271275
}
272276

273-
void ResourceCache::recycleLocked(SkBitmap* resource) {
277+
/**
278+
* Return value indicates whether resource was actually recycled, which happens when RefCnt
279+
* reaches 0.
280+
*/
281+
bool ResourceCache::recycleLocked(SkBitmap* resource) {
274282
ssize_t index = mCache->indexOfKey(resource);
275283
if (index < 0) {
276284
// not tracking this resource; just recycle the pixel data
277285
resource->setPixels(NULL, NULL);
278-
return;
286+
return true;
279287
}
280288
ResourceReference* ref = mCache->valueAt(index);
281289
if (ref == NULL) {
282290
// Should not get here - shouldn't get a call to recycle if we're not yet tracking it
283-
return;
291+
return true;
284292
}
285293
ref->recycled = true;
286294
if (ref->refCount == 0) {
287295
deleteResourceReferenceLocked(resource, ref);
296+
return true;
288297
}
298+
// Still referring to resource, don't recycle yet
299+
return false;
289300
}
290301

291302
/**

libs/hwui/ResourceCache.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ class ANDROID_API ResourceCache {
9999
void destructorLocked(SkiaShader* resource);
100100
void destructorLocked(SkiaColorFilter* resource);
101101

102-
void recycle(SkBitmap* resource);
103-
void recycleLocked(SkBitmap* resource);
102+
bool recycle(SkBitmap* resource);
103+
bool recycleLocked(SkBitmap* resource);
104104

105105
private:
106106
void deleteResourceReferenceLocked(void* resource, ResourceReference* ref);

0 commit comments

Comments
 (0)