AlbumSlidingWindow.java revision cd938f3f05975de73658dc2f2b6c632b7ee569a3
1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/* 2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project 3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License. 6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at 7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software 11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and 14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License. 15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.ui; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 19dd46fe623b16ba14c70a539b7599cc75c7799612Owen Linimport android.graphics.Bitmap; 20dd46fe623b16ba14c70a539b7599cc75c7799612Owen Linimport android.os.Message; 21dd46fe623b16ba14c70a539b7599cc75c7799612Owen Lin 22c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Linimport com.android.gallery3d.app.AlbumDataLoader; 23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.app.GalleryActivity; 24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.common.Utils; 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.MediaItem; 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.Path; 27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.Future; 28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.FutureListener; 29bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Changimport com.android.gallery3d.util.GalleryUtils; 30113bfc77c4468411da9ae1290553c3be89f8df9aOwen Linimport com.android.gallery3d.util.JobLimiter; 31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 32c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Linpublic class AlbumSlidingWindow implements AlbumDataLoader.DataListener { 33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @SuppressWarnings("unused") 34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "AlbumSlidingWindow"; 35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 361a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin private static final int MSG_UPDATE_ENTRY = 0; 37113bfc77c4468411da9ae1290553c3be89f8df9aOwen Lin private static final int JOB_LIMIT = 2; 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static interface Listener { 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onSizeChanged(int size); 417260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin public void onContentChanged(); 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 441a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin public static class AlbumEntry { 451a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin public MediaItem item; 461a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin public Path path; 471a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin public boolean isPanorama; 481a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin public int rotation; 491a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin public int mediaType; 501a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin public boolean isWaitDisplayed; 511a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin public Texture content; 521a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin private BitmapLoader contentLoader; 531a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin } 541a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin 55c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin private final AlbumDataLoader mSource; 56d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin private final AlbumEntry mData[]; 57d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin private final SynchronizedHandler mHandler; 58d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin private final JobLimiter mThreadPool; 59d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin private final TextureUploader mTextureUploader; 60d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mSize; 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mContentStart = 0; 64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mContentEnd = 0; 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mActiveStart = 0; 67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mActiveEnd = 0; 68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private Listener mListener; 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mActiveRequestCount = 0; 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mIsActive = false; 73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public AlbumSlidingWindow(GalleryActivity activity, 75c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin AlbumDataLoader source, int cacheSize) { 76c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin source.setDataListener(this); 77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource = source; 781a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin mData = new AlbumEntry[cacheSize]; 79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSize = source.size(); 80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mHandler = new SynchronizedHandler(activity.getGLRoot()) { 82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void handleMessage(Message message) { 841a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin Utils.assertTrue(message.what == MSG_UPDATE_ENTRY); 851a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin ((ThumbnailLoader) message.obj).updateEntry(); 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin }; 88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 89113bfc77c4468411da9ae1290553c3be89f8df9aOwen Lin mThreadPool = new JobLimiter(activity.getThreadPool(), JOB_LIMIT); 90d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin mTextureUploader = new TextureUploader(activity.getGLRoot()); 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setListener(Listener listener) { 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mListener = listener; 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 971a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin public AlbumEntry get(int slotIndex) { 98cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang if (!isActiveSlot(slotIndex)) { 99cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang Utils.fail("invalid slot: %s outsides (%s, %s)", 100cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang slotIndex, mActiveStart, mActiveEnd); 101cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang } 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mData[slotIndex % mData.length]; 103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean isActiveSlot(int slotIndex) { 106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return slotIndex >= mActiveStart && slotIndex < mActiveEnd; 107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void setContentWindow(int contentStart, int contentEnd) { 110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (contentStart == mContentStart && contentEnd == mContentEnd) return; 111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!mIsActive) { 113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentStart = contentStart; 114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentEnd = contentEnd; 115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource.setActiveWindow(contentStart, contentEnd); 116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return; 117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (contentStart >= mContentEnd || mContentStart >= contentEnd) { 120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mContentStart, n = mContentEnd; i < n; ++i) { 121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin freeSlotContent(i); 122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource.setActiveWindow(contentStart, contentEnd); 124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = contentStart; i < contentEnd; ++i) { 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin prepareSlotContent(i); 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mContentStart; i < contentStart; ++i) { 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin freeSlotContent(i); 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = contentEnd, n = mContentEnd; i < n; ++i) { 132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin freeSlotContent(i); 133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource.setActiveWindow(contentStart, contentEnd); 135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = contentStart, n = mContentStart; i < n; ++i) { 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin prepareSlotContent(i); 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mContentEnd; i < contentEnd; ++i) { 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin prepareSlotContent(i); 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentStart = contentStart; 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentEnd = contentEnd; 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setActiveWindow(int start, int end) { 148cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang if (!(start <= end && end - start <= mData.length && end <= mSize)) { 149cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang Utils.fail("%s, %s, %s, %s", start, end, mData.length, mSize); 150cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang } 1511a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin AlbumEntry data[] = mData; 152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mActiveStart = start; 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mActiveEnd = end; 155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int contentStart = Utils.clamp((start + end) / 2 - data.length / 2, 157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 0, Math.max(0, mSize - data.length)); 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int contentEnd = Math.min(contentStart + data.length, mSize); 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setContentWindow(contentStart, contentEnd); 160cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin updateTextureUploadQueue(); 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mIsActive) updateAllImageRequests(); 162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 164cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin private void uploadBgTextureInSlot(int index) { 165cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin if (index < mContentEnd && index >= mContentStart) { 166cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin AlbumEntry entry = mData[index % mData.length]; 167cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin if (entry.content instanceof BitmapTexture) { 168cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin mTextureUploader.addBgTexture((BitmapTexture) entry.content); 169cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin } 170d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin } 171d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin } 172d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin 173cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin private void updateTextureUploadQueue() { 174d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin if (!mIsActive) return; 175d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin mTextureUploader.clear(); 176cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin 177cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin // add foreground textures 178cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) { 179d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin AlbumEntry entry = mData[i % mData.length]; 180cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin if (entry.content instanceof BitmapTexture) { 181cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin mTextureUploader.addFgTexture((BitmapTexture) entry.content); 182cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin } 183cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin } 184cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin 185cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin // add background textures 186cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin int range = Math.max( 187cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin (mContentEnd - mActiveEnd), (mActiveStart - mContentStart)); 188cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin for (int i = 0; i < range; ++i) { 189cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin uploadBgTextureInSlot(mActiveEnd + i); 190cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin uploadBgTextureInSlot(mActiveStart - i - 1); 191d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin } 192d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin } 193d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin 194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // We would like to request non active slots in the following order: 195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Order: 8 6 4 2 1 3 5 7 196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // |---------|---------------|---------| 197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // |<- active ->| 198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // |<-------- cached range ----------->| 199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void requestNonactiveImages() { 200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int range = Math.max( 201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin (mContentEnd - mActiveEnd), (mActiveStart - mContentStart)); 202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0 ;i < range; ++i) { 2031a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin requestSlotImage(mActiveEnd + i); 2041a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin requestSlotImage(mActiveStart - 1 - i); 205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2081a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin // return whether the request is in progress or not 2091a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin private boolean requestSlotImage(int slotIndex) { 2101a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin if (slotIndex < mContentStart || slotIndex >= mContentEnd) return false; 2111a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin AlbumEntry entry = mData[slotIndex % mData.length]; 2121a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin if (entry.content != null || entry.item == null) return false; 2131a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin 2141a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin entry.contentLoader.startLoad(); 2151a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin return entry.contentLoader.isRequestInProgress(); 216f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 217f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 218f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void cancelNonactiveImages() { 219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int range = Math.max( 220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin (mContentEnd - mActiveEnd), (mActiveStart - mContentStart)); 221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0 ;i < range; ++i) { 2221a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin cancelSlotImage(mActiveEnd + i); 2231a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin cancelSlotImage(mActiveStart - 1 - i); 224f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 225f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 226f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2271a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin private void cancelSlotImage(int slotIndex) { 228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (slotIndex < mContentStart || slotIndex >= mContentEnd) return; 2291a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin AlbumEntry item = mData[slotIndex % mData.length]; 2301a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin if (item.contentLoader != null) item.contentLoader.cancelLoad(); 231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void freeSlotContent(int slotIndex) { 2341a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin AlbumEntry data[] = mData; 235f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int index = slotIndex % data.length; 2361a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin AlbumEntry entry = data[index]; 2371a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin if (entry.contentLoader != null) { 2381a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin entry.contentLoader.recycle(); 239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 2401a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin data[index] = null; 241f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 242f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2431a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin private void prepareSlotContent(int slotIndex) { 2441a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin AlbumEntry entry = new AlbumEntry(); 2451a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin MediaItem item = mSource.get(slotIndex); // item could be null; 2461a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin entry.item = item; 2471a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin entry.isPanorama = GalleryUtils.isPanorama(entry.item); 2481a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin entry.mediaType = (item == null) 2491a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin ? MediaItem.MEDIA_TYPE_UNKNOWN 2501a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin : entry.item.getMediaType(); 2511a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin entry.path = (item == null) ? null : item.getPath(); 2521a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin entry.rotation = (item == null) ? 0 : item.getRotation(); 2531a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin entry.contentLoader = new ThumbnailLoader(slotIndex, entry.item); 2541a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin mData[slotIndex % mData.length] = entry; 255f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 256f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 257f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void updateAllImageRequests() { 258f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mActiveRequestCount = 0; 259f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) { 2601a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin if (requestSlotImage(i)) ++mActiveRequestCount; 261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mActiveRequestCount == 0) { 263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestNonactiveImages(); 264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 265f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cancelNonactiveImages(); 266f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 267f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2691a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin private class ThumbnailLoader extends BitmapLoader { 270d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin private final int mSlotIndex; 271d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin private final MediaItem mItem; 2721a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin 2731a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin public ThumbnailLoader(int slotIndex, MediaItem item) { 274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSlotIndex = slotIndex; 2751a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin mItem = item; 276f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 2794bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin protected void recycleBitmap(Bitmap bitmap) { 280d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin MediaItem.getMicroThumbPool().recycle(bitmap); 2814bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin } 2824bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin 2834bb5912e85f6d1bd8a6b78d6d52b4c4da7aeb740Owen Lin @Override 2841a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin protected Future<Bitmap> submitBitmapTask(FutureListener<Bitmap> l) { 2851a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin return mThreadPool.submit( 2861a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin mItem.requestImage(MediaItem.TYPE_MICROTHUMBNAIL), this); 287f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 288f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 289f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 2901a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin protected void onLoadComplete(Bitmap bitmap) { 2911a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin mHandler.obtainMessage(MSG_UPDATE_ENTRY, this).sendToTarget(); 292f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 293f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2941a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin public void updateEntry() { 295d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin Bitmap bitmap = getBitmap(); 296d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin if (bitmap == null) return; // error or recycled 297f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2981a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin AlbumEntry entry = mData[mSlotIndex % mData.length]; 299d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin entry.content = new BitmapTexture(bitmap); 300f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3011a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin if (isActiveSlot(mSlotIndex)) { 302d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin mTextureUploader.addFgTexture((BitmapTexture) entry.content); 3031a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin --mActiveRequestCount; 3041a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin if (mActiveRequestCount == 0) requestNonactiveImages(); 3051a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin if (mListener != null) mListener.onContentChanged(); 306d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin } else { 307d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin mTextureUploader.addBgTexture((BitmapTexture) entry.content); 3081a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin } 309f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 310f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 311f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3121a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin @Override 313f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onSizeChanged(int size) { 314f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mSize != size) { 315f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSize = size; 316f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mListener != null) mListener.onSizeChanged(mSize); 317cd938f3f05975de73658dc2f2b6c632b7ee569a3Yuli Huang if (mContentEnd > mSize) mContentEnd = mSize; 318cd938f3f05975de73658dc2f2b6c632b7ee569a3Yuli Huang if (mActiveEnd > mSize) mActiveEnd = mSize; 319f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 320f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 321f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3221a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin @Override 323c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin public void onContentChanged(int index) { 324f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (index >= mContentStart && index < mContentEnd && mIsActive) { 325c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin freeSlotContent(index); 326c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin prepareSlotContent(index); 327c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin updateAllImageRequests(); 328c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin if (mListener != null && isActiveSlot(index)) { 329c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin mListener.onContentChanged(); 330c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin } 331f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 332f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 333f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 334f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void resume() { 335f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIsActive = true; 336f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mContentStart, n = mContentEnd; i < n; ++i) { 337f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin prepareSlotContent(i); 338f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 339f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin updateAllImageRequests(); 340f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 341f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 342f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void pause() { 343f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIsActive = false; 344f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mContentStart, n = mContentEnd; i < n; ++i) { 345f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin freeSlotContent(i); 346f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 347f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 348f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 349