summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/jni/android/graphics/BitmapFactory.cpp26
1 files changed, 14 insertions, 12 deletions
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index a7a9266..016c11e 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -296,23 +296,11 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
SkAutoTDelete<SkBitmap> adb(outputBitmap == NULL ? new SkBitmap : NULL);
if (outputBitmap == NULL) outputBitmap = adb.get();
- SkAutoTDelete<SkImageDecoder> add(decoder);
-
NinePatchPeeker peeker(decoder);
decoder->setPeeker(&peeker);
- AutoDecoderCancel adc(options, decoder);
-
- // To fix the race condition in case "requestCancelDecode"
- // happens earlier than AutoDecoderCancel object is added
- // to the gAutoDecoderCancelMutex linked list.
- if (options != NULL && env->GetBooleanField(options, gOptions_mCancelID)) {
- return nullObjectReturn("gOptions_mCancelID");
- }
-
SkImageDecoder::Mode decodeMode = isPurgeable ? SkImageDecoder::kDecodeBounds_Mode : mode;
-
JavaPixelAllocator javaAllocator(env);
RecyclingPixelAllocator recyclingAllocator(outputBitmap->pixelRef(), existingBufferSize);
ScaleCheckingAllocator scaleCheckingAllocator(scale, existingBufferSize);
@@ -328,6 +316,20 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
}
}
+ // Only setup the decoder to be deleted after its stack-based, refcounted
+ // components (allocators, peekers, etc) are declared. This prevents RefCnt
+ // asserts from firing due to the order objects are deleted from the stack.
+ SkAutoTDelete<SkImageDecoder> add(decoder);
+
+ AutoDecoderCancel adc(options, decoder);
+
+ // To fix the race condition in case "requestCancelDecode"
+ // happens earlier than AutoDecoderCancel object is added
+ // to the gAutoDecoderCancelMutex linked list.
+ if (options != NULL && env->GetBooleanField(options, gOptions_mCancelID)) {
+ return nullObjectReturn("gOptions_mCancelID");
+ }
+
SkBitmap decodingBitmap;
if (!decoder->decode(stream, &decodingBitmap, prefConfig, decodeMode)) {
return nullObjectReturn("decoder->decode returned false");