aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Morrissey <davemorrissey@gmail.com>2017-11-24 12:46:45 +0000
committerDavid Morrissey <davemorrissey@gmail.com>2017-11-24 12:46:45 +0000
commit6bb6ea7b1723db9fec0642a1391c848a0e5882c6 (patch)
treeb74fcda2034270a2d17511257eca381a13b2a714
parente8c3772bd72581d06bab40be72f4bd5b2da82909 (diff)
downloadsubsampling-scale-image-view-6bb6ea7b1723db9fec0642a1391c848a0e5882c6.tar.gz
Restored enforced synchronization on BitmapRegionDecoder for SDK < 21, which did not have internal synchronization
-rw-r--r--library/src/main/java/com/davemorrissey/labs/subscaleview/decoder/SkiaImageRegionDecoder.java37
1 files changed, 24 insertions, 13 deletions
diff --git a/library/src/main/java/com/davemorrissey/labs/subscaleview/decoder/SkiaImageRegionDecoder.java b/library/src/main/java/com/davemorrissey/labs/subscaleview/decoder/SkiaImageRegionDecoder.java
index 9d216f6..28f5d80 100644
--- a/library/src/main/java/com/davemorrissey/labs/subscaleview/decoder/SkiaImageRegionDecoder.java
+++ b/library/src/main/java/com/davemorrissey/labs/subscaleview/decoder/SkiaImageRegionDecoder.java
@@ -7,10 +7,12 @@ import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.*;
import android.net.Uri;
+import android.os.Build;
import android.text.TextUtils;
import java.io.InputStream;
import java.util.List;
+import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -21,9 +23,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
* however it has some problems with grayscale, indexed and CMYK images.
*
* A {@link ReadWriteLock} is used to delegate responsibility for multi threading behaviour to the
- * {@link BitmapRegionDecoder} instance, whilst allowing this class to block until no tiles are being
- * loaded before recycling the decoder. In practice, {@link BitmapRegionDecoder} is single threaded
- * so this has no real impact on performance.
+ * {@link BitmapRegionDecoder} instance on SDK >= 21, whilst allowing this class to block until no
+ * tiles are being loaded before recycling the decoder. In practice, {@link BitmapRegionDecoder} is
+ * synchronized internally so this has no real impact on performance.
*/
public class SkiaImageRegionDecoder implements ImageRegionDecoder {
@@ -97,7 +99,7 @@ public class SkiaImageRegionDecoder implements ImageRegionDecoder {
@Override
public Bitmap decodeRegion(Rect sRect, int sampleSize) {
- decoderLock.readLock().lock();
+ getDecodeLock().lock();
try {
if (decoder != null && !decoder.isRecycled()) {
BitmapFactory.Options options = new BitmapFactory.Options();
@@ -112,27 +114,36 @@ public class SkiaImageRegionDecoder implements ImageRegionDecoder {
throw new IllegalStateException("Cannot decode region after decoder has been recycled");
}
} finally {
- decoderLock.readLock().unlock();
+ getDecodeLock().unlock();
}
}
@Override
- public boolean isReady() {
- decoderLock.readLock().lock();
- try {
- return decoder != null && !decoder.isRecycled();
- } finally {
- decoderLock.readLock().unlock();
- }
+ public synchronized boolean isReady() {
+ return decoder != null && !decoder.isRecycled();
}
@Override
- public void recycle() {
+ public synchronized void recycle() {
decoderLock.writeLock().lock();
try {
decoder.recycle();
+ decoder = null;
} finally {
decoderLock.writeLock().unlock();
}
}
+
+ /**
+ * Before SDK 21, BitmapRegionDecoder was not synchronized internally. Any attempt to decode
+ * regions from multiple threads with one decoder instance causes a segfault. For old versions
+ * use the write lock to enforce single threaded decoding.
+ */
+ private Lock getDecodeLock() {
+ if (Build.VERSION.SDK_INT < 21) {
+ return decoderLock.writeLock();
+ } else {
+ return decoderLock.readLock();
+ }
+ }
}