summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/data
diff options
context:
space:
mode:
authorChih-Chung Chang <chihchung@google.com>2012-04-17 20:35:14 +0800
committerChih-Chung Chang <chihchung@google.com>2012-04-18 20:31:10 +0800
commitb8be1e0ad76b6abc0da7ead39f7a9811195d001e (patch)
treefd52c19ef4c77b581acd89c9599205949c371eb4 /src/com/android/gallery3d/data
parent2ae47200a8ac7a57eff925d287f7b48a2360d95c (diff)
downloadandroid_packages_apps_Gallery2-b8be1e0ad76b6abc0da7ead39f7a9811195d001e.tar.gz
android_packages_apps_Gallery2-b8be1e0ad76b6abc0da7ead39f7a9811195d001e.tar.bz2
android_packages_apps_Gallery2-b8be1e0ad76b6abc0da7ead39f7a9811195d001e.zip
Add thumb pool the cache Bitmap used for thumbnails.
Change-Id: Ib710f2a6fc1aa86fe4abdd18d1fa7ac71396a3b4
Diffstat (limited to 'src/com/android/gallery3d/data')
-rw-r--r--src/com/android/gallery3d/data/BitmapPool.java84
-rw-r--r--src/com/android/gallery3d/data/DecodeUtils.java18
-rw-r--r--src/com/android/gallery3d/data/ImageCacheRequest.java2
-rw-r--r--src/com/android/gallery3d/data/MediaItem.java10
4 files changed, 100 insertions, 14 deletions
diff --git a/src/com/android/gallery3d/data/BitmapPool.java b/src/com/android/gallery3d/data/BitmapPool.java
index c52a57b0a..0fbd84ef5 100644
--- a/src/com/android/gallery3d/data/BitmapPool.java
+++ b/src/com/android/gallery3d/data/BitmapPool.java
@@ -1,4 +1,18 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.android.gallery3d.data;
@@ -6,6 +20,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
+import com.android.gallery3d.common.Utils;
import com.android.gallery3d.ui.Log;
import com.android.gallery3d.util.ThreadPool.JobContext;
@@ -15,30 +30,63 @@ import java.util.ArrayList;
public class BitmapPool {
private static final String TAG = "BitmapPool";
- private static final int POOL_SIZE = 16;
- private final ArrayList<Bitmap> mPool = new ArrayList<Bitmap>(POOL_SIZE);
+ private final ArrayList<Bitmap> mPool;
+ private final int mPoolLimit;
- private final int mWidth;
- private final int mHeight;
+ // mOneSize is true if the pool can only cache Bitmap with one size.
+ private final boolean mOneSize;
+ private final int mWidth, mHeight; // only used if mOneSize is true
- public BitmapPool(int width, int height) {
+ // Construct a BitmapPool which caches bitmap with the specified size.
+ public BitmapPool(int width, int height, int poolLimit) {
mWidth = width;
mHeight = height;
+ mPoolLimit = poolLimit;
+ mPool = new ArrayList<Bitmap>(poolLimit);
+ mOneSize = true;
}
+ // Construct a BitmapPool which caches bitmap with any size;
+ public BitmapPool(int poolLimit) {
+ mWidth = -1;
+ mHeight = -1;
+ mPoolLimit = poolLimit;
+ mPool = new ArrayList<Bitmap>(poolLimit);
+ mOneSize = false;
+ }
+
+ // Get a Bitmap from the pool.
public synchronized Bitmap getBitmap() {
+ Utils.assertTrue(mOneSize);
int size = mPool.size();
return size > 0 ? mPool.remove(size - 1) : null;
}
+ // Get a Bitmap from the pool with the specified size.
+ public synchronized Bitmap getBitmap(int width, int height) {
+ Utils.assertTrue(!mOneSize);
+ for (int i = mPool.size() - 1; i >= 0; i--) {
+ Bitmap b = mPool.get(i);
+ if (b.getWidth() == width && b.getHeight() == height) {
+ return mPool.remove(i);
+ }
+ }
+ return null;
+ }
+
+ // Put a Bitmap into the pool, if the Bitmap has a proper size. Otherwise
+ // the Bitmap will be recycled. If the pool is full, an old Bitmap will be
+ // recycled.
public void recycle(Bitmap bitmap) {
if (bitmap == null) return;
- if ((bitmap.getWidth() != mWidth) || (bitmap.getHeight() != mHeight)) {
+ if (mOneSize && ((bitmap.getWidth() != mWidth) ||
+ (bitmap.getHeight() != mHeight))) {
bitmap.recycle();
return;
}
synchronized (this) {
- if (mPool.size() < POOL_SIZE) mPool.add(bitmap);
+ if (mPool.size() >= mPoolLimit) mPool.remove(0);
+ mPool.add(bitmap);
}
}
@@ -46,12 +94,27 @@ public class BitmapPool {
mPool.clear();
}
+ private Bitmap findCachedBitmap(JobContext jc,
+ byte[] data, int offset, int length, Options options) {
+ if (mOneSize) return getBitmap();
+ DecodeUtils.decodeBounds(jc, data, offset, length, options);
+ return getBitmap(options.outWidth, options.outHeight);
+ }
+
+ private Bitmap findCachedBitmap(JobContext jc,
+ FileDescriptor fileDescriptor, Options options) {
+ if (mOneSize) return getBitmap();
+ DecodeUtils.decodeBounds(jc, fileDescriptor, options);
+ return getBitmap(options.outWidth, options.outHeight);
+ }
+
public Bitmap decode(JobContext jc,
byte[] data, int offset, int length, BitmapFactory.Options options) {
if (options == null) options = new BitmapFactory.Options();
if (options.inSampleSize < 1) options.inSampleSize = 1;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
- options.inBitmap = (options.inSampleSize == 1) ? getBitmap() : null;
+ options.inBitmap = (options.inSampleSize == 1)
+ ? findCachedBitmap(jc, data, offset, length, options) : null;
try {
Bitmap bitmap = DecodeUtils.decode(jc, data, offset, length, options);
if (options.inBitmap != null && options.inBitmap != bitmap) {
@@ -76,7 +139,8 @@ public class BitmapPool {
if (options == null) options = new BitmapFactory.Options();
if (options.inSampleSize < 1) options.inSampleSize = 1;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
- options.inBitmap = (options.inSampleSize == 1) ? getBitmap() : null;
+ options.inBitmap = (options.inSampleSize == 1)
+ ? findCachedBitmap(jc, fileDescriptor, options) : null;
try {
Bitmap bitmap = DecodeUtils.decode(jc, fileDescriptor, options);
if (options.inBitmap != null&& options.inBitmap != bitmap) {
diff --git a/src/com/android/gallery3d/data/DecodeUtils.java b/src/com/android/gallery3d/data/DecodeUtils.java
index 319458a14..e51dc3fa9 100644
--- a/src/com/android/gallery3d/data/DecodeUtils.java
+++ b/src/com/android/gallery3d/data/DecodeUtils.java
@@ -55,6 +55,15 @@ public class DecodeUtils {
BitmapFactory.decodeFileDescriptor(fd, null, options));
}
+ public static void decodeBounds(JobContext jc, FileDescriptor fd,
+ Options options) {
+ Utils.assertTrue(options != null);
+ options.inJustDecodeBounds = true;
+ jc.setCancelListener(new DecodeCanceller(options));
+ BitmapFactory.decodeFileDescriptor(fd, null, options);
+ options.inJustDecodeBounds = false;
+ }
+
public static Bitmap decode(JobContext jc, byte[] bytes, Options options) {
return decode(jc, bytes, 0, bytes.length, options);
}
@@ -67,6 +76,15 @@ public class DecodeUtils {
BitmapFactory.decodeByteArray(bytes, offset, length, options));
}
+ public static void decodeBounds(JobContext jc, byte[] bytes, int offset,
+ int length, Options options) {
+ Utils.assertTrue(options != null);
+ options.inJustDecodeBounds = true;
+ jc.setCancelListener(new DecodeCanceller(options));
+ BitmapFactory.decodeByteArray(bytes, offset, length, options);
+ options.inJustDecodeBounds = false;
+ }
+
public static Bitmap decodeThumbnail(
JobContext jc, String filePath, Options options, int targetSize, int type) {
FileInputStream fis = null;
diff --git a/src/com/android/gallery3d/data/ImageCacheRequest.java b/src/com/android/gallery3d/data/ImageCacheRequest.java
index c10158bcd..81660c915 100644
--- a/src/com/android/gallery3d/data/ImageCacheRequest.java
+++ b/src/com/android/gallery3d/data/ImageCacheRequest.java
@@ -60,7 +60,7 @@ abstract class ImageCacheRequest implements Job<Bitmap> {
bitmap = MediaItem.getMicroThumbPool().decode(jc,
buffer.data, buffer.offset, buffer.length, options);
} else {
- bitmap = DecodeUtils.decode(jc,
+ bitmap = MediaItem.getThumbPool().decode(jc,
buffer.data, buffer.offset, buffer.length, options);
}
if (bitmap == null && !jc.isCancelled()) {
diff --git a/src/com/android/gallery3d/data/MediaItem.java b/src/com/android/gallery3d/data/MediaItem.java
index 3de70d954..f0f1af434 100644
--- a/src/com/android/gallery3d/data/MediaItem.java
+++ b/src/com/android/gallery3d/data/MediaItem.java
@@ -42,9 +42,9 @@ public abstract class MediaItem extends MediaObject {
private static final int BYTESBUFFE_POOL_SIZE = 4;
private static final int BYTESBUFFER_SIZE = 200 * 1024;
- private static final BitmapPool sMicroThumbPool =
- new BitmapPool(MICROTHUMBNAIL_TARGET_SIZE, MICROTHUMBNAIL_TARGET_SIZE);
-
+ private static final BitmapPool sMicroThumbPool = new BitmapPool(
+ MICROTHUMBNAIL_TARGET_SIZE, MICROTHUMBNAIL_TARGET_SIZE, 16);
+ private static final BitmapPool sThumbPool = new BitmapPool(4);
private static final BytesBufferPool sMicroThumbBufferPool =
new BytesBufferPool(BYTESBUFFE_POOL_SIZE, BYTESBUFFER_SIZE);
@@ -122,6 +122,10 @@ public abstract class MediaItem extends MediaObject {
return sMicroThumbPool;
}
+ public static BitmapPool getThumbPool() {
+ return sThumbPool;
+ }
+
public static BytesBufferPool getBytesBufferPool() {
return sMicroThumbBufferPool;
}