diff options
author | Chih-Chung Chang <chihchung@google.com> | 2012-04-17 20:35:14 +0800 |
---|---|---|
committer | Chih-Chung Chang <chihchung@google.com> | 2012-04-18 20:31:10 +0800 |
commit | b8be1e0ad76b6abc0da7ead39f7a9811195d001e (patch) | |
tree | fd52c19ef4c77b581acd89c9599205949c371eb4 /src/com/android/gallery3d/data | |
parent | 2ae47200a8ac7a57eff925d287f7b48a2360d95c (diff) | |
download | android_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.java | 84 | ||||
-rw-r--r-- | src/com/android/gallery3d/data/DecodeUtils.java | 18 | ||||
-rw-r--r-- | src/com/android/gallery3d/data/ImageCacheRequest.java | 2 | ||||
-rw-r--r-- | src/com/android/gallery3d/data/MediaItem.java | 10 |
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; } |