Redesign the free texture function.
Change-Id: I1216560b1a4dfbf559423b11ab390d3539997dd5
diff --git a/new3d/src/com/android/gallery3d/app/ViewImage.java b/new3d/src/com/android/gallery3d/app/ViewImage.java
index e77ab06..196f3ba 100644
--- a/new3d/src/com/android/gallery3d/app/ViewImage.java
+++ b/new3d/src/com/android/gallery3d/app/ViewImage.java
@@ -47,7 +47,9 @@
@Override
protected void onPause() {
super.onPause();
- mImageViewer.releaseTiles();
+ synchronized (mGLRootView) {
+ mImageViewer.close();
+ }
mGLRootView.onPause();
}
diff --git a/new3d/src/com/android/gallery3d/ui/GLCanvas.java b/new3d/src/com/android/gallery3d/ui/GLCanvas.java
index 677bf94..9ca64b0 100644
--- a/new3d/src/com/android/gallery3d/ui/GLCanvas.java
+++ b/new3d/src/com/android/gallery3d/ui/GLCanvas.java
@@ -3,8 +3,6 @@
import android.graphics.Rect;
import android.graphics.RectF;
-import java.util.Collection;
-
import javax.microedition.khronos.opengles.GL11;
//
@@ -101,9 +99,6 @@
// Return a texture copied from the specified rectangle.
public BasicTexture copyTexture(int x, int y, int width, int height);
- // TODO: Remove this or document it.
- public void releaseTextures(Collection<? extends BasicTexture> c);
-
// Gets the underlying GL instance. This is used only when direct access to
// GL is needed.
public GL11 getGLInstance();
@@ -111,4 +106,13 @@
// Binds the texture to the canvas for the following drawing calls. This
// function should only be called in Texture.
public void bindTexture(int id);
+
+ // Unloads the specified texture from the canvas. The resource allocated
+ // to draw the texture will be released. The specified texture will return
+ // to the unloaded state.
+ public boolean unloadTexture(BasicTexture texture);
+
+ // Delete the textures in GL side. This function should only be called in
+ // GL thread.
+ public void deleteRecycledTextures();
}
diff --git a/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java b/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java
index 1b516e9..1c6e35d 100644
--- a/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java
+++ b/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java
@@ -9,7 +9,6 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
-import java.util.Collection;
import java.util.Stack;
import javax.microedition.khronos.opengles.GL10;
@@ -29,6 +28,7 @@
private final GL11 mGL;
+ private final int mTextureId[] = new int[1];
private final float mMatrixValues[] = new float[16];
private final float mUvBuffer[] = new float[VERTEX_BUFFER_SIZE];
@@ -59,6 +59,7 @@
private RectF mDrawTextureSourceRect = new RectF();
private Rect mDrawTextureTargetRect = new Rect();
private float[] mTempMatrix = new float[32];
+ private final IntArray mUnboundIds = new IntArray();
GLCanvasImp(GL11 gl) {
mGL = gl;
@@ -759,13 +760,19 @@
mUvPointer.put(buffer, 0, 8).position(0);
}
- public void releaseTextures(Collection<? extends BasicTexture> c) {
- IntArray array = new IntArray();
- for (BasicTexture t : c) {
- if (t.isLoaded(this)) array.add(t.mId);
- }
- if (array.size() > 0) {
- mGL.glDeleteTextures(array.size(), array.toArray(null), 0);
+ public boolean unloadTexture(BasicTexture t) {
+ if (!t.isLoaded(this)) return false;
+ mUnboundIds.add(t.mId);
+ t.mGL = null;
+ t.mState = BasicTexture.STATE_UNLOADED;
+ return true;
+ }
+
+ public void deleteRecycledTextures() {
+ IntArray ids = mUnboundIds;
+ if (ids.size() > 0) {
+ mGL.glDeleteTextures(ids.size(), ids.getInternelArray(), 0);
+ ids.clear();
}
}
diff --git a/new3d/src/com/android/gallery3d/ui/GLRootView.java b/new3d/src/com/android/gallery3d/ui/GLRootView.java
index a14f441..e387f30 100644
--- a/new3d/src/com/android/gallery3d/ui/GLRootView.java
+++ b/new3d/src/com/android/gallery3d/ui/GLRootView.java
@@ -54,7 +54,7 @@
private static final int FLAG_NEED_LAYOUT = 2;
private GL11 mGL;
- private GLCanvas mCanvas;
+ private GLCanvasImp mCanvas;
private GLView mContentView;
private DisplayMetrics mDisplayMetrics;
@@ -203,6 +203,9 @@
++mFrameCount;
}
+ // release the unbound textures
+ mCanvas.deleteRecycledTextures();
+
mRenderRequested = false;
if ((mFlags & FLAG_NEED_LAYOUT) != 0) layoutContentPane();
diff --git a/new3d/src/com/android/gallery3d/ui/GridSlotAdapter.java b/new3d/src/com/android/gallery3d/ui/GridSlotAdapter.java
index 110509c..c2c9079 100644
--- a/new3d/src/com/android/gallery3d/ui/GridSlotAdapter.java
+++ b/new3d/src/com/android/gallery3d/ui/GridSlotAdapter.java
@@ -93,17 +93,14 @@
mSlotIndex = slotIndex;
}
- @Override
public void onImageCanceled(MediaItem abstractMediaItem, int type) {
// Do nothing
}
- @Override
public void onImageError(MediaItem item, int type, Throwable error) {
// Do nothing
}
- @Override
public void onImageReady(MediaItem item, int type, Bitmap bitmap) {
MyDisplayItem displayItem = mItemMap.get(mSlotIndex);
displayItem.updateContent(new BitmapTexture(bitmap));
diff --git a/new3d/src/com/android/gallery3d/ui/ImageViewer.java b/new3d/src/com/android/gallery3d/ui/ImageViewer.java
index 5a063cd..39a739a 100644
--- a/new3d/src/com/android/gallery3d/ui/ImageViewer.java
+++ b/new3d/src/com/android/gallery3d/ui/ImageViewer.java
@@ -11,13 +11,9 @@
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
public class ImageViewer extends GLView {
private static final String TAG = "ImageViewer";
@@ -191,39 +187,20 @@
invalidate();
}
- public void releaseTiles() {
- GLRootView root = getGLRootView();
- FutureTask<Void> task = new FutureTask<Void>(new ReleaseTiles());
- synchronized (root) {
- root.queueEvent(task);
- try {
- task.get();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- } catch (ExecutionException e) {
- Log.e(TAG, "release tiles fail", e);
- }
+ public void close() {
+ GLCanvas canvas = getGLRootView().getCanvas();
+ for (TileTexture texture : mActiveTiles.values()) {
+ canvas.unloadTexture(texture);
+ texture.recycle();
}
- }
-
- private class ReleaseTiles implements Callable<Void> {
- public Void call() throws Exception {
- ArrayList<TileTexture> tiles = new ArrayList<TileTexture>();
- tiles.addAll(mActiveTiles.values());
- mActiveTiles.clear();
-
- TileTexture tile = mRecycledHead;
- while (tile != null) {
- tiles.add(tile);
- tile = tile.mNextFree;
- }
- mRecycledHead = null;
- GLRootView root = getGLRootView();
- if (root != null) {
- root.getCanvas().releaseTextures(tiles);
- }
- return null;
+ mActiveTiles.clear();
+ TileTexture tile = mRecycledHead;
+ while (tile != null) {
+ canvas.unloadTexture(tile);
+ tile.recycle();
+ tile = tile.mNextFree;
}
+ mRecycledHead = null;
}
@Override
diff --git a/new3d/src/com/android/gallery3d/ui/IntArray.java b/new3d/src/com/android/gallery3d/ui/IntArray.java
index f9e2dfc..2b5a985 100644
--- a/new3d/src/com/android/gallery3d/ui/IntArray.java
+++ b/new3d/src/com/android/gallery3d/ui/IntArray.java
@@ -26,4 +26,13 @@
System.arraycopy(mData, 0, result, 0, mSize);
return result;
}
+
+ public int[] getInternelArray() {
+ return mData;
+ }
+
+ public void clear() {
+ mSize = 0;
+ if (mData.length != INIT_CAPACITY) mData = new int[INIT_CAPACITY];
+ }
}
diff --git a/new3d/src/com/android/gallery3d/ui/MediaSetSlotAdapter.java b/new3d/src/com/android/gallery3d/ui/MediaSetSlotAdapter.java
index a19abf3..067954d 100644
--- a/new3d/src/com/android/gallery3d/ui/MediaSetSlotAdapter.java
+++ b/new3d/src/com/android/gallery3d/ui/MediaSetSlotAdapter.java
@@ -136,17 +136,14 @@
mItemIndex = itemIndex;
}
- @Override
public void onImageCanceled(MediaItem abstractMediaItem, int type) {
// Do nothing
}
- @Override
public void onImageError(MediaItem item, int type, Throwable error) {
// Do nothing
}
- @Override
public void onImageReady(MediaItem item, int type, Bitmap bitmap) {
MyDisplayItem[] items = mItemsetMap.get(mSlotIndex);
items[mItemIndex].updateContent(new BitmapTexture(bitmap));