diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/jni/android/graphics/BitmapFactory.cpp | 26 |
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"); |