summaryrefslogtreecommitdiffstats
path: root/src/com
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
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')
-rw-r--r--src/com/android/gallery3d/app/AbstractGalleryActivity.java1
-rw-r--r--src/com/android/gallery3d/app/CameraScreenNail.java2
-rw-r--r--src/com/android/gallery3d/app/PhotoDataAdapter.java27
-rw-r--r--src/com/android/gallery3d/app/PhotoPage.java4
-rw-r--r--src/com/android/gallery3d/app/SinglePhotoDataAdapter.java5
-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
-rw-r--r--src/com/android/gallery3d/ui/AlbumLabelMaker.java20
-rw-r--r--src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java2
-rw-r--r--src/com/android/gallery3d/ui/BitmapScreenNail.java10
-rw-r--r--src/com/android/gallery3d/ui/BitmapTileProvider.java2
-rw-r--r--src/com/android/gallery3d/ui/PhotoView.java66
-rw-r--r--src/com/android/gallery3d/ui/PositionController.java3
-rw-r--r--src/com/android/gallery3d/ui/ScreenNail.java8
-rw-r--r--src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java2
-rw-r--r--src/com/android/gallery3d/ui/TileImageView.java16
-rw-r--r--src/com/android/gallery3d/ui/TileImageViewAdapter.java23
19 files changed, 192 insertions, 113 deletions
diff --git a/src/com/android/gallery3d/app/AbstractGalleryActivity.java b/src/com/android/gallery3d/app/AbstractGalleryActivity.java
index eddaea5cb..00f6ac5e1 100644
--- a/src/com/android/gallery3d/app/AbstractGalleryActivity.java
+++ b/src/com/android/gallery3d/app/AbstractGalleryActivity.java
@@ -178,6 +178,7 @@ public class AbstractGalleryActivity extends Activity implements GalleryActivity
mGLRootView.unlockRenderThread();
}
MediaItem.getMicroThumbPool().clear();
+ MediaItem.getThumbPool().clear();
MediaItem.getBytesBufferPool().clear();
}
diff --git a/src/com/android/gallery3d/app/CameraScreenNail.java b/src/com/android/gallery3d/app/CameraScreenNail.java
index f68ab72f8..24857a48f 100644
--- a/src/com/android/gallery3d/app/CameraScreenNail.java
+++ b/src/com/android/gallery3d/app/CameraScreenNail.java
@@ -128,7 +128,7 @@ class CameraScreenNail extends SurfaceTextureScreenNail {
}
@Override
- public void pauseDraw() {
+ public void recycle() {
mVisible = false;
}
diff --git a/src/com/android/gallery3d/app/PhotoDataAdapter.java b/src/com/android/gallery3d/app/PhotoDataAdapter.java
index 10ed8f3d0..f9979f88e 100644
--- a/src/com/android/gallery3d/app/PhotoDataAdapter.java
+++ b/src/com/android/gallery3d/app/PhotoDataAdapter.java
@@ -55,6 +55,7 @@ public class PhotoDataAdapter implements PhotoPage.Model {
private static final int MSG_LOAD_START = 1;
private static final int MSG_LOAD_FINISH = 2;
private static final int MSG_RUN_OBJECT = 3;
+ private static final int MSG_UPDATE_IMAGE_REQUESTS = 4;
private static final int MIN_LOAD_COUNT = 8;
private static final int DATA_CACHE_SIZE = 32;
@@ -143,9 +144,9 @@ public class PhotoDataAdapter implements PhotoPage.Model {
private int mSize = 0;
private Path mItemPath;
private boolean mIsActive;
+ private boolean mNeedFullImage;
public interface DataListener extends LoadingListener {
- public void onPhotoAvailable(long version, boolean fullImage);
public void onPhotoChanged(int index, Path item);
}
@@ -164,6 +165,7 @@ public class PhotoDataAdapter implements PhotoPage.Model {
mItemPath = Utils.checkNotNull(itemPath);
mCurrentIndex = indexHint;
mThreadPool = activity.getThreadPool();
+ mNeedFullImage = true;
Arrays.fill(mChanges, MediaObject.INVALID_DATA_VERSION);
@@ -183,6 +185,10 @@ public class PhotoDataAdapter implements PhotoPage.Model {
if (mDataListener != null) mDataListener.onLoadingFinished();
return;
}
+ case MSG_UPDATE_IMAGE_REQUESTS: {
+ updateImageRequests();
+ return;
+ }
default: throw new AssertionError();
}
}
@@ -211,26 +217,29 @@ public class PhotoDataAdapter implements PhotoPage.Model {
mDataListener = listener;
}
+ @Override
+ public void setNeedFullImage(boolean enabled) {
+ mNeedFullImage = enabled;
+ mMainHandler.sendEmptyMessage(MSG_UPDATE_IMAGE_REQUESTS);
+ }
+
private void updateScreenNail(long version, Future<ScreenNail> future) {
ImageEntry entry = mImageCache.get(version);
ScreenNail screenNail = future.get();
if (entry == null || entry.screenNailTask != future) {
- if (screenNail != null) screenNail.pauseDraw();
+ if (screenNail != null) screenNail.recycle();
return;
}
entry.screenNailTask = null;
+ Utils.assertTrue(entry.screenNail == null);
entry.screenNail = screenNail;
if (screenNail == null) {
entry.failToLoad = true;
}
- if (mDataListener != null) {
- mDataListener.onPhotoAvailable(version, false);
- }
-
for (int i = -SCREEN_NAIL_MAX; i <= SCREEN_NAIL_MAX; ++i) {
if (version == getVersion(mCurrentIndex + i)) {
if (i == 0) updateTileProvider(entry);
@@ -252,9 +261,6 @@ public class PhotoDataAdapter implements PhotoPage.Model {
entry.fullImageTask = null;
entry.fullImage = future.get();
if (entry.fullImage != null) {
- if (mDataListener != null) {
- mDataListener.onPhotoAvailable(version, true);
- }
if (version == getVersion(mCurrentIndex)) {
updateTileProvider(entry);
mPhotoView.notifyImageChange(0);
@@ -286,6 +292,7 @@ public class PhotoDataAdapter implements PhotoPage.Model {
for (ImageEntry entry : mImageCache.values()) {
if (entry.fullImageTask != null) entry.fullImageTask.cancel();
if (entry.screenNailTask != null) entry.screenNailTask.cancel();
+ if (entry.screenNail != null) entry.screenNail.recycle();
}
mImageCache.clear();
mTileProvider.clear();
@@ -457,6 +464,7 @@ public class PhotoDataAdapter implements PhotoPage.Model {
for (int i = 0; i < sImageFetchSeq.length; i++) {
int offset = sImageFetchSeq[i].indexOffset;
int bit = sImageFetchSeq[i].imageBit;
+ if (bit == BIT_FULL_IMAGE && !mNeedFullImage) continue;
task = startTaskIfNeeded(currentIndex + offset, bit);
if (task != null) break;
}
@@ -570,6 +578,7 @@ public class PhotoDataAdapter implements PhotoPage.Model {
ImageEntry entry = mImageCache.remove(version);
if (entry.fullImageTask != null) entry.fullImageTask.cancel();
if (entry.screenNailTask != null) entry.screenNailTask.cancel();
+ if (entry.screenNail != null) entry.screenNail.recycle();
}
}
diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java
index 2bdf970d3..78bb34cab 100644
--- a/src/com/android/gallery3d/app/PhotoPage.java
+++ b/src/com/android/gallery3d/app/PhotoPage.java
@@ -238,10 +238,6 @@ public class PhotoPage extends ActivityState
public void onLoadingStarted() {
GalleryUtils.setSpinnerVisibility((Activity) mActivity, true);
}
-
- @Override
- public void onPhotoAvailable(long version, boolean fullImage) {
- }
});
} else {
// Get default media set by the URI
diff --git a/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java b/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
index 315f5b59c..59959cf4a 100644
--- a/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
+++ b/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
@@ -113,6 +113,11 @@ public class SinglePhotoDataAdapter extends TileImageViewAdapter
return mItem.getRotation();
}
+ @Override
+ public void setNeedFullImage(boolean enabled) {
+ // currently not necessary.
+ }
+
private void onDecodeLargeComplete(ImageBundle bundle) {
try {
setScreenNail(bundle.backupImage,
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;
}
diff --git a/src/com/android/gallery3d/ui/AlbumLabelMaker.java b/src/com/android/gallery3d/ui/AlbumLabelMaker.java
index 43a9055a4..f837092b8 100644
--- a/src/com/android/gallery3d/ui/AlbumLabelMaker.java
+++ b/src/com/android/gallery3d/ui/AlbumLabelMaker.java
@@ -1,4 +1,18 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
+/*
+ * Copyright (C) 2012 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.ui;
@@ -106,7 +120,7 @@ public class AlbumLabelMaker {
mLabelWidth = width;
int borders = 2 * BORDER_SIZE;
mBitmapPool = new BitmapPool(
- width + borders, mSpec.labelBackgroundHeight + borders);
+ width + borders, mSpec.labelBackgroundHeight + borders, 16);
}
public ThreadPool.Job<Bitmap> requestLabel(
@@ -192,7 +206,7 @@ public class AlbumLabelMaker {
}
}
- public void reycleLabel(Bitmap label) {
+ public void recycleLabel(Bitmap label) {
mBitmapPool.recycle(label);
}
diff --git a/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java b/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java
index 10943eaa6..7fa7df48a 100644
--- a/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java
+++ b/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java
@@ -492,7 +492,7 @@ public class AlbumSetSlidingWindow implements AlbumSetDataLoader.DataListener {
@Override
protected void recycleBitmap(Bitmap bitmap) {
- mLabelMaker.reycleLabel(bitmap);
+ mLabelMaker.recycleLabel(bitmap);
}
@Override
diff --git a/src/com/android/gallery3d/ui/BitmapScreenNail.java b/src/com/android/gallery3d/ui/BitmapScreenNail.java
index 3481aa18e..064e1af0e 100644
--- a/src/com/android/gallery3d/ui/BitmapScreenNail.java
+++ b/src/com/android/gallery3d/ui/BitmapScreenNail.java
@@ -20,6 +20,8 @@ import android.graphics.Bitmap;
import android.graphics.RectF;
import android.util.Log;
+import com.android.gallery3d.data.MediaItem;
+
// This is a ScreenNail wraps a Bitmap. It also includes the rotation
// information. The getWidth() and getHeight() methods return the width/height
// before rotation.
@@ -28,7 +30,7 @@ public class BitmapScreenNail implements ScreenNail {
private final int mWidth;
private final int mHeight;
private final int mRotation;
- private final Bitmap mBitmap;
+ private Bitmap mBitmap;
private BitmapTexture mTexture;
public BitmapScreenNail(Bitmap bitmap, int rotation) {
@@ -60,11 +62,15 @@ public class BitmapScreenNail implements ScreenNail {
}
@Override
- public void pauseDraw() {
+ public void recycle() {
if (mTexture != null) {
mTexture.recycle();
mTexture = null;
}
+ if (mBitmap != null) {
+ MediaItem.getThumbPool().recycle(mBitmap);
+ mBitmap = null;
+ }
}
@Override
diff --git a/src/com/android/gallery3d/ui/BitmapTileProvider.java b/src/com/android/gallery3d/ui/BitmapTileProvider.java
index 1e78cfd33..99b64d42e 100644
--- a/src/com/android/gallery3d/ui/BitmapTileProvider.java
+++ b/src/com/android/gallery3d/ui/BitmapTileProvider.java
@@ -96,7 +96,7 @@ public class BitmapTileProvider implements TileImageView.Model {
BitmapUtils.recycleSilently(bitmap);
}
if (mScreenNail != null) {
- mScreenNail.pauseDraw();
+ mScreenNail.recycle();
}
}
diff --git a/src/com/android/gallery3d/ui/PhotoView.java b/src/com/android/gallery3d/ui/PhotoView.java
index b2a4be49d..f0b4a12e7 100644
--- a/src/com/android/gallery3d/ui/PhotoView.java
+++ b/src/com/android/gallery3d/ui/PhotoView.java
@@ -52,6 +52,7 @@ public class PhotoView extends GLView {
// ScreenNail at previous (negative offset) or next (positive offset)
// positions. Returns null if the specified ScreenNail is unavailable.
public ScreenNail getScreenNail(int offset);
+ public void setNeedFullImage(boolean enabled);
}
public interface PhotoTapListener {
@@ -90,10 +91,6 @@ public class PhotoView extends GLView {
// SCREEN_NAIL_MAX.
private final RangeArray<Picture> mPictures =
new RangeArray<Picture>(-SCREEN_NAIL_MAX, SCREEN_NAIL_MAX);
- private final RangeBoolArray mReused =
- new RangeBoolArray(-SCREEN_NAIL_MAX, SCREEN_NAIL_MAX);
- private final RangeArray<ScreenNail> mTempScreenNail =
- new RangeArray<ScreenNail>(-SCREEN_NAIL_MAX, SCREEN_NAIL_MAX);
private final long mDataVersion[] = new long[2 * SCREEN_NAIL_MAX + 1];
private final int mFromIndex[] = new int[2 * SCREEN_NAIL_MAX + 1];
@@ -247,11 +244,6 @@ public class PhotoView extends GLView {
}
if (!changed) return;
- // Remembers those ScreenNail which are reused.
- for (int i = -SCREEN_NAIL_MAX; i <= SCREEN_NAIL_MAX; i++) {
- mReused.put(i, false);
- }
-
// Create the mFromIndex array, which records the index where the picture
// come from. The value Integer.MAX_VALUE means it's a new picture.
for (int i = 0; i < N; i++) {
@@ -265,7 +257,6 @@ public class PhotoView extends GLView {
int j;
for (j = 0; j < N; j++) {
if (mDataVersion[j] == v) {
- mReused.put(j - SCREEN_NAIL_MAX, true);
break;
}
}
@@ -280,25 +271,8 @@ public class PhotoView extends GLView {
// Move the boxes
mPositionController.moveBox(mFromIndex);
- // Free those ScreenNails that are not reused.
- for (int i = -SCREEN_NAIL_MAX; i <= SCREEN_NAIL_MAX; i++) {
- if (!mReused.get(i)) mPictures.get(i).updateScreenNail(null);
- }
-
- // Collect the reused ScreenNails, so we don't need to re-upload the
- // textures.
+ // Update the ScreenNails.
for (int i = -SCREEN_NAIL_MAX; i <= SCREEN_NAIL_MAX; i++) {
- mTempScreenNail.put(i, mPictures.get(i).releaseScreenNail());
- }
-
- // Put back the reused ScreenNails.
- for (int i = -SCREEN_NAIL_MAX; i <= SCREEN_NAIL_MAX; i++) {
- int j = mFromIndex[i + SCREEN_NAIL_MAX];
- if (j != Integer.MAX_VALUE) {
- ScreenNail s = mTempScreenNail.get(j);
- mTempScreenNail.put(j, null);
- mPictures.get(i).updateScreenNail(s);
- }
mPictures.get(i).reload();
}
@@ -317,11 +291,7 @@ public class PhotoView extends GLView {
private interface Picture {
void reload();
void draw(GLCanvas canvas, Rect r);
-
- void updateScreenNail(ScreenNail s);
- // Release the ownership of the ScreenNail from this entry.
- ScreenNail releaseScreenNail();
-
+ void setScreenNail(ScreenNail s);
boolean isEnabled();
};
@@ -352,8 +322,7 @@ public class PhotoView extends GLView {
getRotated(mRotation, w, h),
getRotated(mRotation, h, w));
}
- updateScreenNail(mModel == null
- ? null : mModel.getScreenNail(0));
+ setScreenNail(mModel == null ? null : mModel.getScreenNail(0));
updateLoadingState();
}
@@ -374,14 +343,9 @@ public class PhotoView extends GLView {
}
@Override
- public void updateScreenNail(ScreenNail s) {
+ public void setScreenNail(ScreenNail s) {
mIsNonBitmap = (s != null && !(s instanceof BitmapScreenNail));
- mTileView.updateScreenNail(s);
- }
-
- @Override
- public ScreenNail releaseScreenNail() {
- return mTileView.releaseScreenNail();
+ mTileView.setScreenNail(s);
}
@Override
@@ -489,8 +453,7 @@ public class PhotoView extends GLView {
@Override
public void reload() {
- updateScreenNail(mModel == null ? null
- : mModel.getScreenNail(mIndex));
+ setScreenNail(mModel == null ? null : mModel.getScreenNail(mIndex));
}
@Override
@@ -533,12 +496,9 @@ public class PhotoView extends GLView {
}
@Override
- public void updateScreenNail(ScreenNail s) {
+ public void setScreenNail(ScreenNail s) {
mEnabled = (s != null);
if (mScreenNail == s) return;
- if (mScreenNail != null) {
- mScreenNail.pauseDraw();
- }
mScreenNail = s;
if (mScreenNail != null) {
mRotation = mScreenNail.getRotation();
@@ -553,13 +513,6 @@ public class PhotoView extends GLView {
}
@Override
- public ScreenNail releaseScreenNail() {
- ScreenNail s = mScreenNail;
- mScreenNail = null;
- return s;
- }
-
- @Override
public boolean isEnabled() {
return mEnabled;
}
@@ -704,6 +657,7 @@ public class PhotoView extends GLView {
if (mFilmMode == enabled) return;
mFilmMode = enabled;
mPositionController.setFilmMode(mFilmMode);
+ mModel.setNeedFullImage(!enabled);
}
////////////////////////////////////////////////////////////////////////////
@@ -724,7 +678,7 @@ public class PhotoView extends GLView {
mPositionController.skipAnimation();
mTileView.freeTextures();
for (int i = -SCREEN_NAIL_MAX; i <= SCREEN_NAIL_MAX; i++) {
- mPictures.get(i).updateScreenNail(null);
+ mPictures.get(i).setScreenNail(null);
}
}
diff --git a/src/com/android/gallery3d/ui/PositionController.java b/src/com/android/gallery3d/ui/PositionController.java
index 6650d246c..a5eb22425 100644
--- a/src/com/android/gallery3d/ui/PositionController.java
+++ b/src/com/android/gallery3d/ui/PositionController.java
@@ -578,7 +578,7 @@ class PositionController {
if (changed) redraw();
}
- public boolean advanceAnimation() {
+ public void advanceAnimation() {
boolean changed = false;
changed |= mPlatform.advanceAnimation();
for (int i = -BOX_MAX; i <= BOX_MAX; i++) {
@@ -588,7 +588,6 @@ class PositionController {
changed |= mGaps.get(i).advanceAnimation();
}
if (changed) redraw();
- return changed;
}
////////////////////////////////////////////////////////////////////////////
diff --git a/src/com/android/gallery3d/ui/ScreenNail.java b/src/com/android/gallery3d/ui/ScreenNail.java
index 58ae8c942..25adc77da 100644
--- a/src/com/android/gallery3d/ui/ScreenNail.java
+++ b/src/com/android/gallery3d/ui/ScreenNail.java
@@ -22,8 +22,12 @@ public interface ScreenNail {
public int getHeight();
public int getRotation();
public void draw(GLCanvas canvas, int x, int y, int width, int height);
- public void noDraw(); // we do not need to draw this ScreenNail in this frame.
- public void pauseDraw(); // we do not expect to draw this ScreenNail for some time.
+
+ // We do not need to draw this ScreenNail in this frame.
+ public void noDraw();
+
+ // This ScreenNail will not be used anymore. Release related resources.
+ public void recycle();
// This is only used by TileImageView to back up the tiles not yet loaded.
public void draw(GLCanvas canvas, RectF source, RectF dest);
diff --git a/src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java b/src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java
index 3a8f2b0a4..f8442d059 100644
--- a/src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java
+++ b/src/com/android/gallery3d/ui/SurfaceTextureScreenNail.java
@@ -109,7 +109,7 @@ public abstract class SurfaceTextureScreenNail implements ScreenNail,
abstract public void noDraw();
@Override
- abstract public void pauseDraw();
+ abstract public void recycle();
@Override
abstract public void onFrameAvailable(SurfaceTexture surfaceTexture);
diff --git a/src/com/android/gallery3d/ui/TileImageView.java b/src/com/android/gallery3d/ui/TileImageView.java
index 610a34688..b37cf9c4a 100644
--- a/src/com/android/gallery3d/ui/TileImageView.java
+++ b/src/com/android/gallery3d/ui/TileImageView.java
@@ -153,18 +153,10 @@ public class TileImageView extends GLView {
if (model != null) notifyModelInvalidated();
}
- public void updateScreenNail(ScreenNail s) {
- if (mScreenNail == s) return;
- if (mScreenNail != null) mScreenNail.pauseDraw();
+ public void setScreenNail(ScreenNail s) {
mScreenNail = s;
}
- public ScreenNail releaseScreenNail() {
- ScreenNail s = mScreenNail;
- mScreenNail = null;
- return s;
- }
-
public void notifyModelInvalidated() {
invalidateTiles();
if (mModel == null) {
@@ -173,7 +165,7 @@ public class TileImageView extends GLView {
mImageHeight = 0;
mLevelCount = 0;
} else {
- updateScreenNail(mModel.getScreenNail());
+ setScreenNail(mModel.getScreenNail());
mImageWidth = mModel.getImageWidth();
mImageHeight = mModel.getImageHeight();
mLevelCount = mModel.getLevelCount();
@@ -389,7 +381,7 @@ public class TileImageView extends GLView {
tile = mRecycledQueue.pop();
}
}
- updateScreenNail(null);
+ setScreenNail(null);
}
public void prepareTextures() {
@@ -399,7 +391,7 @@ public class TileImageView extends GLView {
if (mIsTextureFreed) {
layoutTiles(mCenterX, mCenterY, mScale, mRotation);
mIsTextureFreed = false;
- updateScreenNail(mModel != null ? mModel.getScreenNail() : null);
+ setScreenNail(mModel == null ? null : mModel.getScreenNail());
}
}
diff --git a/src/com/android/gallery3d/ui/TileImageViewAdapter.java b/src/com/android/gallery3d/ui/TileImageViewAdapter.java
index a441c21c2..8061657fd 100644
--- a/src/com/android/gallery3d/ui/TileImageViewAdapter.java
+++ b/src/com/android/gallery3d/ui/TileImageViewAdapter.java
@@ -28,6 +28,7 @@ import com.android.gallery3d.common.Utils;
public class TileImageViewAdapter implements TileImageView.Model {
private static final String TAG = "TileImageViewAdapter";
protected ScreenNail mScreenNail;
+ protected boolean mOwnScreenNail;
protected BitmapRegionDecoder mRegionDecoder;
protected int mImageWidth;
protected int mImageHeight;
@@ -37,8 +38,10 @@ public class TileImageViewAdapter implements TileImageView.Model {
public TileImageViewAdapter() {
}
- public TileImageViewAdapter(Bitmap bitmap, BitmapRegionDecoder regionDecoder) {
- mScreenNail = new BitmapScreenNail(Utils.checkNotNull(bitmap), 0);
+ public TileImageViewAdapter(
+ Bitmap bitmap, BitmapRegionDecoder regionDecoder) {
+ Utils.checkNotNull(bitmap);
+ updateScreenNail(new BitmapScreenNail(bitmap, 0), true);
mRegionDecoder = regionDecoder;
mImageWidth = regionDecoder.getWidth();
mImageHeight = regionDecoder.getHeight();
@@ -46,7 +49,7 @@ public class TileImageViewAdapter implements TileImageView.Model {
}
public synchronized void clear() {
- mScreenNail = null;
+ updateScreenNail(null, false);
mImageWidth = 0;
mImageHeight = 0;
mLevelCount = 0;
@@ -55,7 +58,8 @@ public class TileImageViewAdapter implements TileImageView.Model {
}
public synchronized void setScreenNail(Bitmap bitmap, int width, int height) {
- mScreenNail = new BitmapScreenNail(Utils.checkNotNull(bitmap), 0);
+ Utils.checkNotNull(bitmap);
+ updateScreenNail(new BitmapScreenNail(bitmap, 0), true);
mImageWidth = width;
mImageHeight = height;
mRegionDecoder = null;
@@ -65,7 +69,8 @@ public class TileImageViewAdapter implements TileImageView.Model {
public synchronized void setScreenNail(
ScreenNail screenNail, int width, int height) {
- mScreenNail = Utils.checkNotNull(screenNail);
+ Utils.checkNotNull(screenNail);
+ updateScreenNail(screenNail, false);
mImageWidth = width;
mImageHeight = height;
mRegionDecoder = null;
@@ -73,6 +78,14 @@ public class TileImageViewAdapter implements TileImageView.Model {
mFailedToLoad = false;
}
+ private void updateScreenNail(ScreenNail screenNail, boolean own) {
+ if (mScreenNail != null && mOwnScreenNail) {
+ mScreenNail.recycle();
+ }
+ mScreenNail = screenNail;
+ mOwnScreenNail = own;
+ }
+
public synchronized void setRegionDecoder(BitmapRegionDecoder decoder) {
mRegionDecoder = Utils.checkNotNull(decoder);
mImageWidth = decoder.getWidth();