From e80981e0c5b33f69e8c99a8909f6fce16891ccea Mon Sep 17 00:00:00 2001
From: Hannes Janetzek <hannes.janetzek@gmail.com>
Date: Tue, 1 Apr 2014 03:42:56 +0200
Subject: [PATCH 1/3] add SyncPool.clear()

---
 vtm/src/org/oscim/utils/pool/SyncPool.java | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/vtm/src/org/oscim/utils/pool/SyncPool.java b/vtm/src/org/oscim/utils/pool/SyncPool.java
index 4a704d10..56e69b60 100644
--- a/vtm/src/org/oscim/utils/pool/SyncPool.java
+++ b/vtm/src/org/oscim/utils/pool/SyncPool.java
@@ -18,6 +18,7 @@ package org.oscim.utils.pool;
 
 import javax.annotation.CheckReturnValue;
 
+@SuppressWarnings({ "rawtypes", "unchecked" })
 public abstract class SyncPool<T extends Inlist<?>> {
 	protected final int mMaxFill;
 	protected final boolean mClearItems;
@@ -50,6 +51,13 @@ public abstract class SyncPool<T extends Inlist<?>> {
 		mPool = null;
 	}
 
+	public synchronized void clear() {
+		while (mPool != null) {
+			freeItem(mPool);
+			mPool = (T) mPool.next;
+		}
+	}
+
 	/**
 	 * @param item
 	 *            set initial state
@@ -81,7 +89,6 @@ public abstract class SyncPool<T extends Inlist<?>> {
 	 * Usage item = pool.release(item), to ensure to not keep a reference to
 	 * item!
 	 */
-	@SuppressWarnings({ "rawtypes", "unchecked" })
 	@CheckReturnValue
 	public T release(T item) {
 		if (item == null)
@@ -111,7 +118,6 @@ public abstract class SyncPool<T extends Inlist<?>> {
 	 * Usage list = pool.releaseAll(list), to ensure to not keep a reference to
 	 * list!
 	 */
-	@SuppressWarnings({ "unchecked", "rawtypes" })
 	@CheckReturnValue
 	public T releaseAll(T item) {
 		if (item == null)
@@ -156,7 +162,6 @@ public abstract class SyncPool<T extends Inlist<?>> {
 	 * 
 	 * @return the item
 	 */
-	@SuppressWarnings("unchecked")
 	public T get() {
 
 		synchronized (this) {

From b45e38ef4dba33e8dee4ef25bf4cf9064781bb32 Mon Sep 17 00:00:00 2001
From: Hannes Janetzek <hannes.janetzek@gmail.com>
Date: Tue, 1 Apr 2014 03:44:33 +0200
Subject: [PATCH 2/3] dispose textures at end of each frame

---
 vtm/src/org/oscim/renderer/MapRenderer.java   |  2 +
 .../oscim/renderer/elements/TextureItem.java  | 45 ++++++++++---------
 2 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/vtm/src/org/oscim/renderer/MapRenderer.java b/vtm/src/org/oscim/renderer/MapRenderer.java
index f72e6734..58535580 100644
--- a/vtm/src/org/oscim/renderer/MapRenderer.java
+++ b/vtm/src/org/oscim/renderer/MapRenderer.java
@@ -27,6 +27,7 @@ import org.oscim.backend.GLAdapter;
 import org.oscim.backend.canvas.Color;
 import org.oscim.map.Map;
 import org.oscim.renderer.elements.ElementLayers;
+import org.oscim.renderer.elements.TextureItem;
 import org.oscim.utils.pool.Inlist;
 import org.oscim.utils.pool.Pool;
 import org.slf4j.Logger;
@@ -174,6 +175,7 @@ public class MapRenderer {
 		draw();
 
 		mBufferPool.releaseBuffers();
+		TextureItem.disposeTextures();
 	}
 
 	private void draw() {
diff --git a/vtm/src/org/oscim/renderer/elements/TextureItem.java b/vtm/src/org/oscim/renderer/elements/TextureItem.java
index 1ebe8a07..ae79677a 100644
--- a/vtm/src/org/oscim/renderer/elements/TextureItem.java
+++ b/vtm/src/org/oscim/renderer/elements/TextureItem.java
@@ -144,8 +144,6 @@ public class TextureItem extends Inlist<TextureItem> {
 	}
 
 	public static class TexturePool extends SyncPool<TextureItem> {
-
-		private final ArrayList<Integer> mTexDisposed = new ArrayList<Integer>();
 		private final ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(10);
 
 		private final int mHeight;
@@ -226,13 +224,11 @@ public class TextureItem extends Inlist<TextureItem> {
 
 		@Override
 		protected void freeItem(TextureItem t) {
-
-			if (!t.ref) {
-				synchronized (mTexDisposed) {
-					if (t.id >= 0) {
-						mTexDisposed.add(Integer.valueOf(t.id));
-						t.id = -1;
-					}
+			if (!t.ref && t.id >= 0) {
+				mTexCnt--;
+				synchronized (disposedTextures) {
+					disposedTextures.add(Integer.valueOf(t.id));
+					t.id = -1;
 				}
 			}
 		}
@@ -253,19 +249,6 @@ public class TextureItem extends Inlist<TextureItem> {
 			if (t.bitmap == null)
 				throw new RuntimeException("Missing bitmap for texture");
 
-			synchronized (mTexDisposed) {
-				int size = mTexDisposed.size();
-				if (size > 0) {
-					int[] tmp = new int[size];
-					for (int i = 0; i < size; i++)
-						tmp[i] = mTexDisposed.get(i).intValue();
-
-					mTexDisposed.clear();
-					GLUtils.glDeleteTextures(size, tmp);
-					mTexCnt -= size;
-				}
-			}
-
 			if (t.id < 0) {
 				int[] textureIds = GLUtils.glGenTextures(1);
 				t.id = textureIds[0];
@@ -318,10 +301,28 @@ public class TextureItem extends Inlist<TextureItem> {
 	/* Pool for not-pooled textures. Disposed items will only be released
 	 * on the GL-Thread and will not be put back in any pool. */
 	final static TexturePool NOPOOL = new TexturePool(0);
+	final static ArrayList<Integer> disposedTextures = new ArrayList<Integer>();
 
 	private static GL20 GL;
 
 	static void init(GL20 gl) {
 		GL = gl;
 	}
+
+	/** disposed textures are released by MapRenderer after each frame */
+	public static void disposeTextures() {
+		synchronized (disposedTextures) {
+
+			int size = disposedTextures.size();
+			if (size > 0) {
+				int[] tmp = new int[size];
+				for (int i = 0; i < size; i++)
+					tmp[i] = disposedTextures.get(i).intValue();
+
+				disposedTextures.clear();
+				GLUtils.glDeleteTextures(size, tmp);
+				//mTexCnt -= size;
+			}
+		}
+	}
 }

From a37b5036288b701727c668a4bfc55d15f24f856b Mon Sep 17 00:00:00 2001
From: Hannes Janetzek <hannes.janetzek@gmail.com>
Date: Tue, 1 Apr 2014 03:45:43 +0200
Subject: [PATCH 3/3] use one TexturePool per BitmapTileLayer

- dispose textures onDetach()
---
 vtm/src/org/oscim/layers/tile/bitmap/BitmapTileLayer.java | 8 +++++++-
 .../org/oscim/layers/tile/bitmap/BitmapTileLoader.java    | 7 ++++---
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/vtm/src/org/oscim/layers/tile/bitmap/BitmapTileLayer.java b/vtm/src/org/oscim/layers/tile/bitmap/BitmapTileLayer.java
index 9d192109..fca6b19e 100644
--- a/vtm/src/org/oscim/layers/tile/bitmap/BitmapTileLayer.java
+++ b/vtm/src/org/oscim/layers/tile/bitmap/BitmapTileLayer.java
@@ -104,10 +104,16 @@ public class BitmapTileLayer extends TileLayer {
 		return new BitmapTileLoader(this, mTileSource);
 	}
 
+	@Override
+	public void onDetach() {
+		super.onDetach();
+		pool.clear();
+	}
+
 	final static int POOL_FILL = 40;
 
 	/** pool shared by TextLayers */
-	final static TexturePool pool = new TexturePool(POOL_FILL) {
+	final TexturePool pool = new TexturePool(POOL_FILL) {
 
 		//		int sum = 0;
 		//
diff --git a/vtm/src/org/oscim/layers/tile/bitmap/BitmapTileLoader.java b/vtm/src/org/oscim/layers/tile/bitmap/BitmapTileLoader.java
index ad4c2905..7035585e 100644
--- a/vtm/src/org/oscim/layers/tile/bitmap/BitmapTileLoader.java
+++ b/vtm/src/org/oscim/layers/tile/bitmap/BitmapTileLoader.java
@@ -21,7 +21,6 @@ import static org.oscim.layers.tile.MapTile.State.CANCEL;
 import org.oscim.backend.canvas.Bitmap;
 import org.oscim.core.Tile;
 import org.oscim.layers.tile.MapTile;
-import org.oscim.layers.tile.TileLayer;
 import org.oscim.layers.tile.TileLoader;
 import org.oscim.renderer.elements.BitmapLayer;
 import org.oscim.renderer.elements.ElementLayers;
@@ -35,10 +34,12 @@ public class BitmapTileLoader extends TileLoader {
 	protected static final Logger log = LoggerFactory.getLogger(BitmapTileLoader.class);
 
 	private final ITileDataSource mTileDataSource;
+	private final BitmapTileLayer mLayer;
 
-	public BitmapTileLoader(TileLayer tileLayer, TileSource tileSource) {
+	public BitmapTileLoader(BitmapTileLayer tileLayer, TileSource tileSource) {
 		super(tileLayer.getManager());
 		mTileDataSource = tileSource.getDataSource();
+		mLayer = tileLayer;
 	}
 
 	@Override
@@ -58,7 +59,7 @@ public class BitmapTileLoader extends TileLoader {
 			return;
 
 		BitmapLayer l = new BitmapLayer(false);
-		l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE, BitmapTileLayer.pool);
+		l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE, mLayer.pool);
 
 		ElementLayers layers = new ElementLayers();
 		layers.setTextureLayers(l);