summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2015-04-23 22:59:16 (GMT)
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-04-23 22:59:16 (GMT)
commit3ed91a812dc34b1a8a594322aaff5d9df0467d3f (patch)
treead517ddb89299194bc437fe941baa63a9edea009
parent33817eaefa27af45f0e25358ff36a09a4843aab8 (diff)
parent38f3678fe9ee5e050af1587a525dadc40f526a51 (diff)
downloadandroid_frameworks_ex-3ed91a812dc34b1a8a594322aaff5d9df0467d3f.zip
android_frameworks_ex-3ed91a812dc34b1a8a594322aaff5d9df0467d3f.tar.gz
android_frameworks_ex-3ed91a812dc34b1a8a594322aaff5d9df0467d3f.tar.bz2
Merge "Fix race in bitmap decode vs release."
-rw-r--r--framesequence/src/android/support/rastermill/FrameSequenceDrawable.java59
1 files changed, 39 insertions, 20 deletions
diff --git a/framesequence/src/android/support/rastermill/FrameSequenceDrawable.java b/framesequence/src/android/support/rastermill/FrameSequenceDrawable.java
index af25c82..2228b1d 100644
--- a/framesequence/src/android/support/rastermill/FrameSequenceDrawable.java
+++ b/framesequence/src/android/support/rastermill/FrameSequenceDrawable.java
@@ -161,13 +161,26 @@ public class FrameSequenceDrawable extends Drawable implements Animatable, Runna
int lastFrame = nextFrame - 2;
long invalidateTimeMs = mFrameSequenceState.getFrame(nextFrame, bitmap, lastFrame);
+ boolean schedule = false;
+ Bitmap bitmapToRelease = null;
synchronized (mLock) {
- if (mNextFrameToDecode < 0 || mState != STATE_DECODING) return;
- mNextSwap = invalidateTimeMs + mLastSwap;
-
- mState = STATE_WAITING_TO_SWAP;
+ if (mDestroyed) {
+ bitmapToRelease = mBackBitmap;
+ mBackBitmap = null;
+ } else if (mNextFrameToDecode >= 0 && mState == STATE_DECODING) {
+ schedule = true;
+ mNextSwap = invalidateTimeMs + mLastSwap;
+ mState = STATE_WAITING_TO_SWAP;
+ }
+ }
+ if (schedule) {
+ scheduleSelf(FrameSequenceDrawable.this, mNextSwap);
+ }
+ if (bitmapToRelease != null) {
+ // destroy the bitmap here, since there's no safe way to get back to
+ // drawable thread - drawable is likely detached, so schedule is noop.
+ mBitmapProvider.releaseBitmap(bitmapToRelease);
}
- scheduleSelf(FrameSequenceDrawable.this, mNextSwap);
}
};
@@ -238,30 +251,31 @@ public class FrameSequenceDrawable extends Drawable implements Animatable, Runna
* If no BitmapProvider is attached to the drawable, recycle() is called on the Bitmaps.
*/
public void destroy() {
- destroy(mBitmapProvider);
- }
-
- private void destroy(BitmapProvider bitmapProvider) {
- if (bitmapProvider == null) {
+ if (mBitmapProvider == null) {
throw new IllegalStateException("BitmapProvider must be non-null");
}
Bitmap bitmapToReleaseA;
- Bitmap bitmapToReleaseB;
+ Bitmap bitmapToReleaseB = null;
synchronized (mLock) {
checkDestroyedLocked();
bitmapToReleaseA = mFrontBitmap;
- bitmapToReleaseB = mBackBitmap;
-
mFrontBitmap = null;
- mBackBitmap = null;
+
+ if (mState != STATE_DECODING) {
+ bitmapToReleaseB = mBackBitmap;
+ mBackBitmap = null;
+ }
+
mDestroyed = true;
}
// For simplicity and safety, we don't destroy the state object here
- bitmapProvider.releaseBitmap(bitmapToReleaseA);
- bitmapProvider.releaseBitmap(bitmapToReleaseB);
+ mBitmapProvider.releaseBitmap(bitmapToReleaseA);
+ if (bitmapToReleaseB != null) {
+ mBitmapProvider.releaseBitmap(bitmapToReleaseB);
+ }
}
@Override
@@ -322,12 +336,17 @@ public class FrameSequenceDrawable extends Drawable implements Animatable, Runna
@Override
public void run() {
- // set ready to swap
+ // set ready to swap as necessary
+ boolean invalidate = false;
synchronized (mLock) {
- if (mState != STATE_WAITING_TO_SWAP || mNextFrameToDecode < 0) return;
- mState = STATE_READY_TO_SWAP;
+ if (mNextFrameToDecode >= 0 && mState == STATE_WAITING_TO_SWAP) {
+ mState = STATE_READY_TO_SWAP;
+ invalidate = true;
+ }
+ }
+ if (invalidate) {
+ invalidateSelf();
}
- invalidateSelf();
}
@Override