From ab56cc4b18608cd9ef8ff15dcdd3ee2da6e1edb5 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Tue, 9 Apr 2013 23:06:06 +0200 Subject: [PATCH] pooled items now extend pool.Inlist and using generic pool.SyncPool --- src/org/oscim/generator/TileGenerator.java | 6 +- src/org/oscim/generator/WayDecorator.java | 2 +- src/org/oscim/renderer/GLRenderer.java | 3 +- src/org/oscim/renderer/TextureRenderer.java | 3 +- src/org/oscim/renderer/TileManager.java | 10 +- .../oscim/renderer/layer/ExtrusionLayer.java | 62 ++-- src/org/oscim/renderer/layer/Layer.java | 4 +- src/org/oscim/renderer/layer/Layers.java | 28 +- src/org/oscim/renderer/layer/LineLayer.java | 70 ++-- .../oscim/renderer/layer/LineTexLayer.java | 10 +- .../oscim/renderer/layer/PolygonLayer.java | 18 +- src/org/oscim/renderer/layer/SymbolItem.java | 48 +-- src/org/oscim/renderer/layer/SymbolLayer.java | 31 +- src/org/oscim/renderer/layer/TextItem.java | 155 ++------ src/org/oscim/renderer/layer/TextLayer.java | 47 +-- .../TextureItem.java} | 190 +++++----- .../oscim/renderer/layer/TextureLayer.java | 7 +- .../{VertexPoolItem.java => VertexItem.java} | 22 +- src/org/oscim/renderer/layer/VertexPool.java | 103 ------ .../oscim/renderer/overlays/GridOverlay.java | 2 +- .../oscim/renderer/overlays/TextOverlay.java | 346 ++++++++++-------- src/org/oscim/utils/pool/Inlist.java | 73 ++++ src/org/oscim/utils/pool/Pool.java | 62 ++++ src/org/oscim/utils/pool/SyncPool.java | 145 ++++++++ 24 files changed, 767 insertions(+), 680 deletions(-) rename src/org/oscim/renderer/{TextureObject.java => layer/TextureItem.java} (60%) rename src/org/oscim/renderer/layer/{VertexPoolItem.java => VertexItem.java} (69%) delete mode 100644 src/org/oscim/renderer/layer/VertexPool.java create mode 100644 src/org/oscim/utils/pool/Inlist.java create mode 100644 src/org/oscim/utils/pool/Pool.java create mode 100644 src/org/oscim/utils/pool/SyncPool.java diff --git a/src/org/oscim/generator/TileGenerator.java b/src/org/oscim/generator/TileGenerator.java index f8b08d8d..47628463 100644 --- a/src/org/oscim/generator/TileGenerator.java +++ b/src/org/oscim/generator/TileGenerator.java @@ -167,7 +167,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback { //Log.d(TAG, "Failed loading: " + tile); mTile.layers.clear(); mTile.layers = null; - TextItem.release(mTile.labels); + TextItem.pool.releaseAll(mTile.labels); mTile.labels = null; // FIXME add STATE_FAILED? mTile.state = STATE_NONE; @@ -459,7 +459,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback { float x = mWay.geom.points[0]; float y = mWay.geom.points[1]; - mTile.addLabel(TextItem.get().set(x, y, value, text)); + mTile.addLabel(TextItem.pool.get().set(x, y, value, text)); } @Override @@ -471,7 +471,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback { for (int i = 0, n = mGeom.index[0]; i < n; i += 2) { float x = mGeom.points[i]; float y = mGeom.points[i + 1]; - mTile.addLabel(TextItem.get().set(x, y, value, text)); + mTile.addLabel(TextItem.pool.get().set(x, y, value, text)); } } diff --git a/src/org/oscim/generator/WayDecorator.java b/src/org/oscim/generator/WayDecorator.java index 84f3067f..7d9d8368 100644 --- a/src/org/oscim/generator/WayDecorator.java +++ b/src/org/oscim/generator/WayDecorator.java @@ -194,7 +194,7 @@ public final class WayDecorator { y2 = prevY; } - TextItem n = TextItem.get(); + TextItem n = TextItem.pool.get(); // link items together if (t != null) { diff --git a/src/org/oscim/renderer/GLRenderer.java b/src/org/oscim/renderer/GLRenderer.java index ca97a90b..a769e34d 100644 --- a/src/org/oscim/renderer/GLRenderer.java +++ b/src/org/oscim/renderer/GLRenderer.java @@ -32,6 +32,7 @@ import javax.microedition.khronos.opengles.GL10; import org.oscim.core.MapPosition; import org.oscim.core.Tile; import org.oscim.renderer.layer.Layers; +import org.oscim.renderer.layer.TextureItem; import org.oscim.renderer.overlays.RenderOverlay; import org.oscim.theme.RenderTheme; import org.oscim.utils.GlUtils; @@ -646,7 +647,7 @@ public class GLRenderer implements GLSurfaceView.Renderer { LineTexRenderer.init(); PolygonRenderer.init(); TextureRenderer.init(); - TextureObject.init(10); + TextureItem.init(10); mNewSurface = true; } diff --git a/src/org/oscim/renderer/TextureRenderer.java b/src/org/oscim/renderer/TextureRenderer.java index c2e27854..76c7ac1c 100644 --- a/src/org/oscim/renderer/TextureRenderer.java +++ b/src/org/oscim/renderer/TextureRenderer.java @@ -18,6 +18,7 @@ package org.oscim.renderer; import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.layer.Layer; import org.oscim.renderer.layer.TextureLayer; +import org.oscim.renderer.layer.TextureItem; import org.oscim.utils.GlUtils; import android.opengl.GLES20; @@ -74,7 +75,7 @@ public final class TextureRenderer { GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLRenderer.mQuadIndicesID); - for (TextureObject to = tl.textures; to != null; to = to.next) { + for (TextureItem to = tl.textures; to != null; to = to.next) { GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, to.id); int maxVertices = GLRenderer.maxQuads * INDICES_PER_SPRITE; diff --git a/src/org/oscim/renderer/TileManager.java b/src/org/oscim/renderer/TileManager.java index bacb776b..46624c61 100644 --- a/src/org/oscim/renderer/TileManager.java +++ b/src/org/oscim/renderer/TileManager.java @@ -27,7 +27,6 @@ import org.oscim.core.Tile; import org.oscim.generator.JobTile; import org.oscim.generator.TileDistanceSort; import org.oscim.renderer.layer.TextItem; -import org.oscim.renderer.layer.VertexPool; import org.oscim.utils.FastMath; import org.oscim.view.MapView; import org.oscim.view.MapViewPosition; @@ -112,11 +111,12 @@ public class TileManager { // pass VBOs and VertexItems back to pools for (int i = 0; i < mTilesSize; i++) clearTile(mTiles[i]); - } else { + } + //else { // mInitialized is set when surface changed // and VBOs might be lost - VertexPool.init(); - } + // VertexPool.init(); + //} // clear cache index QuadTree.init(); @@ -397,7 +397,7 @@ public class TileManager { t.layers = null; } - TextItem.release(t.labels); + TextItem.pool.releaseAll(t.labels); QuadTree.remove(t); t.state = STATE_NONE; diff --git a/src/org/oscim/renderer/layer/ExtrusionLayer.java b/src/org/oscim/renderer/layer/ExtrusionLayer.java index ef094081..ea69a5fd 100644 --- a/src/org/oscim/renderer/layer/ExtrusionLayer.java +++ b/src/org/oscim/renderer/layer/ExtrusionLayer.java @@ -36,9 +36,9 @@ import android.util.Log; public class ExtrusionLayer extends Layer { private final static String TAG = ExtrusionLayer.class.getName(); private static final float S = GLRenderer.COORD_SCALE; - private final VertexPoolItem mVertices; - private VertexPoolItem mCurVertices; - private final VertexPoolItem mIndices[], mCurIndices[]; + private final VertexItem mVertices; + private VertexItem mCurVertices; + private final VertexItem mIndices[], mCurIndices[]; private LineClipper mClipper; // indices for: @@ -65,12 +65,12 @@ public class ExtrusionLayer extends Layer { this.level = level; mGroundResolution = groundResolution; - mVertices = mCurVertices = VertexPool.get(); + mVertices = mCurVertices = VertexItem.pool.get(); - mIndices = new VertexPoolItem[4]; - mCurIndices = new VertexPoolItem[4]; + mIndices = new VertexItem[4]; + mCurIndices = new VertexItem[4]; for (int i = 0; i < 4; i++) - mIndices[i] = mCurIndices[i] = VertexPool.get(); + mIndices[i] = mCurIndices[i] = VertexItem.pool.get(); mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE); } @@ -158,9 +158,9 @@ public class ExtrusionLayer extends Layer { short first = (short) (startVertex + 1); for (int k = 0; k < len - 4; k += 2) { - if (i == VertexPoolItem.SIZE) { - mCurIndices[IND_ROOF].used = VertexPoolItem.SIZE; - mCurIndices[IND_ROOF].next = VertexPool.get(); + if (i == VertexItem.SIZE) { + mCurIndices[IND_ROOF].used = VertexItem.SIZE; + mCurIndices[IND_ROOF].next = VertexItem.pool.get(); mCurIndices[IND_ROOF] = mCurIndices[2].next; indices = mCurIndices[IND_ROOF].vertices; i = 0; @@ -194,7 +194,7 @@ public class ExtrusionLayer extends Layer { if (used > 0) { // get back to the last item added.. - VertexPoolItem it = mIndices[IND_ROOF]; + VertexItem it = mIndices[IND_ROOF]; while (it.next != null) it = it.next; mCurIndices[IND_ROOF] = it; @@ -247,9 +247,9 @@ public class ExtrusionLayer extends Layer { uy = vy; /* add bottom and top vertex for each point */ - if (v == VertexPoolItem.SIZE) { - mCurVertices.used = VertexPoolItem.SIZE; - mCurVertices.next = VertexPool.get(); + if (v == VertexItem.SIZE) { + mCurVertices.used = VertexItem.SIZE; + mCurVertices.next = VertexItem.pool.get(); mCurVertices = mCurVertices.next; vertices = mCurVertices.vertices; v = 0; @@ -329,8 +329,8 @@ public class ExtrusionLayer extends Layer { // index id relative to mCurIndices item int ind = mCurIndices[even].used; - if (ind == VertexPoolItem.SIZE) { - mCurIndices[even].next = VertexPool.get(); + if (ind == VertexItem.SIZE) { + mCurIndices[even].next = VertexItem.pool.get(); mCurIndices[even] = mCurIndices[even].next; indices = mCurIndices[even].vertices; ind = 0; @@ -348,9 +348,9 @@ public class ExtrusionLayer extends Layer { even = (even == 0 ? 1 : 0); /* add roof outline indices */ - VertexPoolItem it = mCurIndices[IND_OUTLINE]; - if (it.used == VertexPoolItem.SIZE) { - it.next = VertexPool.get(); + VertexItem it = mCurIndices[IND_OUTLINE]; + if (it.used == VertexItem.SIZE) { + it.next = VertexItem.pool.get(); it = mCurIndices[IND_OUTLINE] = it.next; } it.vertices[it.used++] = s1; @@ -377,7 +377,7 @@ public class ExtrusionLayer extends Layer { sbuf.clear(); mNumIndices = 0; for (int i = 0; i < 4; i++) { - for (VertexPoolItem vi = mIndices[i]; vi != null; vi = vi.next) { + for (VertexItem vi = mIndices[i]; vi != null; vi = vi.next) { sbuf.put(vi.vertices, 0, vi.used); mIndiceCnt[i] += vi.used; } @@ -392,7 +392,7 @@ public class ExtrusionLayer extends Layer { // upload vertices sbuf.clear(); - for (VertexPoolItem vi = mVertices; vi != null; vi = vi.next) + for (VertexItem vi = mVertices; vi != null; vi = vi.next) sbuf.put(vi.vertices, 0, vi.used); sbuf.flip(); @@ -404,10 +404,10 @@ public class ExtrusionLayer extends Layer { GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); - for (VertexPoolItem i : mIndices) - VertexPool.release(i); + for (VertexItem i : mIndices) + VertexItem.pool.releaseAll(i); - VertexPool.release(mVertices); + VertexItem.pool.releaseAll(mVertices); mClipper = null; @@ -423,9 +423,9 @@ public class ExtrusionLayer extends Layer { mVertexBO = null; //GLES20.glDeleteBuffers(2, mVboIds, 0); } else { - VertexPool.release(mVertices); - for (VertexPoolItem i : mIndices) - VertexPool.release(i); + VertexItem.pool.releaseAll(mVertices); + for (VertexItem i : mIndices) + VertexItem.pool.releaseAll(i); } } @@ -433,7 +433,7 @@ public class ExtrusionLayer extends Layer { private static ShortBuffer sBuf; public static synchronized int triangulate(float[] points, int ppos, int plen, short[] index, - int ipos, int rings, int vertexOffset, VertexPoolItem item) { + int ipos, int rings, int vertexOffset, VertexItem item) { if (!initialized) { // FIXME also cleanup on shutdown! @@ -454,12 +454,12 @@ public class ExtrusionLayer extends Layer { for (int k = 0, cnt = 0; k < numIndices; k += cnt) { - if (item.used == VertexPoolItem.SIZE) { - item.next = VertexPool.get(); + if (item.used == VertexItem.SIZE) { + item.next = VertexItem.pool.get(); item = item.next; } - cnt = VertexPoolItem.SIZE - item.used; + cnt = VertexItem.SIZE - item.used; if (k + cnt > numIndices) cnt = numIndices - k; diff --git a/src/org/oscim/renderer/layer/Layer.java b/src/org/oscim/renderer/layer/Layer.java index 04e6c582..adff2d23 100644 --- a/src/org/oscim/renderer/layer/Layer.java +++ b/src/org/oscim/renderer/layer/Layer.java @@ -45,8 +45,8 @@ public abstract class Layer { // - offset in byte in VBO public int offset; - VertexPoolItem pool; - protected VertexPoolItem curItem; + VertexItem vertexItems; + protected VertexItem curItem; abstract protected void compile(ShortBuffer sbuf); abstract protected void clear(); diff --git a/src/org/oscim/renderer/layer/Layers.java b/src/org/oscim/renderer/layer/Layers.java index 74f52937..a5f1a292 100644 --- a/src/org/oscim/renderer/layer/Layers.java +++ b/src/org/oscim/renderer/layer/Layers.java @@ -179,21 +179,21 @@ public class Layers { // optimization for Line- and PolygonLayer: // collect all pool items and add back in one go private static int addLayerItems(ShortBuffer sbuf, Layer l, byte type, int pos) { - VertexPoolItem last = null, items = null; + VertexItem last = null, items = null; int size = 0; for (; l != null; l = l.next) { if (l.type != type) continue; - for (VertexPoolItem it = l.pool; it != null; it = it.next) { + for (VertexItem it = l.vertexItems; it != null; it = it.next) { if (it.next == null){ size += it.used; sbuf.put(it.vertices, 0, it.used); } else{ - size += VertexPoolItem.SIZE; - sbuf.put(it.vertices, 0, VertexPoolItem.SIZE); + size += VertexItem.SIZE; + sbuf.put(it.vertices, 0, VertexItem.SIZE); } last = it; } @@ -205,13 +205,13 @@ public class Layers { pos += l.verticesCnt; last.next = items; - items = l.pool; + items = l.vertexItems; last = null; - l.pool = null; + l.vertexItems = null; l.curItem = null; } - VertexPool.release(items); + VertexItem.pool.releaseAll(items); return size; } @@ -220,15 +220,15 @@ public class Layers { // offset of layer data in vbo l.offset = sbuf.position() * SHORT_BYTES; - for (VertexPoolItem it = l.pool; it != null; it = it.next) { + for (VertexItem it = l.vertexItems; it != null; it = it.next) { if (it.next == null) sbuf.put(it.vertices, 0, it.used); else - sbuf.put(it.vertices, 0, VertexPoolItem.SIZE); + sbuf.put(it.vertices, 0, VertexItem.SIZE); } - VertexPool.release(l.pool); - l.pool = null; + VertexItem.pool.releaseAll(l.vertexItems); + l.vertexItems = null; } // cleanup only when layers are not used by tile or overlay anymore! @@ -237,9 +237,9 @@ public class Layers { // clear line and polygon layers directly Layer l = baseLayers; while (l != null) { - if (l.pool != null) { - VertexPool.release(l.pool); - l.pool = null; + if (l.vertexItems != null) { + VertexItem.pool.releaseAll(l.vertexItems); + l.vertexItems = null; l.curItem = null; } l = l.next; diff --git a/src/org/oscim/renderer/layer/LineLayer.java b/src/org/oscim/renderer/layer/LineLayer.java index 2de34ff8..3fce5df4 100644 --- a/src/org/oscim/renderer/layer/LineLayer.java +++ b/src/org/oscim/renderer/layer/LineLayer.java @@ -85,10 +85,10 @@ public final class LineLayer extends Layer { else if (line.cap == Cap.SQUARE) squared = true; - if (pool == null) - curItem = pool = VertexPool.get(); + if (vertexItems == null) + curItem = vertexItems = VertexItem.pool.get(); - VertexPoolItem si = curItem; + VertexItem si = curItem; short v[] = si.vertices; int opos = si.used; @@ -175,8 +175,8 @@ public final class LineLayer extends Layer { // when the endpoint is outside the tile region omit round caps. boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax); - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -193,8 +193,8 @@ public final class LineLayer extends Layer { v[opos++] = dx; v[opos++] = dy; - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -204,8 +204,8 @@ public final class LineLayer extends Layer { v[opos++] = dx; v[opos++] = dy; - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -218,8 +218,8 @@ public final class LineLayer extends Layer { v[opos++] = (short) (2 | ddx & DIR_MASK); v[opos++] = (short) (2 | ddy & DIR_MASK); - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -233,8 +233,8 @@ public final class LineLayer extends Layer { v[opos++] = (short) (0 | ddx & DIR_MASK); v[opos++] = (short) (1 | ddy & DIR_MASK); - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -273,8 +273,8 @@ public final class LineLayer extends Layer { v[opos++] = dx; v[opos++] = dy; - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -284,8 +284,8 @@ public final class LineLayer extends Layer { v[opos++] = dx; v[opos++] = dy; - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -366,8 +366,8 @@ public final class LineLayer extends Layer { ddx = -ddx; ddy = -ddy; } - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -377,8 +377,8 @@ public final class LineLayer extends Layer { v[opos++] = (short) (0 | ddx & DIR_MASK); v[opos++] = (short) (1 | ddy & DIR_MASK); - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -401,8 +401,8 @@ public final class LineLayer extends Layer { outside = (x < tmin || x > tmax || y < tmin || y > tmax); - if (opos == VertexPoolItem.SIZE) { - si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si.next = VertexItem.pool.get(); si = si.next; opos = 0; v = si.vertices; @@ -425,8 +425,8 @@ public final class LineLayer extends Layer { v[opos++] = (short) (0 | ddx & DIR_MASK); v[opos++] = (short) (1 | ddy & DIR_MASK); - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -436,8 +436,8 @@ public final class LineLayer extends Layer { v[opos++] = (short) (2 | -ddx & DIR_MASK); v[opos++] = (short) (1 | -ddy & DIR_MASK); - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -454,8 +454,8 @@ public final class LineLayer extends Layer { v[opos++] = dx; v[opos++] = dy; - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -471,8 +471,8 @@ public final class LineLayer extends Layer { v[opos++] = dx; v[opos++] = dy; - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -502,8 +502,8 @@ public final class LineLayer extends Layer { v[opos++] = (short) (0 | (flip ? -ddx : ddx) & DIR_MASK); v[opos++] = (short) (1 | (flip ? -ddy : ddy) & DIR_MASK); - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } @@ -519,8 +519,8 @@ public final class LineLayer extends Layer { v[opos++] = dx; v[opos++] = dy; - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } diff --git a/src/org/oscim/renderer/layer/LineTexLayer.java b/src/org/oscim/renderer/layer/LineTexLayer.java index b43857fe..6560e575 100644 --- a/src/org/oscim/renderer/layer/LineTexLayer.java +++ b/src/org/oscim/renderer/layer/LineTexLayer.java @@ -89,8 +89,8 @@ public final class LineTexLayer extends Layer { public void addLine(float[] points, short[] index) { - if (pool == null) { - curItem = pool = VertexPool.get(); + if (vertexItems == null) { + curItem = vertexItems = VertexItem.pool.get(); // HACK add one vertex offset when compiling // buffer otherwise one cant use the full @@ -103,7 +103,7 @@ public final class LineTexLayer extends Layer { verticesCnt = 1; } - VertexPoolItem si = curItem; + VertexItem si = curItem; short v[] = si.vertices; int opos = si.used; @@ -169,8 +169,8 @@ public final class LineTexLayer extends Layer { short dx = (short) (ux * DIR_SCALE); short dy = (short) (uy * DIR_SCALE); - if (opos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (opos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; opos = 0; } diff --git a/src/org/oscim/renderer/layer/PolygonLayer.java b/src/org/oscim/renderer/layer/PolygonLayer.java index cb26448d..2749774e 100644 --- a/src/org/oscim/renderer/layer/PolygonLayer.java +++ b/src/org/oscim/renderer/layer/PolygonLayer.java @@ -28,14 +28,14 @@ public final class PolygonLayer extends Layer { PolygonLayer(int layer) { this.level = layer; this.type = Layer.POLYGON; - curItem = VertexPool.get(); - pool = curItem; + curItem = VertexItem.pool.get(); + vertexItems = curItem; } public void addPolygon(float[] points, short[] index) { short center = (short) ((Tile.SIZE >> 1) * S); - VertexPoolItem si = curItem; + VertexItem si = curItem; short[] v = si.vertices; int outPos = si.used; @@ -54,8 +54,8 @@ public final class PolygonLayer extends Layer { int inPos = pos; - if (outPos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (outPos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; outPos = 0; } @@ -64,8 +64,8 @@ public final class PolygonLayer extends Layer { v[outPos++] = center; for (int j = 0; j < length; j += 2) { - if (outPos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (outPos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; outPos = 0; } @@ -73,8 +73,8 @@ public final class PolygonLayer extends Layer { v[outPos++] = (short) (points[inPos++] * S); } - if (outPos == VertexPoolItem.SIZE) { - si = si.next = VertexPool.get(); + if (outPos == VertexItem.SIZE) { + si = si.next = VertexItem.pool.get(); v = si.vertices; outPos = 0; } diff --git a/src/org/oscim/renderer/layer/SymbolItem.java b/src/org/oscim/renderer/layer/SymbolItem.java index bf6f40f5..e25224bd 100644 --- a/src/org/oscim/renderer/layer/SymbolItem.java +++ b/src/org/oscim/renderer/layer/SymbolItem.java @@ -14,47 +14,28 @@ */ package org.oscim.renderer.layer; +import org.oscim.utils.pool.Inlist; +import org.oscim.utils.pool.SyncPool; + import android.graphics.Bitmap; import android.graphics.drawable.Drawable; -public class SymbolItem { - private static Object lock = new Object(); - private static SymbolItem pool; +public class SymbolItem extends Inlist { - public static SymbolItem get() { - synchronized (lock) { - if (pool == null) - return new SymbolItem(); + public final static SyncPool pool = new SyncPool() { - SymbolItem ti = pool; - pool = pool.next; - - ti.next = null; - - return ti; + @Override + protected SymbolItem createItem() { + return new SymbolItem(); } - } - public static void release(SymbolItem ti) { - if (ti == null) - return; - - synchronized (lock) { - while (ti != null) { - SymbolItem next = ti.next; - - ti.drawable = null; - ti.bitmap = null; - - ti.next = pool; - pool = ti; - - ti = next; - } + @Override + protected void clearItem(SymbolItem it) { + // drop references + it.drawable = null; + it.bitmap = null; } - } - - SymbolItem next; + }; public Bitmap bitmap; public Drawable drawable; @@ -65,5 +46,4 @@ public class SymbolItem { // center, top, bottom, left, right, top-left... // byte placement; - } diff --git a/src/org/oscim/renderer/layer/SymbolLayer.java b/src/org/oscim/renderer/layer/SymbolLayer.java index 3f678509..0e51d04b 100644 --- a/src/org/oscim/renderer/layer/SymbolLayer.java +++ b/src/org/oscim/renderer/layer/SymbolLayer.java @@ -14,7 +14,6 @@ */ package org.oscim.renderer.layer; -import org.oscim.renderer.TextureObject; import org.oscim.renderer.TextureRenderer; import android.graphics.Canvas; @@ -27,8 +26,8 @@ import android.util.Log; public final class SymbolLayer extends TextureLayer { private final static String TAG = SymbolLayer.class.getSimpleName(); - private final static int TEXTURE_WIDTH = TextureObject.TEXTURE_WIDTH; - private final static int TEXTURE_HEIGHT = TextureObject.TEXTURE_HEIGHT; + private final static int TEXTURE_WIDTH = TextureItem.TEXTURE_WIDTH; + private final static int TEXTURE_HEIGHT = TextureItem.TEXTURE_HEIGHT; private final static float SCALE = 8.0f; SymbolItem symbols; @@ -63,7 +62,7 @@ public final class SymbolLayer extends TextureLayer { verticesCnt += 4; - SymbolItem item = SymbolItem.get(); + SymbolItem item = SymbolItem.pool.get(); item.drawable = drawable; item.x = x; item.y = y; @@ -93,9 +92,9 @@ public final class SymbolLayer extends TextureLayer { short offsetIndices = 0; short curIndices = 0; - curItem = VertexPool.get(); - pool = curItem; - VertexPoolItem si = curItem; + curItem = VertexItem.pool.get(); + vertexItems = curItem; + VertexItem si = curItem; int pos = si.used; short buf[] = si.vertices; @@ -104,7 +103,7 @@ public final class SymbolLayer extends TextureLayer { float x = 0; float y = 0; - TextureObject to = TextureObject.get(); + TextureItem to = TextureItem.pool.get(); textures = to; mCanvas.setBitmap(to.bitmap); @@ -140,7 +139,7 @@ public final class SymbolLayer extends TextureLayer { offsetIndices = numIndices; curIndices = 0; - to.next = TextureObject.get(); + to.next = TextureItem.pool.get(); to = to.next; mCanvas.setBitmap(to.bitmap); @@ -196,9 +195,9 @@ public final class SymbolLayer extends TextureLayer { short tx = (short) ((int) (SCALE * it2.x) & LBIT_MASK | (it2.billboard ? 1 : 0)); short ty = (short) (SCALE * it2.y); - if (pos == VertexPoolItem.SIZE) { - si.used = VertexPoolItem.SIZE; - si = si.next = VertexPool.get(); + if (pos == VertexItem.SIZE) { + si.used = VertexItem.SIZE; + si = si.next = VertexItem.pool.get(); buf = si.vertices; pos = 0; } @@ -249,12 +248,12 @@ public final class SymbolLayer extends TextureLayer { @Override protected void clear() { - TextureObject.release(textures); - SymbolItem.release(symbols); - VertexPool.release(pool); + TextureItem.pool.releaseAll(textures); + SymbolItem.pool.releaseAll(symbols); + VertexItem.pool.releaseAll(vertexItems); textures = null; symbols = null; - pool = null; + vertexItems = null; verticesCnt = 0; } } diff --git a/src/org/oscim/renderer/layer/TextItem.java b/src/org/oscim/renderer/layer/TextItem.java index 8260a17e..fcaad86b 100644 --- a/src/org/oscim/renderer/layer/TextItem.java +++ b/src/org/oscim/renderer/layer/TextItem.java @@ -15,117 +15,45 @@ package org.oscim.renderer.layer; import org.oscim.theme.renderinstruction.Text; +import org.oscim.utils.pool.Inlist; +import org.oscim.utils.pool.SyncPool; -import android.util.Log; - -public class TextItem { - private final static String TAG = TextItem.class.getName(); +public class TextItem extends Inlist { + //private final static String TAG = TextItem.class.getName(); private final static int MAX_POOL = 250; - private static Object lock = new Object(); - private static TextItem pool; - private static int count = 0; - private static int inPool = 0; + public final static SyncPool pool = new SyncPool(MAX_POOL) { - public static TextItem get() { - synchronized (lock) { - if (pool == null) { - count++; - return new TextItem(); - } - - inPool--; - TextItem ti = pool; - pool = pool.next; - - ti.next = null; - //ti.active = 0; - return ti; + @Override + protected TextItem createItem() { + return new TextItem(); } - } + + @Override + protected void clearItem(TextItem ti) { + // drop references + ti.string = null; + ti.text = null; + ti.n1 = null; + ti.n2 = null; + } + }; public static TextItem copy(TextItem orig) { - synchronized (lock) { - TextItem ti = pool; - if (ti == null) { - count++; - ti = new TextItem(); - } else { - inPool--; - pool = pool.next; - } + TextItem ti = pool.get(); - ti.next = null; + ti.next = null; - ti.x = orig.x; - ti.y = orig.y; + ti.x = orig.x; + ti.y = orig.y; - ti.x1 = orig.x1; - ti.y1 = orig.y1; - ti.x2 = orig.x2; - ti.y2 = orig.y2; + ti.x1 = orig.x1; + ti.y1 = orig.y1; + ti.x2 = orig.x2; + ti.y2 = orig.y2; - return ti; - } - } - - // public static void append(TextItem ti, TextItem in) { - // if (ti == null) - // return; - // if (ti.next == null) { - // in.next = ti.next; - // ti.next = in; - // } - // - // TextItem t = ti; - // while (t.next != null) - // t = t.next; - // - // in.next = t.next; - // t.next = in; - // } - - public static void release(TextItem ti) { - if (ti == null) - return; - - if (inPool > MAX_POOL) { - while (ti != null) { - TextItem next = ti.next; - - // drop references - ti.string = null; - ti.text = null; - ti.n1 = null; - ti.n2 = null; - ti = next; - count--; - } - } - - synchronized (lock) { - while (ti != null) { - TextItem next = ti.next; - ti.next = pool; - - // drop references - ti.string = null; - ti.text = null; - ti.n1 = null; - ti.n2 = null; - - pool = ti; - - ti = next; - - inPool++; - } - } - } - - public static void printPool() { - Log.d(TAG, "in pool " + inPool + " / " + count); + return ti; } public TextItem set(float x, float y, String string, Text text) { @@ -137,33 +65,6 @@ public class TextItem { return this; } - public TextItem move(TextItem ti, float dx, float dy) { - this.x = dx + ti.x; - this.y = dy + ti.y; - return this; - - } - - public TextItem move(TextItem ti, float dx, float dy, float scale) { - this.x = (dx + ti.x) * scale; - this.y = (dy + ti.y) * scale; - return this; - } - - public void clone(TextItem ti){ - this.string = ti.string; - this.text = ti.text; - this.width = ti.width; - this.length = ti.length; - } - - public void setAxisAlignedBBox() { - this.x1 = x - width / 2; - this.y1 = y - text.fontHeight / 2; - this.x2 = x + width / 2; - this.y2 = y + text.fontHeight / 2; - } - public static boolean bboxOverlaps(TextItem it1, TextItem it2, float add) { if (it1.y1 < it1.y2) { if (it2.y1 < it2.y2) @@ -194,7 +95,7 @@ public class TextItem { } // link to next node - public TextItem next; + //public TextItem next; // center public float x, y; diff --git a/src/org/oscim/renderer/layer/TextLayer.java b/src/org/oscim/renderer/layer/TextLayer.java index afd68095..f838b5a9 100644 --- a/src/org/oscim/renderer/layer/TextLayer.java +++ b/src/org/oscim/renderer/layer/TextLayer.java @@ -14,18 +14,16 @@ */ package org.oscim.renderer.layer; -import org.oscim.renderer.TextureObject; import org.oscim.renderer.TextureRenderer; import android.graphics.Canvas; -import android.util.Log; public final class TextLayer extends TextureLayer { //private static String TAG = TextureLayer.class.getName(); - private final static int TEXTURE_WIDTH = TextureObject.TEXTURE_WIDTH; - private final static int TEXTURE_HEIGHT = TextureObject.TEXTURE_HEIGHT; + private final static int TEXTURE_WIDTH = TextureItem.TEXTURE_WIDTH; + private final static int TEXTURE_HEIGHT = TextureItem.TEXTURE_HEIGHT; private final static float SCALE = 8.0f; private final static int LBIT_MASK = 0xfffffffe; @@ -45,25 +43,6 @@ public final class TextLayer extends TextureLayer { fixed = true; } - public boolean removeText(TextItem item) { - - if (item == labels) { - labels = labels.next; - return true; - } - - for (TextItem prev = labels, it = labels.next; it != null; it = it.next) { - - if (it == item) { - prev.next = it.next; - return true; - } - prev = it; - } - - return false; - } - public void addText(TextItem item) { TextItem it = labels; @@ -97,13 +76,11 @@ public final class TextLayer extends TextureLayer { @Override public boolean prepare() { - if (TextureRenderer.debug) - Log.d("...", "prepare"); short numIndices = 0; short offsetIndices = 0; - VertexPoolItem vi = pool = VertexPool.get(); + VertexItem vi = vertexItems = VertexItem.pool.get(); int pos = vi.used; // 0 short buf[] = vi.vertices; @@ -114,7 +91,7 @@ public final class TextLayer extends TextureLayer { float y = 0; float yy; - TextureObject to = TextureObject.get(); + TextureItem to = TextureItem.pool.get(); textures = to; mCanvas.setBitmap(to.bitmap); @@ -136,7 +113,7 @@ public final class TextLayer extends TextureLayer { to.vertices = (short) (numIndices - offsetIndices); offsetIndices = numIndices; - to.next = TextureObject.get(); + to.next = TextureItem.pool.get(); to = to.next; mCanvas.setBitmap(to.bitmap); @@ -227,9 +204,9 @@ public final class TextLayer extends TextureLayer { short tx = (short) (tmp | (it.text.caption ? 1 : 0)); short ty = (short) (SCALE * it.y); - if (pos == VertexPoolItem.SIZE) { - vi.used = VertexPoolItem.SIZE; - vi = vi.next = VertexPool.get(); + if (pos == VertexItem.SIZE) { + vi.used = VertexItem.SIZE; + vi = vi.next = VertexItem.pool.get(); buf = vi.vertices; pos = 0; } @@ -288,12 +265,12 @@ public final class TextLayer extends TextureLayer { @Override protected void clear() { - TextureObject.release(textures); - TextItem.release(labels); - VertexPool.release(pool); + TextureItem.pool.releaseAll(textures); + TextItem.pool.releaseAll(labels); + VertexItem.pool.releaseAll(vertexItems); textures = null; labels = null; - pool = null; + vertexItems = null; verticesCnt = 0; } } diff --git a/src/org/oscim/renderer/TextureObject.java b/src/org/oscim/renderer/layer/TextureItem.java similarity index 60% rename from src/org/oscim/renderer/TextureObject.java rename to src/org/oscim/renderer/layer/TextureItem.java index f3a5c86b..c062312d 100644 --- a/src/org/oscim/renderer/TextureObject.java +++ b/src/org/oscim/renderer/layer/TextureItem.java @@ -12,10 +12,14 @@ * You should have received a copy of the GNU Lesser General Public License along with * this program. If not, see . */ -package org.oscim.renderer; +package org.oscim.renderer.layer; import java.util.ArrayList; +import org.oscim.renderer.TextureRenderer; +import org.oscim.utils.pool.Inlist; +import org.oscim.utils.pool.SyncPool; + import android.graphics.Bitmap; import android.graphics.Color; import android.opengl.GLES20; @@ -25,11 +29,64 @@ import android.util.Log; /** * @author Hannes Janetzek */ -public class TextureObject { - private final static String TAG = TextureObject.class.getName(); +public class TextureItem extends Inlist { + private final static String TAG = TextureItem.class.getName(); - private static TextureObject pool; - private static int poolCount; + // texture ID + public int id; + + int width; + int height; + + // vertex offset from which this texture is referenced + public short offset; + public short vertices; + + // temporary Bitmap + public Bitmap bitmap; + + TextureItem(int id) { + this.id = id; + } + + public final static SyncPool pool = new SyncPool() { + + @Override + public void init(int num) { + this.pool = null; + + int[] textureIds = new int[num]; + GLES20.glGenTextures(num, textureIds, 0); + + for (int i = 1; i < num; i++) { + initTexture(textureIds[i]); + TextureItem to = new TextureItem(textureIds[i]); + + to.next = this.pool; + this.pool = to; + } + } + + @Override + public TextureItem get() { + TextureItem it = super.get(); + + it.bitmap = TextureItem.getBitmap(); + it.bitmap.eraseColor(Color.TRANSPARENT); + + return it; + } + + @Override + protected TextureItem createItem() { + return new TextureItem(-1); + } + + @Override + protected void clearItem(TextureItem it) { + TextureItem.releaseBitmap(it); + } + }; private static ArrayList mBitmaps; @@ -39,62 +96,12 @@ public class TextureObject { private static int mBitmapFormat; private static int mBitmapType; - /** - * Get a TextureObject with Bitmap to draw to. - * 'uploadTexture()' uploads the Bitmap as texture. - * - * @return obtained TextureObject - */ - public static synchronized TextureObject get() { - TextureObject to; - - if (pool == null) { - poolCount += 1; - if (TextureRenderer.debug) - Log.d(TAG, "textures: " + poolCount); - pool = new TextureObject(-1); - } - - to = pool; - pool = pool.next; - - to.next = null; - - to.bitmap = getBitmap(); - to.bitmap.eraseColor(Color.TRANSPARENT); - - if (TextureRenderer.debug) - Log.d(TAG, "get texture " + to.id + " " + to.bitmap); - - return to; - } - - public static synchronized void release(TextureObject to) { - while (to != null) { - if (TextureRenderer.debug) - Log.d(TAG, "release texture " + to.id); - - TextureObject next = to.next; - - if (to.bitmap != null) { - mBitmaps.add(to.bitmap); - to.bitmap = null; - } - - to.next = pool; - pool = to; - - to = next; - } - } - /** * This function may only be used in GLRenderer Thread. * * @param to the TextureObjet to compile and upload */ - public static synchronized void uploadTexture(TextureObject to) { - // FIXME what needs synchronized ? + public static void uploadTexture(TextureItem to) { if (TextureRenderer.debug) Log.d(TAG, "upload texture " + to.id); @@ -104,6 +111,7 @@ public class TextureObject { GLES20.glGenTextures(1, textureIds, 0); to.id = textureIds[0]; initTexture(to.id); + if (TextureRenderer.debug) Log.d(TAG, "new texture " + to.id); } @@ -111,11 +119,10 @@ public class TextureObject { uploadTexture(to, to.bitmap, mBitmapFormat, mBitmapType, TEXTURE_WIDTH, TEXTURE_HEIGHT); - mBitmaps.add(to.bitmap); - to.bitmap = null; + TextureItem.releaseBitmap(to); } - public static void uploadTexture(TextureObject to, Bitmap bitmap, + public static void uploadTexture(TextureItem to, Bitmap bitmap, int format, int type, int w, int h) { if (to == null) { @@ -145,20 +152,8 @@ public class TextureObject { GLES20.GL_CLAMP_TO_EDGE); // Set V Wrapping } - static void init(int num) { - pool = null; - poolCount = num; - - int[] textureIds = new int[num]; - GLES20.glGenTextures(num, textureIds, 0); - - for (int i = 1; i < num; i++) { - initTexture(textureIds[i]); - TextureObject to = new TextureObject(textureIds[i]); - - to.next = pool; - pool = to; - } + public static void init(int num) { + pool.init(num); mBitmaps = new ArrayList(10); @@ -174,39 +169,32 @@ public class TextureObject { mBitmapType = GLUtils.getType(mBitmaps.get(0)); } - private static Bitmap getBitmap() { - int size = mBitmaps.size(); - if (size == 0) { - Bitmap bitmap = Bitmap.createBitmap( - TEXTURE_WIDTH, TEXTURE_HEIGHT, - Bitmap.Config.ARGB_8888); + static Bitmap getBitmap() { + synchronized (mBitmaps) { - if (TextureRenderer.debug) - Log.d(TAG, "alloc bitmap: " + - android.os.Debug.getNativeHeapAllocatedSize() / (1024 * 1024)); + int size = mBitmaps.size(); + if (size == 0) { + Bitmap bitmap = Bitmap.createBitmap( + TEXTURE_WIDTH, TEXTURE_HEIGHT, + Bitmap.Config.ARGB_8888); - return bitmap; + if (TextureRenderer.debug) + Log.d(TAG, "alloc bitmap: " + + android.os.Debug.getNativeHeapAllocatedSize() / (1024 * 1024)); + + return bitmap; + } + return mBitmaps.remove(size - 1); } - return mBitmaps.remove(size - 1); } - // ----------------------- - public TextureObject next; + static void releaseBitmap(TextureItem it) { + synchronized (mBitmaps) { - // texture ID - int id; - - int width; - int height; - - // vertex offset from which this texture is referenced - public short offset; - public short vertices; - - // temporary Bitmap - public Bitmap bitmap; - - TextureObject(int id) { - this.id = id; + if (it.bitmap != null) { + mBitmaps.add(it.bitmap); + it.bitmap = null; + } + } } } diff --git a/src/org/oscim/renderer/layer/TextureLayer.java b/src/org/oscim/renderer/layer/TextureLayer.java index 3d4879dd..281693f6 100644 --- a/src/org/oscim/renderer/layer/TextureLayer.java +++ b/src/org/oscim/renderer/layer/TextureLayer.java @@ -16,14 +16,13 @@ package org.oscim.renderer.layer; import java.nio.ShortBuffer; -import org.oscim.renderer.TextureObject; /** * @author Hannes Janetzek */ public abstract class TextureLayer extends Layer { // holds textures and offset in vbo - public TextureObject textures; + public TextureItem textures; // scale mode public boolean fixed; @@ -35,8 +34,8 @@ public abstract class TextureLayer extends Layer { @Override protected void compile(ShortBuffer sbuf) { - for (TextureObject to = textures; to != null; to = to.next) - TextureObject.uploadTexture(to); + for (TextureItem to = textures; to != null; to = to.next) + TextureItem.uploadTexture(to); // add vertices to vbo Layers.addPoolItems(this, sbuf); diff --git a/src/org/oscim/renderer/layer/VertexPoolItem.java b/src/org/oscim/renderer/layer/VertexItem.java similarity index 69% rename from src/org/oscim/renderer/layer/VertexPoolItem.java rename to src/org/oscim/renderer/layer/VertexItem.java index 570e96aa..ade015da 100644 --- a/src/org/oscim/renderer/layer/VertexPoolItem.java +++ b/src/org/oscim/renderer/layer/VertexItem.java @@ -14,11 +14,29 @@ */ package org.oscim.renderer.layer; -public class VertexPoolItem { +import org.oscim.utils.pool.Inlist; +import org.oscim.utils.pool.SyncPool; + +public class VertexItem extends Inlist { + + private static final int MAX_POOL = 500; + + public final static SyncPool pool = new SyncPool(MAX_POOL) { + + @Override + protected VertexItem createItem() { + return new VertexItem(); + } + + @Override + protected void clearItem(VertexItem it) { + it.used = 0; + } + }; + public final short[] vertices = new short[SIZE]; public int used; - public VertexPoolItem next; // must be multiple of // 4 (LineLayer/PolygonLayer), diff --git a/src/org/oscim/renderer/layer/VertexPool.java b/src/org/oscim/renderer/layer/VertexPool.java deleted file mode 100644 index 4258f9ca..00000000 --- a/src/org/oscim/renderer/layer/VertexPool.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2012 Hannes Janetzek - * - * This program is free software: you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * this program. If not, see . - */ -package org.oscim.renderer.layer; - -import android.util.Log; - -public class VertexPool { - private static final int POOL_LIMIT = 5000; - - static private VertexPoolItem pool = null; - static private int count = 0; - static private int countAll = 0; - - public static synchronized void init() { - count = 0; - countAll = 0; - pool = null; - } - - public static VertexPoolItem getNext(VertexPoolItem prev) { - VertexPoolItem it = get(); - if (prev != null) { - prev.next = it; - prev.used = VertexPoolItem.SIZE; - } - return it; - } - - public static synchronized VertexPoolItem get() { - - if (pool == null && count > 0) { - Log.d("VertexPool", "BUG wrong count: " + count); - } - if (pool == null) { - countAll++; - return new VertexPoolItem(); - } - - count--; - - if (count < 0) { - int c = 0; - - for (VertexPoolItem tmp = pool; tmp != null; tmp = tmp.next) - c++; - - Log.d("VertexPool", "BUG wrong count: " + count + " left" + c); - return new VertexPoolItem(); - } - - VertexPoolItem it = pool; - pool = pool.next; - it.used = 0; - it.next = null; - return it; - } - - public static synchronized void release(VertexPoolItem items) { - if (items == null) - return; - - // limit pool items - if (countAll < POOL_LIMIT) { - - VertexPoolItem last = items; - - while (true) { - count++; - - if (last.next == null) - break; - - last = last.next; - } - - last.next = pool; - pool = items; - - } else { - VertexPoolItem prev, tmp = items; - while (tmp != null) { - prev = tmp; - tmp = tmp.next; - - countAll--; - prev.next = null; - - } - } - } -} diff --git a/src/org/oscim/renderer/overlays/GridOverlay.java b/src/org/oscim/renderer/overlays/GridOverlay.java index 36b87f92..71653708 100644 --- a/src/org/oscim/renderer/overlays/GridOverlay.java +++ b/src/org/oscim/renderer/overlays/GridOverlay.java @@ -77,7 +77,7 @@ public class GridOverlay extends BasicOverlay { for (int i = -2; i < 2; i++) { for (int j = -2; j < 2; j++) { - TextItem ti = TextItem.get().set(size * j + size / 2, size * i + size / 2, + TextItem ti = TextItem.pool.get().set(size * j + size / 2, size * i + size / 2, (x + j) + " / " + (y + i) + " / " + z, mText); // TextItem ti = new TextItem(size * j + size / 2, size * i + diff --git a/src/org/oscim/renderer/overlays/TextOverlay.java b/src/org/oscim/renderer/overlays/TextOverlay.java index 64ed57c1..192ce74d 100644 --- a/src/org/oscim/renderer/overlays/TextOverlay.java +++ b/src/org/oscim/renderer/overlays/TextOverlay.java @@ -47,6 +47,7 @@ import org.oscim.theme.renderinstruction.Line; import org.oscim.utils.FastMath; import org.oscim.utils.OBB2D; import org.oscim.utils.PausableThread; +import org.oscim.utils.pool.Pool; import org.oscim.view.MapView; import org.oscim.view.MapViewPosition; @@ -57,6 +58,8 @@ import android.os.SystemClock; public class TextOverlay extends BasicOverlay { //private final static String TAG = TextOverlay.class.getName(); + private final static float MIN_CAPTION_DIST = 5; + private final static float MIN_WAY_DIST = 3; private final MapViewPosition mMapViewPosition; private TileSet mTileSet; @@ -70,8 +73,27 @@ public class TextOverlay extends BasicOverlay { private TextLayer mNextLayer; // local pool, avoids synchronized TextItem.get()/release() - private Label mPool; + + + class LabelPool extends Pool{ + Label releaseAndGetNext(Label l){ + if (l.item != null){ + TextItem.pool.release(l.item); + l.item = null; + } + + Label ret = (Label) l.next; + super.release(l); + + return ret; + } + + } + + private final LabelPool mPool = new LabelPool(); + private Label mPrevLabels; + private Label mLabels; private final float[] mTmpCoords = new float[8]; @@ -89,9 +111,38 @@ public class TextOverlay extends BasicOverlay { MapTile tile; - public byte origin; + //public byte origin; public int active; public OBB2D bbox; + + public TextItem move(TextItem ti, float dx, float dy) { + this.x = dx + ti.x; + this.y = dy + ti.y; + return this; + + } + + public TextItem move(TextItem ti, float dx, float dy, float scale) { + this.x = (dx + ti.x) * scale; + this.y = (dy + ti.y) * scale; + return this; + } + + public void clone(TextItem ti) { + this.string = ti.string; + this.text = ti.text; + this.width = ti.width; + this.length = ti.length; + } + + public void setAxisAlignedBBox() { + this.x1 = x - width / 2; + this.y1 = y - text.fontHeight / 2; + this.x2 = x + width / 2; + this.y2 = y + text.fontHeight / 2; + } + + // } // class Link { @@ -112,7 +163,7 @@ public class TextOverlay extends BasicOverlay { @Override protected void doWork() { - SystemClock.sleep(500); + SystemClock.sleep(250); if (!mRun) return; @@ -153,22 +204,47 @@ public class TextOverlay extends BasicOverlay { mRelabelCnt = 0; } - private Label removeLabel(TextLayer tl, Label l) { - Label tmp = l; - l = (Label) l.next; - - TextItem.release(tmp.item); - tl.removeText(tmp); - - tmp.next = mPool; - mPool = tmp; - - return l; + // remove Label l from mLabels and return l.next + private Label removeLabel(Label l) { + Label ret = (Label)l.next; + mPool.release(mLabels, l); + return ret; } - private byte checkOverlap(TextLayer tl, Label ti) { + public void addLabel(Label item) { + TextItem it = mLabels; - for (Label lp = (Label) tl.labels; lp != null;) { + for (; it != null; it = it.next) { + + if (item.text == it.text) { + while (it.next != null + // break if next item uses different text style + && item.text == it.next.text + // check same string instance + && item.string != it.string + // check same string + && !item.string.equals(it.string)) + it = it.next; + + // unify duplicate string :) + // Note: this is required for 'packing test' in prepare to work! + if (item.string != it.string && item.string.equals(it.string)) + item.string = it.string; + + // insert after text of same type and/or before same string + item.next = it.next; + it.next = item; + return; + } + } + + item.next = mLabels; + mLabels = item; + } + + private byte checkOverlap(Label ti) { + + for (Label lp = mLabels; lp != null;) { // check bounding box if (!TextItem.bboxOverlaps(ti, lp, 150)) { @@ -187,7 +263,7 @@ public class TextOverlay extends BasicOverlay { // keep the label with longer segment if (lp.length < ti.length) { - lp = removeLabel(tl, lp); + lp = removeLabel(lp); continue; } @@ -207,7 +283,7 @@ public class TextOverlay extends BasicOverlay { if (!lp.text.caption && (lp.text.priority > ti.text.priority || lp.length < ti.length)) { - lp = removeLabel(tl, lp); + lp = removeLabel(lp); continue; } @@ -247,38 +323,29 @@ public class TextOverlay extends BasicOverlay { private Layers mDebugLayer; private final static float[] mDebugPoints = new float[4]; - //private final Matrix4 mMVP = new Matrix4(); - - //void addTile(MapTile t) { - //} - - private Label addToPool(Label l) { - TextItem.release(l.item); - l.item = null; - - Label next = (Label) l.next; - l.next = mPool; - mPool = l; - - return next; - } - private Label getLabel() { - Label l; + Label l = (Label)mPool.get(); - if (mPool == null) + if (l == null) l = new Label(); - else { - l = mPool; - mPool = (Label) mPool.next; - l.next = null; - } + l.active = Integer.MAX_VALUE; return l; } + private static float flipLatitude(float dx, int max) { + // flip around date-line + if (dx > max) + dx = dx - max * 2; + else if (dx < -max) + dx = dx + max * 2; + + return dx; + } + boolean updateLabels() { + // could this happen? if (mTmpLayer == null) return false; @@ -288,12 +355,6 @@ public class TextOverlay extends BasicOverlay { if (mTileSet.cnt == 0) return false; - // reuse text layer - TextLayer tl = mTmpLayer; - mTmpLayer = null; - - //mNewLabels = null; - Layers dbg = null; if (mMapView.getDebugSettings().debugLabels) dbg = new Layers(); @@ -304,31 +365,24 @@ public class TextOverlay extends BasicOverlay { synchronized (mMapViewPosition) { mMapViewPosition.getMapPosition(pos); mMapViewPosition.getMapViewProjection(coords); - //mMapViewPosition.getMatrix(null, null, mMVP); } + int mw = (mMapView.getWidth() + Tile.SIZE) / 2; int mh = (mMapView.getHeight() + Tile.SIZE) / 2; mSquareRadius = mw * mw + mh * mh; - // mTiles might be from another zoomlevel than the current: - // this scales MapPosition to the zoomlevel of mTiles... - // TODO create a helper function in MapPosition MapTile[] tiles = mTileSet.tiles; - //int zoom = tiles[0].zoomLevel; + int zoom = tiles[0].zoomLevel; - int diff = tiles[0].zoomLevel - pos.zoomLevel; - float div = FastMath.pow(diff); - - double scale = pos.getZoomScale() * div; - - //float scale = (float)(pos.absScale / (1 << zoom) ); + // scale of tiles zoom-level relative to current position + double scale = pos.scale / (1 << zoom); double angle = Math.toRadians(pos.angle); float cos = (float) Math.cos(angle); float sin = (float) Math.sin(angle); - int maxx = Tile.SIZE << (pos.zoomLevel - 1); + int maxx = Tile.SIZE << (zoom - 1); Label l = null; @@ -337,72 +391,69 @@ public class TextOverlay extends BasicOverlay { mRelabelCnt++; - double tileX = (pos.x * (Tile.SIZE << pos.zoomLevel)); - double tileY = (pos.y * (Tile.SIZE << pos.zoomLevel)); + double tileX = (pos.x * (Tile.SIZE << zoom)); + double tileY = (pos.y * (Tile.SIZE << zoom)); for (l = mPrevLabels; l != null;) { - - // transform screen coordinates to tile coordinates - float s = FastMath.pow(l.tile.zoomLevel - pos.zoomLevel); - - //float sscale = (float)((1 << l.tile.zoomLevel) / pos.absScale); - - float sscale = (float) (pos.getZoomScale() / s); - - if (l.width > l.length * sscale) { - //Log.d(TAG, "- scale " + lp + " " + s + " " + sscale + " " + lp.length + " " + lp.width); - l = addToPool(l); + if (l.text.caption) { + l = mPool.releaseAndGetNext(l); continue; } - float dx = (float) (l.tile.tileX * Tile.SIZE - tileX * s); - float dy = (float) (l.tile.tileY * Tile.SIZE - tileY * s); + int diff = l.tile.zoomLevel - zoom; + if (diff > 1 || diff < -1) { + l = mPool.releaseAndGetNext(l); + continue; + } - // flip around date-line - if (dx > maxx) - dx = dx - maxx * 2; - else if (dx < -maxx) - dx = dx + maxx * 2; + float div = FastMath.pow(diff); + float sscale = (float) (pos.scale / (1 << l.tile.zoomLevel)); + + if (l.width > l.length * sscale) { + l = mPool.releaseAndGetNext(l); + continue; + } + + float dx = (float) (l.tile.tileX * Tile.SIZE - tileX * div); + float dy = (float) (l.tile.tileY * Tile.SIZE - tileY * div); + + dx = flipLatitude(dx, maxx); l.move(l.item, dx, dy, sscale); - if (!l.text.caption) { - // set line endpoints relative to view to be able to - // check intersections with label from other tiles - float width = (l.item.x2 - l.item.x1) / 2f; - float height = (l.item.y2 - l.item.y1) / 2f; + // set line endpoints relative to view to be able to + // check intersections with label from other tiles + float w = (l.item.x2 - l.item.x1) / 2f; + float h = (l.item.y2 - l.item.y1) / 2f; + l.x1 = l.x - w; + l.y1 = l.y - h; + l.x2 = l.x + w; + l.y2 = l.y + h; - l.x2 = (l.x + width); - l.x1 = (l.x - width); - l.y2 = (l.y + height); - l.y1 = (l.y - height); - - if (!wayIsVisible(l)) { - l = addToPool(l); - continue; - } - - byte overlaps = -1; - - l.bbox.set(l.x, l.y, l.x1, l.y1, l.width + 5, l.text.fontHeight + 5); - - overlaps = checkOverlap(tl, l); - - if (dbg != null) - addDebugBox(dbg, l, l.item, overlaps, true, sscale); - - if (overlaps == 0) { - - Label tmp = l; - l = (Label) l.next; - - tmp.next = null; - tl.addText(tmp); - continue; - } + if (!wayIsVisible(l)) { + l = mPool.releaseAndGetNext(l); + continue; } - l = addToPool(l); + l.bbox.set(l.x, l.y, l.x1, l.y1, + l.width + MIN_WAY_DIST, + l.text.fontHeight + MIN_WAY_DIST); + + byte overlaps = checkOverlap(l); + + if (dbg != null) + addDebugBox(dbg, l, l.item, overlaps, true, sscale); + + if (overlaps == 0) { + Label tmp = l; + l = (Label) l.next; + + tmp.next = null; + addLabel(tmp); + continue; + } + + l = mPool.releaseAndGetNext(l); } /* add way labels */ @@ -414,12 +465,7 @@ public class TextOverlay extends BasicOverlay { float dx = (float) (t.tileX * Tile.SIZE - tileX); float dy = (float) (t.tileY * Tile.SIZE - tileY); - - // flip around date-line - if (dx > maxx) - dx = dx - maxx * 2; - else if (dx < -maxx) - dx = dx + maxx * 2; + dx = flipLatitude(dx, maxx); for (TextItem ti = t.labels; ti != null; ti = ti.next) { @@ -439,13 +485,13 @@ public class TextOverlay extends BasicOverlay { // set line endpoints relative to view to be able to // check intersections with label from other tiles - float width = (ti.x2 - ti.x1) / 2f; - float height = (ti.y2 - ti.y1) / 2f; + float w = (ti.x2 - ti.x1) / 2f; + float h = (ti.y2 - ti.y1) / 2f; l.bbox = null; - l.x1 = (l.x - width); - l.y1 = (l.y - height); - l.x2 = (l.x + width); - l.y2 = (l.y + height); + l.x1 = l.x - w; + l.y1 = l.y - h; + l.x2 = l.x + w; + l.y2 = l.y + h; if (!wayIsVisible(l)) continue; @@ -453,18 +499,22 @@ public class TextOverlay extends BasicOverlay { byte overlaps = -1; if (l.bbox == null) - l.bbox = new OBB2D(l.x, l.y, l.x1, l.y1, l.width + 5, l.text.fontHeight + 5); + l.bbox = new OBB2D(l.x, l.y, l.x1, l.y1, + l.width + MIN_WAY_DIST, + l.text.fontHeight + MIN_WAY_DIST); else - l.bbox.set(l.x, l.y, l.x1, l.y1, l.width + 5, l.text.fontHeight + 5); + l.bbox.set(l.x, l.y, l.x1, l.y1, + l.width + MIN_WAY_DIST, + l.text.fontHeight + MIN_WAY_DIST); if (dbg == null || ti.width < ti.length * scale) - overlaps = checkOverlap(tl, l); + overlaps = checkOverlap(l); if (dbg != null) addDebugBox(dbg, l, ti, overlaps, false, (float) scale); if (overlaps == 0) { - tl.addText(l); + addLabel(l); l.item = TextItem.copy(ti); l.tile = t; l.active = mRelabelCnt; @@ -481,12 +531,7 @@ public class TextOverlay extends BasicOverlay { float dx = (float) (t.tileX * Tile.SIZE - tileX); float dy = (float) (t.tileY * Tile.SIZE - tileY); - - // flip around date-line - if (dx > maxx) - dx = dx - maxx * 2; - else if (dx < -maxx) - dx = dx + maxx * 2; + dx = flipLatitude(dx, maxx); for (TextItem ti = t.labels; ti != null; ti = ti.next) { if (!ti.text.caption) @@ -506,21 +551,20 @@ public class TextOverlay extends BasicOverlay { if (l.bbox == null) l.bbox = new OBB2D(); - l.bbox.setNormalized(l.x, l.y, cos, -sin, l.width + 6, - l.text.fontHeight + 6); + l.bbox.setNormalized(l.x, l.y, cos, -sin, + l.width + MIN_CAPTION_DIST, + l.text.fontHeight + MIN_CAPTION_DIST); boolean overlaps = false; - for (Label lp = (Label) tl.labels; lp != null; lp = (Label) lp.next) { + for (Label lp = mLabels; lp != null; lp = (Label) lp.next) { if (l.bbox.overlaps(lp.bbox)) { - //Log.d(TAG, "overlap > " + ti2.string + " " + lp.string); - //if (TextItem.bboxOverlaps(ti2, lp, 4)) { overlaps = true; break; } } if (!overlaps) { - tl.addText(l); + addLabel(l); l.item = TextItem.copy(ti); l.tile = t; l.active = mRelabelCnt; @@ -529,8 +573,7 @@ public class TextOverlay extends BasicOverlay { } } - for (Label ti = (Label) tl.labels; ti != null; ti = (Label) ti.next) { - + for (Label ti = mLabels; ti != null; ti = (Label) ti.next) { if (ti.text.caption) continue; @@ -546,17 +589,20 @@ public class TextOverlay extends BasicOverlay { } } - // keep temporarily used Label - if (l != null) { - l.next = mPool; - mPool = l; - } + // temporarily used Label + mPool.release(l); + //reuse text layer + TextLayer tl = mTmpLayer; + mTmpLayer = null; + + tl.labels = mLabels; // draw text to bitmaps and create vertices tl.prepare(); - // after 'prepare' TextLayer does not need TextItems any longer - mPrevLabels = (Label) tl.labels; + // after 'prepare' TextLayer does not need TextItems + mPrevLabels = mLabels; + mLabels = null; tl.labels = null; // remove tile locks diff --git a/src/org/oscim/utils/pool/Inlist.java b/src/org/oscim/utils/pool/Inlist.java new file mode 100644 index 00000000..016b669d --- /dev/null +++ b/src/org/oscim/utils/pool/Inlist.java @@ -0,0 +1,73 @@ +/* + * Copyright 2013 Hannes Janetzek + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package org.oscim.utils.pool; + +public class Inlist> { + + private final static boolean debug = false; + + public T next; + + static > int size(Inlist list) { + int count = 0; + for (Inlist l = list; l != null; l = l.next) + count++; + return count; + } + + public static > Inlist remove(Inlist list, Inlist item) { + if (item == list) { + return item.next; + } + for (Inlist prev = list, it = list.next; it != null; it = it.next) { + + if (it == item) { + prev.next = it.next; + return list; + } + prev = it; + } + + return list; + } + + + static > Inlist prepend(T list, T item) { + item.next = list; + return item; + } + + static > Inlist append(T list, T item) { + + if (debug) { + if (item.next != null) { + // warn + item.next = null; + } + } + + if (list == null) + return item; + + Inlist it = list; + + while (it.next != null) + it = it.next; + + it.next = item; + + return list; + } +} diff --git a/src/org/oscim/utils/pool/Pool.java b/src/org/oscim/utils/pool/Pool.java new file mode 100644 index 00000000..fb557662 --- /dev/null +++ b/src/org/oscim/utils/pool/Pool.java @@ -0,0 +1,62 @@ +/* + * Copyright 2013 Hannes Janetzek + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package org.oscim.utils.pool; + +public class Pool> { + + T pool; + + public void release(T item) { + if (item == null) + return; + item.next = pool; + pool = item; + } + + // remove 'item' from 'list' and add back to pool + public void release(T list, T item) { + if (item == null) + return; + + if (item == list) { + item.next = pool; + pool = item; + return; + } + + for (T prev = list, it = list.next; it != null; it = it.next) { + + if (it == item) { + prev.next = it.next; + + item.next = pool; + pool = item; + return; + } + prev = it; + } + } + + public T get() { + if (pool == null) + return null; + + T ret = pool; + pool = pool.next; + + ret.next = null; + return ret; + } +} diff --git a/src/org/oscim/utils/pool/SyncPool.java b/src/org/oscim/utils/pool/SyncPool.java new file mode 100644 index 00000000..82899e74 --- /dev/null +++ b/src/org/oscim/utils/pool/SyncPool.java @@ -0,0 +1,145 @@ +/* + * Copyright 2013 Hannes Janetzek + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package org.oscim.utils.pool; + +public abstract class SyncPool> { + protected final int maxFill; + protected int fill; + protected int count; + + protected T pool; + + public SyncPool(){ + maxFill = 100; + } + + public SyncPool(int maxItemsInPool) { + maxFill = maxItemsInPool; + fill = 0; + } + + /** + * @param items number of initial items + */ + public void init(int items){ + + } + + /** + * @param item release resources + */ + protected void clearItem(T item) { + + } + + protected abstract T createItem(); + + public void release(T item) { + if (item == null) + return; + + clearItem(item); + + if (fill < maxFill) { + synchronized (this) { + fill++; + + item.next = pool; + pool = item; + } + } else{ + count--; + } + } + + public void releaseAll(T item) { + if (item == null) + return; + + if (fill > maxFill) + while (item != null) { + clearItem(item); + item = item.next; + count--; + } + + if (item == null) + return; + + synchronized (this) { + while (item != null) { + T next = item.next; + clearItem(item); + + item.next = pool; + pool = item; + fill++; + + item = next; + } + } + } + + // remove 'item' from 'list' and add back to pool + public T release(T list, T item) { + if (item == null) + return list; + + T ret = list; + + if (item == list) { + ret = item.next; + } else { + for (T prev = list, it = list.next; it != null; it = it.next) { + if (it == item) { + prev.next = it.next; + } + prev = it; + } + } + + clearItem(item); + + if (fill < maxFill) { + synchronized (this) { + fill++; + + item.next = pool; + pool = item; + } + } else{ + count--; + } + + return ret; + } + + public T get() { + if (pool == null){ + count++; + return createItem(); + } + + synchronized (this) { + fill--; + + T ret = pool; + pool = pool.next; + + ret.next = null; + return ret; + } + } +}