pooled items now extend pool.Inlist and using generic pool.SyncPool

This commit is contained in:
Hannes Janetzek 2013-04-09 23:06:06 +02:00
parent 5f37f2f0de
commit ab56cc4b18
24 changed files with 767 additions and 680 deletions

View File

@ -167,7 +167,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
//Log.d(TAG, "Failed loading: " + tile); //Log.d(TAG, "Failed loading: " + tile);
mTile.layers.clear(); mTile.layers.clear();
mTile.layers = null; mTile.layers = null;
TextItem.release(mTile.labels); TextItem.pool.releaseAll(mTile.labels);
mTile.labels = null; mTile.labels = null;
// FIXME add STATE_FAILED? // FIXME add STATE_FAILED?
mTile.state = STATE_NONE; mTile.state = STATE_NONE;
@ -459,7 +459,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
float x = mWay.geom.points[0]; float x = mWay.geom.points[0];
float y = mWay.geom.points[1]; 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 @Override
@ -471,7 +471,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
for (int i = 0, n = mGeom.index[0]; i < n; i += 2) { for (int i = 0, n = mGeom.index[0]; i < n; i += 2) {
float x = mGeom.points[i]; float x = mGeom.points[i];
float y = mGeom.points[i + 1]; 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));
} }
} }

View File

@ -194,7 +194,7 @@ public final class WayDecorator {
y2 = prevY; y2 = prevY;
} }
TextItem n = TextItem.get(); TextItem n = TextItem.pool.get();
// link items together // link items together
if (t != null) { if (t != null) {

View File

@ -32,6 +32,7 @@ import javax.microedition.khronos.opengles.GL10;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.layer.Layers; import org.oscim.renderer.layer.Layers;
import org.oscim.renderer.layer.TextureItem;
import org.oscim.renderer.overlays.RenderOverlay; import org.oscim.renderer.overlays.RenderOverlay;
import org.oscim.theme.RenderTheme; import org.oscim.theme.RenderTheme;
import org.oscim.utils.GlUtils; import org.oscim.utils.GlUtils;
@ -646,7 +647,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
LineTexRenderer.init(); LineTexRenderer.init();
PolygonRenderer.init(); PolygonRenderer.init();
TextureRenderer.init(); TextureRenderer.init();
TextureObject.init(10); TextureItem.init(10);
mNewSurface = true; mNewSurface = true;
} }

View File

@ -18,6 +18,7 @@ package org.oscim.renderer;
import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.GLRenderer.Matrices;
import org.oscim.renderer.layer.Layer; import org.oscim.renderer.layer.Layer;
import org.oscim.renderer.layer.TextureLayer; import org.oscim.renderer.layer.TextureLayer;
import org.oscim.renderer.layer.TextureItem;
import org.oscim.utils.GlUtils; import org.oscim.utils.GlUtils;
import android.opengl.GLES20; import android.opengl.GLES20;
@ -74,7 +75,7 @@ public final class TextureRenderer {
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLRenderer.mQuadIndicesID); 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); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, to.id);
int maxVertices = GLRenderer.maxQuads * INDICES_PER_SPRITE; int maxVertices = GLRenderer.maxQuads * INDICES_PER_SPRITE;

View File

@ -27,7 +27,6 @@ import org.oscim.core.Tile;
import org.oscim.generator.JobTile; import org.oscim.generator.JobTile;
import org.oscim.generator.TileDistanceSort; import org.oscim.generator.TileDistanceSort;
import org.oscim.renderer.layer.TextItem; import org.oscim.renderer.layer.TextItem;
import org.oscim.renderer.layer.VertexPool;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
import org.oscim.view.MapView; import org.oscim.view.MapView;
import org.oscim.view.MapViewPosition; import org.oscim.view.MapViewPosition;
@ -112,11 +111,12 @@ public class TileManager {
// pass VBOs and VertexItems back to pools // pass VBOs and VertexItems back to pools
for (int i = 0; i < mTilesSize; i++) for (int i = 0; i < mTilesSize; i++)
clearTile(mTiles[i]); clearTile(mTiles[i]);
} else { }
//else {
// mInitialized is set when surface changed // mInitialized is set when surface changed
// and VBOs might be lost // and VBOs might be lost
VertexPool.init(); // VertexPool.init();
} //}
// clear cache index // clear cache index
QuadTree.init(); QuadTree.init();
@ -397,7 +397,7 @@ public class TileManager {
t.layers = null; t.layers = null;
} }
TextItem.release(t.labels); TextItem.pool.releaseAll(t.labels);
QuadTree.remove(t); QuadTree.remove(t);
t.state = STATE_NONE; t.state = STATE_NONE;

View File

@ -36,9 +36,9 @@ import android.util.Log;
public class ExtrusionLayer extends Layer { public class ExtrusionLayer extends Layer {
private final static String TAG = ExtrusionLayer.class.getName(); private final static String TAG = ExtrusionLayer.class.getName();
private static final float S = GLRenderer.COORD_SCALE; private static final float S = GLRenderer.COORD_SCALE;
private final VertexPoolItem mVertices; private final VertexItem mVertices;
private VertexPoolItem mCurVertices; private VertexItem mCurVertices;
private final VertexPoolItem mIndices[], mCurIndices[]; private final VertexItem mIndices[], mCurIndices[];
private LineClipper mClipper; private LineClipper mClipper;
// indices for: // indices for:
@ -65,12 +65,12 @@ public class ExtrusionLayer extends Layer {
this.level = level; this.level = level;
mGroundResolution = groundResolution; mGroundResolution = groundResolution;
mVertices = mCurVertices = VertexPool.get(); mVertices = mCurVertices = VertexItem.pool.get();
mIndices = new VertexPoolItem[4]; mIndices = new VertexItem[4];
mCurIndices = new VertexPoolItem[4]; mCurIndices = new VertexItem[4];
for (int i = 0; i < 4; i++) 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); mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE);
} }
@ -158,9 +158,9 @@ public class ExtrusionLayer extends Layer {
short first = (short) (startVertex + 1); short first = (short) (startVertex + 1);
for (int k = 0; k < len - 4; k += 2) { for (int k = 0; k < len - 4; k += 2) {
if (i == VertexPoolItem.SIZE) { if (i == VertexItem.SIZE) {
mCurIndices[IND_ROOF].used = VertexPoolItem.SIZE; mCurIndices[IND_ROOF].used = VertexItem.SIZE;
mCurIndices[IND_ROOF].next = VertexPool.get(); mCurIndices[IND_ROOF].next = VertexItem.pool.get();
mCurIndices[IND_ROOF] = mCurIndices[2].next; mCurIndices[IND_ROOF] = mCurIndices[2].next;
indices = mCurIndices[IND_ROOF].vertices; indices = mCurIndices[IND_ROOF].vertices;
i = 0; i = 0;
@ -194,7 +194,7 @@ public class ExtrusionLayer extends Layer {
if (used > 0) { if (used > 0) {
// get back to the last item added.. // get back to the last item added..
VertexPoolItem it = mIndices[IND_ROOF]; VertexItem it = mIndices[IND_ROOF];
while (it.next != null) while (it.next != null)
it = it.next; it = it.next;
mCurIndices[IND_ROOF] = it; mCurIndices[IND_ROOF] = it;
@ -247,9 +247,9 @@ public class ExtrusionLayer extends Layer {
uy = vy; uy = vy;
/* add bottom and top vertex for each point */ /* add bottom and top vertex for each point */
if (v == VertexPoolItem.SIZE) { if (v == VertexItem.SIZE) {
mCurVertices.used = VertexPoolItem.SIZE; mCurVertices.used = VertexItem.SIZE;
mCurVertices.next = VertexPool.get(); mCurVertices.next = VertexItem.pool.get();
mCurVertices = mCurVertices.next; mCurVertices = mCurVertices.next;
vertices = mCurVertices.vertices; vertices = mCurVertices.vertices;
v = 0; v = 0;
@ -329,8 +329,8 @@ public class ExtrusionLayer extends Layer {
// index id relative to mCurIndices item // index id relative to mCurIndices item
int ind = mCurIndices[even].used; int ind = mCurIndices[even].used;
if (ind == VertexPoolItem.SIZE) { if (ind == VertexItem.SIZE) {
mCurIndices[even].next = VertexPool.get(); mCurIndices[even].next = VertexItem.pool.get();
mCurIndices[even] = mCurIndices[even].next; mCurIndices[even] = mCurIndices[even].next;
indices = mCurIndices[even].vertices; indices = mCurIndices[even].vertices;
ind = 0; ind = 0;
@ -348,9 +348,9 @@ public class ExtrusionLayer extends Layer {
even = (even == 0 ? 1 : 0); even = (even == 0 ? 1 : 0);
/* add roof outline indices */ /* add roof outline indices */
VertexPoolItem it = mCurIndices[IND_OUTLINE]; VertexItem it = mCurIndices[IND_OUTLINE];
if (it.used == VertexPoolItem.SIZE) { if (it.used == VertexItem.SIZE) {
it.next = VertexPool.get(); it.next = VertexItem.pool.get();
it = mCurIndices[IND_OUTLINE] = it.next; it = mCurIndices[IND_OUTLINE] = it.next;
} }
it.vertices[it.used++] = s1; it.vertices[it.used++] = s1;
@ -377,7 +377,7 @@ public class ExtrusionLayer extends Layer {
sbuf.clear(); sbuf.clear();
mNumIndices = 0; mNumIndices = 0;
for (int i = 0; i < 4; i++) { 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); sbuf.put(vi.vertices, 0, vi.used);
mIndiceCnt[i] += vi.used; mIndiceCnt[i] += vi.used;
} }
@ -392,7 +392,7 @@ public class ExtrusionLayer extends Layer {
// upload vertices // upload vertices
sbuf.clear(); 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.put(vi.vertices, 0, vi.used);
sbuf.flip(); sbuf.flip();
@ -404,10 +404,10 @@ public class ExtrusionLayer extends Layer {
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
for (VertexPoolItem i : mIndices) for (VertexItem i : mIndices)
VertexPool.release(i); VertexItem.pool.releaseAll(i);
VertexPool.release(mVertices); VertexItem.pool.releaseAll(mVertices);
mClipper = null; mClipper = null;
@ -423,9 +423,9 @@ public class ExtrusionLayer extends Layer {
mVertexBO = null; mVertexBO = null;
//GLES20.glDeleteBuffers(2, mVboIds, 0); //GLES20.glDeleteBuffers(2, mVboIds, 0);
} else { } else {
VertexPool.release(mVertices); VertexItem.pool.releaseAll(mVertices);
for (VertexPoolItem i : mIndices) for (VertexItem i : mIndices)
VertexPool.release(i); VertexItem.pool.releaseAll(i);
} }
} }
@ -433,7 +433,7 @@ public class ExtrusionLayer extends Layer {
private static ShortBuffer sBuf; private static ShortBuffer sBuf;
public static synchronized int triangulate(float[] points, int ppos, int plen, short[] index, 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) { if (!initialized) {
// FIXME also cleanup on shutdown! // FIXME also cleanup on shutdown!
@ -454,12 +454,12 @@ public class ExtrusionLayer extends Layer {
for (int k = 0, cnt = 0; k < numIndices; k += cnt) { for (int k = 0, cnt = 0; k < numIndices; k += cnt) {
if (item.used == VertexPoolItem.SIZE) { if (item.used == VertexItem.SIZE) {
item.next = VertexPool.get(); item.next = VertexItem.pool.get();
item = item.next; item = item.next;
} }
cnt = VertexPoolItem.SIZE - item.used; cnt = VertexItem.SIZE - item.used;
if (k + cnt > numIndices) if (k + cnt > numIndices)
cnt = numIndices - k; cnt = numIndices - k;

View File

@ -45,8 +45,8 @@ public abstract class Layer {
// - offset in byte in VBO // - offset in byte in VBO
public int offset; public int offset;
VertexPoolItem pool; VertexItem vertexItems;
protected VertexPoolItem curItem; protected VertexItem curItem;
abstract protected void compile(ShortBuffer sbuf); abstract protected void compile(ShortBuffer sbuf);
abstract protected void clear(); abstract protected void clear();

View File

@ -179,21 +179,21 @@ public class Layers {
// optimization for Line- and PolygonLayer: // optimization for Line- and PolygonLayer:
// collect all pool items and add back in one go // collect all pool items and add back in one go
private static int addLayerItems(ShortBuffer sbuf, Layer l, byte type, int pos) { 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; int size = 0;
for (; l != null; l = l.next) { for (; l != null; l = l.next) {
if (l.type != type) if (l.type != type)
continue; 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){ if (it.next == null){
size += it.used; size += it.used;
sbuf.put(it.vertices, 0, it.used); sbuf.put(it.vertices, 0, it.used);
} }
else{ else{
size += VertexPoolItem.SIZE; size += VertexItem.SIZE;
sbuf.put(it.vertices, 0, VertexPoolItem.SIZE); sbuf.put(it.vertices, 0, VertexItem.SIZE);
} }
last = it; last = it;
} }
@ -205,13 +205,13 @@ public class Layers {
pos += l.verticesCnt; pos += l.verticesCnt;
last.next = items; last.next = items;
items = l.pool; items = l.vertexItems;
last = null; last = null;
l.pool = null; l.vertexItems = null;
l.curItem = null; l.curItem = null;
} }
VertexPool.release(items); VertexItem.pool.releaseAll(items);
return size; return size;
} }
@ -220,15 +220,15 @@ public class Layers {
// offset of layer data in vbo // offset of layer data in vbo
l.offset = sbuf.position() * SHORT_BYTES; 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) if (it.next == null)
sbuf.put(it.vertices, 0, it.used); sbuf.put(it.vertices, 0, it.used);
else else
sbuf.put(it.vertices, 0, VertexPoolItem.SIZE); sbuf.put(it.vertices, 0, VertexItem.SIZE);
} }
VertexPool.release(l.pool); VertexItem.pool.releaseAll(l.vertexItems);
l.pool = null; l.vertexItems = null;
} }
// cleanup only when layers are not used by tile or overlay anymore! // 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 // clear line and polygon layers directly
Layer l = baseLayers; Layer l = baseLayers;
while (l != null) { while (l != null) {
if (l.pool != null) { if (l.vertexItems != null) {
VertexPool.release(l.pool); VertexItem.pool.releaseAll(l.vertexItems);
l.pool = null; l.vertexItems = null;
l.curItem = null; l.curItem = null;
} }
l = l.next; l = l.next;

View File

@ -85,10 +85,10 @@ public final class LineLayer extends Layer {
else if (line.cap == Cap.SQUARE) else if (line.cap == Cap.SQUARE)
squared = true; squared = true;
if (pool == null) if (vertexItems == null)
curItem = pool = VertexPool.get(); curItem = vertexItems = VertexItem.pool.get();
VertexPoolItem si = curItem; VertexItem si = curItem;
short v[] = si.vertices; short v[] = si.vertices;
int opos = si.used; 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. // when the endpoint is outside the tile region omit round caps.
boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax); boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax);
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -193,8 +193,8 @@ public final class LineLayer extends Layer {
v[opos++] = dx; v[opos++] = dx;
v[opos++] = dy; v[opos++] = dy;
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -204,8 +204,8 @@ public final class LineLayer extends Layer {
v[opos++] = dx; v[opos++] = dx;
v[opos++] = dy; v[opos++] = dy;
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -218,8 +218,8 @@ public final class LineLayer extends Layer {
v[opos++] = (short) (2 | ddx & DIR_MASK); v[opos++] = (short) (2 | ddx & DIR_MASK);
v[opos++] = (short) (2 | ddy & DIR_MASK); v[opos++] = (short) (2 | ddy & DIR_MASK);
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -233,8 +233,8 @@ public final class LineLayer extends Layer {
v[opos++] = (short) (0 | ddx & DIR_MASK); v[opos++] = (short) (0 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK); v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -273,8 +273,8 @@ public final class LineLayer extends Layer {
v[opos++] = dx; v[opos++] = dx;
v[opos++] = dy; v[opos++] = dy;
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -284,8 +284,8 @@ public final class LineLayer extends Layer {
v[opos++] = dx; v[opos++] = dx;
v[opos++] = dy; v[opos++] = dy;
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -366,8 +366,8 @@ public final class LineLayer extends Layer {
ddx = -ddx; ddx = -ddx;
ddy = -ddy; ddy = -ddy;
} }
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -377,8 +377,8 @@ public final class LineLayer extends Layer {
v[opos++] = (short) (0 | ddx & DIR_MASK); v[opos++] = (short) (0 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK); v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -401,8 +401,8 @@ public final class LineLayer extends Layer {
outside = (x < tmin || x > tmax || y < tmin || y > tmax); outside = (x < tmin || x > tmax || y < tmin || y > tmax);
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si.next = VertexPool.get(); si.next = VertexItem.pool.get();
si = si.next; si = si.next;
opos = 0; opos = 0;
v = si.vertices; v = si.vertices;
@ -425,8 +425,8 @@ public final class LineLayer extends Layer {
v[opos++] = (short) (0 | ddx & DIR_MASK); v[opos++] = (short) (0 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK); v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -436,8 +436,8 @@ public final class LineLayer extends Layer {
v[opos++] = (short) (2 | -ddx & DIR_MASK); v[opos++] = (short) (2 | -ddx & DIR_MASK);
v[opos++] = (short) (1 | -ddy & DIR_MASK); v[opos++] = (short) (1 | -ddy & DIR_MASK);
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -454,8 +454,8 @@ public final class LineLayer extends Layer {
v[opos++] = dx; v[opos++] = dx;
v[opos++] = dy; v[opos++] = dy;
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -471,8 +471,8 @@ public final class LineLayer extends Layer {
v[opos++] = dx; v[opos++] = dx;
v[opos++] = dy; v[opos++] = dy;
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -502,8 +502,8 @@ public final class LineLayer extends Layer {
v[opos++] = (short) (0 | (flip ? -ddx : ddx) & DIR_MASK); v[opos++] = (short) (0 | (flip ? -ddx : ddx) & DIR_MASK);
v[opos++] = (short) (1 | (flip ? -ddy : ddy) & DIR_MASK); v[opos++] = (short) (1 | (flip ? -ddy : ddy) & DIR_MASK);
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }
@ -519,8 +519,8 @@ public final class LineLayer extends Layer {
v[opos++] = dx; v[opos++] = dx;
v[opos++] = dy; v[opos++] = dy;
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }

View File

@ -89,8 +89,8 @@ public final class LineTexLayer extends Layer {
public void addLine(float[] points, short[] index) { public void addLine(float[] points, short[] index) {
if (pool == null) { if (vertexItems == null) {
curItem = pool = VertexPool.get(); curItem = vertexItems = VertexItem.pool.get();
// HACK add one vertex offset when compiling // HACK add one vertex offset when compiling
// buffer otherwise one cant use the full // buffer otherwise one cant use the full
@ -103,7 +103,7 @@ public final class LineTexLayer extends Layer {
verticesCnt = 1; verticesCnt = 1;
} }
VertexPoolItem si = curItem; VertexItem si = curItem;
short v[] = si.vertices; short v[] = si.vertices;
int opos = si.used; int opos = si.used;
@ -169,8 +169,8 @@ public final class LineTexLayer extends Layer {
short dx = (short) (ux * DIR_SCALE); short dx = (short) (ux * DIR_SCALE);
short dy = (short) (uy * DIR_SCALE); short dy = (short) (uy * DIR_SCALE);
if (opos == VertexPoolItem.SIZE) { if (opos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
opos = 0; opos = 0;
} }

View File

@ -28,14 +28,14 @@ public final class PolygonLayer extends Layer {
PolygonLayer(int layer) { PolygonLayer(int layer) {
this.level = layer; this.level = layer;
this.type = Layer.POLYGON; this.type = Layer.POLYGON;
curItem = VertexPool.get(); curItem = VertexItem.pool.get();
pool = curItem; vertexItems = curItem;
} }
public void addPolygon(float[] points, short[] index) { public void addPolygon(float[] points, short[] index) {
short center = (short) ((Tile.SIZE >> 1) * S); short center = (short) ((Tile.SIZE >> 1) * S);
VertexPoolItem si = curItem; VertexItem si = curItem;
short[] v = si.vertices; short[] v = si.vertices;
int outPos = si.used; int outPos = si.used;
@ -54,8 +54,8 @@ public final class PolygonLayer extends Layer {
int inPos = pos; int inPos = pos;
if (outPos == VertexPoolItem.SIZE) { if (outPos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
outPos = 0; outPos = 0;
} }
@ -64,8 +64,8 @@ public final class PolygonLayer extends Layer {
v[outPos++] = center; v[outPos++] = center;
for (int j = 0; j < length; j += 2) { for (int j = 0; j < length; j += 2) {
if (outPos == VertexPoolItem.SIZE) { if (outPos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
outPos = 0; outPos = 0;
} }
@ -73,8 +73,8 @@ public final class PolygonLayer extends Layer {
v[outPos++] = (short) (points[inPos++] * S); v[outPos++] = (short) (points[inPos++] * S);
} }
if (outPos == VertexPoolItem.SIZE) { if (outPos == VertexItem.SIZE) {
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
v = si.vertices; v = si.vertices;
outPos = 0; outPos = 0;
} }

View File

@ -14,47 +14,28 @@
*/ */
package org.oscim.renderer.layer; package org.oscim.renderer.layer;
import org.oscim.utils.pool.Inlist;
import org.oscim.utils.pool.SyncPool;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
public class SymbolItem { public class SymbolItem extends Inlist<SymbolItem> {
private static Object lock = new Object();
private static SymbolItem pool;
public static SymbolItem get() { public final static SyncPool<SymbolItem> pool = new SyncPool<SymbolItem>() {
synchronized (lock) {
if (pool == null)
return new SymbolItem();
SymbolItem ti = pool; @Override
pool = pool.next; protected SymbolItem createItem() {
return new SymbolItem();
ti.next = null;
return ti;
} }
}
public static void release(SymbolItem ti) { @Override
if (ti == null) protected void clearItem(SymbolItem it) {
return; // drop references
it.drawable = null;
synchronized (lock) { it.bitmap = null;
while (ti != null) {
SymbolItem next = ti.next;
ti.drawable = null;
ti.bitmap = null;
ti.next = pool;
pool = ti;
ti = next;
}
} }
} };
SymbolItem next;
public Bitmap bitmap; public Bitmap bitmap;
public Drawable drawable; public Drawable drawable;
@ -65,5 +46,4 @@ public class SymbolItem {
// center, top, bottom, left, right, top-left... // center, top, bottom, left, right, top-left...
// byte placement; // byte placement;
} }

View File

@ -14,7 +14,6 @@
*/ */
package org.oscim.renderer.layer; package org.oscim.renderer.layer;
import org.oscim.renderer.TextureObject;
import org.oscim.renderer.TextureRenderer; import org.oscim.renderer.TextureRenderer;
import android.graphics.Canvas; import android.graphics.Canvas;
@ -27,8 +26,8 @@ import android.util.Log;
public final class SymbolLayer extends TextureLayer { public final class SymbolLayer extends TextureLayer {
private final static String TAG = SymbolLayer.class.getSimpleName(); private final static String TAG = SymbolLayer.class.getSimpleName();
private final static int TEXTURE_WIDTH = TextureObject.TEXTURE_WIDTH; private final static int TEXTURE_WIDTH = TextureItem.TEXTURE_WIDTH;
private final static int TEXTURE_HEIGHT = TextureObject.TEXTURE_HEIGHT; private final static int TEXTURE_HEIGHT = TextureItem.TEXTURE_HEIGHT;
private final static float SCALE = 8.0f; private final static float SCALE = 8.0f;
SymbolItem symbols; SymbolItem symbols;
@ -63,7 +62,7 @@ public final class SymbolLayer extends TextureLayer {
verticesCnt += 4; verticesCnt += 4;
SymbolItem item = SymbolItem.get(); SymbolItem item = SymbolItem.pool.get();
item.drawable = drawable; item.drawable = drawable;
item.x = x; item.x = x;
item.y = y; item.y = y;
@ -93,9 +92,9 @@ public final class SymbolLayer extends TextureLayer {
short offsetIndices = 0; short offsetIndices = 0;
short curIndices = 0; short curIndices = 0;
curItem = VertexPool.get(); curItem = VertexItem.pool.get();
pool = curItem; vertexItems = curItem;
VertexPoolItem si = curItem; VertexItem si = curItem;
int pos = si.used; int pos = si.used;
short buf[] = si.vertices; short buf[] = si.vertices;
@ -104,7 +103,7 @@ public final class SymbolLayer extends TextureLayer {
float x = 0; float x = 0;
float y = 0; float y = 0;
TextureObject to = TextureObject.get(); TextureItem to = TextureItem.pool.get();
textures = to; textures = to;
mCanvas.setBitmap(to.bitmap); mCanvas.setBitmap(to.bitmap);
@ -140,7 +139,7 @@ public final class SymbolLayer extends TextureLayer {
offsetIndices = numIndices; offsetIndices = numIndices;
curIndices = 0; curIndices = 0;
to.next = TextureObject.get(); to.next = TextureItem.pool.get();
to = to.next; to = to.next;
mCanvas.setBitmap(to.bitmap); 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 tx = (short) ((int) (SCALE * it2.x) & LBIT_MASK | (it2.billboard ? 1 : 0));
short ty = (short) (SCALE * it2.y); short ty = (short) (SCALE * it2.y);
if (pos == VertexPoolItem.SIZE) { if (pos == VertexItem.SIZE) {
si.used = VertexPoolItem.SIZE; si.used = VertexItem.SIZE;
si = si.next = VertexPool.get(); si = si.next = VertexItem.pool.get();
buf = si.vertices; buf = si.vertices;
pos = 0; pos = 0;
} }
@ -249,12 +248,12 @@ public final class SymbolLayer extends TextureLayer {
@Override @Override
protected void clear() { protected void clear() {
TextureObject.release(textures); TextureItem.pool.releaseAll(textures);
SymbolItem.release(symbols); SymbolItem.pool.releaseAll(symbols);
VertexPool.release(pool); VertexItem.pool.releaseAll(vertexItems);
textures = null; textures = null;
symbols = null; symbols = null;
pool = null; vertexItems = null;
verticesCnt = 0; verticesCnt = 0;
} }
} }

View File

@ -15,117 +15,45 @@
package org.oscim.renderer.layer; package org.oscim.renderer.layer;
import org.oscim.theme.renderinstruction.Text; 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 extends Inlist<TextItem> {
//private final static String TAG = TextItem.class.getName();
public class TextItem {
private final static String TAG = TextItem.class.getName();
private final static int MAX_POOL = 250; private final static int MAX_POOL = 250;
private static Object lock = new Object(); public final static SyncPool<TextItem> pool = new SyncPool<TextItem>(MAX_POOL) {
private static TextItem pool;
private static int count = 0;
private static int inPool = 0;
public static TextItem get() { @Override
synchronized (lock) { protected TextItem createItem() {
if (pool == null) { return new TextItem();
count++;
return new TextItem();
}
inPool--;
TextItem ti = pool;
pool = pool.next;
ti.next = null;
//ti.active = 0;
return ti;
} }
}
@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) { public static TextItem copy(TextItem orig) {
synchronized (lock) {
TextItem ti = pool;
if (ti == null) { TextItem ti = pool.get();
count++;
ti = new TextItem();
} else {
inPool--;
pool = pool.next;
}
ti.next = null; ti.next = null;
ti.x = orig.x; ti.x = orig.x;
ti.y = orig.y; ti.y = orig.y;
ti.x1 = orig.x1; ti.x1 = orig.x1;
ti.y1 = orig.y1; ti.y1 = orig.y1;
ti.x2 = orig.x2; ti.x2 = orig.x2;
ti.y2 = orig.y2; ti.y2 = orig.y2;
return ti; 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);
} }
public TextItem set(float x, float y, String string, Text text) { public TextItem set(float x, float y, String string, Text text) {
@ -137,33 +65,6 @@ public class TextItem {
return this; 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) { public static boolean bboxOverlaps(TextItem it1, TextItem it2, float add) {
if (it1.y1 < it1.y2) { if (it1.y1 < it1.y2) {
if (it2.y1 < it2.y2) if (it2.y1 < it2.y2)
@ -194,7 +95,7 @@ public class TextItem {
} }
// link to next node // link to next node
public TextItem next; //public TextItem next;
// center // center
public float x, y; public float x, y;

View File

@ -14,18 +14,16 @@
*/ */
package org.oscim.renderer.layer; package org.oscim.renderer.layer;
import org.oscim.renderer.TextureObject;
import org.oscim.renderer.TextureRenderer; import org.oscim.renderer.TextureRenderer;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.util.Log;
public final class TextLayer extends TextureLayer { public final class TextLayer extends TextureLayer {
//private static String TAG = TextureLayer.class.getName(); //private static String TAG = TextureLayer.class.getName();
private final static int TEXTURE_WIDTH = TextureObject.TEXTURE_WIDTH; private final static int TEXTURE_WIDTH = TextureItem.TEXTURE_WIDTH;
private final static int TEXTURE_HEIGHT = TextureObject.TEXTURE_HEIGHT; private final static int TEXTURE_HEIGHT = TextureItem.TEXTURE_HEIGHT;
private final static float SCALE = 8.0f; private final static float SCALE = 8.0f;
private final static int LBIT_MASK = 0xfffffffe; private final static int LBIT_MASK = 0xfffffffe;
@ -45,25 +43,6 @@ public final class TextLayer extends TextureLayer {
fixed = true; 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) { public void addText(TextItem item) {
TextItem it = labels; TextItem it = labels;
@ -97,13 +76,11 @@ public final class TextLayer extends TextureLayer {
@Override @Override
public boolean prepare() { public boolean prepare() {
if (TextureRenderer.debug)
Log.d("...", "prepare");
short numIndices = 0; short numIndices = 0;
short offsetIndices = 0; short offsetIndices = 0;
VertexPoolItem vi = pool = VertexPool.get(); VertexItem vi = vertexItems = VertexItem.pool.get();
int pos = vi.used; // 0 int pos = vi.used; // 0
short buf[] = vi.vertices; short buf[] = vi.vertices;
@ -114,7 +91,7 @@ public final class TextLayer extends TextureLayer {
float y = 0; float y = 0;
float yy; float yy;
TextureObject to = TextureObject.get(); TextureItem to = TextureItem.pool.get();
textures = to; textures = to;
mCanvas.setBitmap(to.bitmap); mCanvas.setBitmap(to.bitmap);
@ -136,7 +113,7 @@ public final class TextLayer extends TextureLayer {
to.vertices = (short) (numIndices - offsetIndices); to.vertices = (short) (numIndices - offsetIndices);
offsetIndices = numIndices; offsetIndices = numIndices;
to.next = TextureObject.get(); to.next = TextureItem.pool.get();
to = to.next; to = to.next;
mCanvas.setBitmap(to.bitmap); mCanvas.setBitmap(to.bitmap);
@ -227,9 +204,9 @@ public final class TextLayer extends TextureLayer {
short tx = (short) (tmp | (it.text.caption ? 1 : 0)); short tx = (short) (tmp | (it.text.caption ? 1 : 0));
short ty = (short) (SCALE * it.y); short ty = (short) (SCALE * it.y);
if (pos == VertexPoolItem.SIZE) { if (pos == VertexItem.SIZE) {
vi.used = VertexPoolItem.SIZE; vi.used = VertexItem.SIZE;
vi = vi.next = VertexPool.get(); vi = vi.next = VertexItem.pool.get();
buf = vi.vertices; buf = vi.vertices;
pos = 0; pos = 0;
} }
@ -288,12 +265,12 @@ public final class TextLayer extends TextureLayer {
@Override @Override
protected void clear() { protected void clear() {
TextureObject.release(textures); TextureItem.pool.releaseAll(textures);
TextItem.release(labels); TextItem.pool.releaseAll(labels);
VertexPool.release(pool); VertexItem.pool.releaseAll(vertexItems);
textures = null; textures = null;
labels = null; labels = null;
pool = null; vertexItems = null;
verticesCnt = 0; verticesCnt = 0;
} }
} }

View File

@ -12,10 +12,14 @@
* You should have received a copy of the GNU Lesser General Public License along with * You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.oscim.renderer; package org.oscim.renderer.layer;
import java.util.ArrayList; 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.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import android.opengl.GLES20; import android.opengl.GLES20;
@ -25,11 +29,64 @@ import android.util.Log;
/** /**
* @author Hannes Janetzek * @author Hannes Janetzek
*/ */
public class TextureObject { public class TextureItem extends Inlist<TextureItem> {
private final static String TAG = TextureObject.class.getName(); private final static String TAG = TextureItem.class.getName();
private static TextureObject pool; // texture ID
private static int poolCount; 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<TextureItem> pool = new SyncPool<TextureItem>() {
@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<Bitmap> mBitmaps; private static ArrayList<Bitmap> mBitmaps;
@ -39,62 +96,12 @@ public class TextureObject {
private static int mBitmapFormat; private static int mBitmapFormat;
private static int mBitmapType; 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. * This function may only be used in GLRenderer Thread.
* *
* @param to the TextureObjet to compile and upload * @param to the TextureObjet to compile and upload
*/ */
public static synchronized void uploadTexture(TextureObject to) { public static void uploadTexture(TextureItem to) {
// FIXME what needs synchronized ?
if (TextureRenderer.debug) if (TextureRenderer.debug)
Log.d(TAG, "upload texture " + to.id); Log.d(TAG, "upload texture " + to.id);
@ -104,6 +111,7 @@ public class TextureObject {
GLES20.glGenTextures(1, textureIds, 0); GLES20.glGenTextures(1, textureIds, 0);
to.id = textureIds[0]; to.id = textureIds[0];
initTexture(to.id); initTexture(to.id);
if (TextureRenderer.debug) if (TextureRenderer.debug)
Log.d(TAG, "new texture " + to.id); Log.d(TAG, "new texture " + to.id);
} }
@ -111,11 +119,10 @@ public class TextureObject {
uploadTexture(to, to.bitmap, mBitmapFormat, mBitmapType, uploadTexture(to, to.bitmap, mBitmapFormat, mBitmapType,
TEXTURE_WIDTH, TEXTURE_HEIGHT); TEXTURE_WIDTH, TEXTURE_HEIGHT);
mBitmaps.add(to.bitmap); TextureItem.releaseBitmap(to);
to.bitmap = null;
} }
public static void uploadTexture(TextureObject to, Bitmap bitmap, public static void uploadTexture(TextureItem to, Bitmap bitmap,
int format, int type, int w, int h) { int format, int type, int w, int h) {
if (to == null) { if (to == null) {
@ -145,20 +152,8 @@ public class TextureObject {
GLES20.GL_CLAMP_TO_EDGE); // Set V Wrapping GLES20.GL_CLAMP_TO_EDGE); // Set V Wrapping
} }
static void init(int num) { public static void init(int num) {
pool = null; pool.init(num);
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;
}
mBitmaps = new ArrayList<Bitmap>(10); mBitmaps = new ArrayList<Bitmap>(10);
@ -174,39 +169,32 @@ public class TextureObject {
mBitmapType = GLUtils.getType(mBitmaps.get(0)); mBitmapType = GLUtils.getType(mBitmaps.get(0));
} }
private static Bitmap getBitmap() { static Bitmap getBitmap() {
int size = mBitmaps.size(); synchronized (mBitmaps) {
if (size == 0) {
Bitmap bitmap = Bitmap.createBitmap(
TEXTURE_WIDTH, TEXTURE_HEIGHT,
Bitmap.Config.ARGB_8888);
if (TextureRenderer.debug) int size = mBitmaps.size();
Log.d(TAG, "alloc bitmap: " + if (size == 0) {
android.os.Debug.getNativeHeapAllocatedSize() / (1024 * 1024)); 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);
} }
// ----------------------- static void releaseBitmap(TextureItem it) {
public TextureObject next; synchronized (mBitmaps) {
// texture ID if (it.bitmap != null) {
int id; mBitmaps.add(it.bitmap);
it.bitmap = null;
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;
} }
} }

View File

@ -16,14 +16,13 @@ package org.oscim.renderer.layer;
import java.nio.ShortBuffer; import java.nio.ShortBuffer;
import org.oscim.renderer.TextureObject;
/** /**
* @author Hannes Janetzek * @author Hannes Janetzek
*/ */
public abstract class TextureLayer extends Layer { public abstract class TextureLayer extends Layer {
// holds textures and offset in vbo // holds textures and offset in vbo
public TextureObject textures; public TextureItem textures;
// scale mode // scale mode
public boolean fixed; public boolean fixed;
@ -35,8 +34,8 @@ public abstract class TextureLayer extends Layer {
@Override @Override
protected void compile(ShortBuffer sbuf) { protected void compile(ShortBuffer sbuf) {
for (TextureObject to = textures; to != null; to = to.next) for (TextureItem to = textures; to != null; to = to.next)
TextureObject.uploadTexture(to); TextureItem.uploadTexture(to);
// add vertices to vbo // add vertices to vbo
Layers.addPoolItems(this, sbuf); Layers.addPoolItems(this, sbuf);

View File

@ -14,11 +14,29 @@
*/ */
package org.oscim.renderer.layer; 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<VertexItem> {
private static final int MAX_POOL = 500;
public final static SyncPool<VertexItem> pool = new SyncPool<VertexItem>(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 final short[] vertices = new short[SIZE];
public int used; public int used;
public VertexPoolItem next;
// must be multiple of // must be multiple of
// 4 (LineLayer/PolygonLayer), // 4 (LineLayer/PolygonLayer),

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}
}
}

View File

@ -77,7 +77,7 @@ public class GridOverlay extends BasicOverlay {
for (int i = -2; i < 2; i++) { for (int i = -2; i < 2; i++) {
for (int j = -2; j < 2; j++) { 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); (x + j) + " / " + (y + i) + " / " + z, mText);
// TextItem ti = new TextItem(size * j + size / 2, size * i + // TextItem ti = new TextItem(size * j + size / 2, size * i +

View File

@ -47,6 +47,7 @@ import org.oscim.theme.renderinstruction.Line;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
import org.oscim.utils.OBB2D; import org.oscim.utils.OBB2D;
import org.oscim.utils.PausableThread; import org.oscim.utils.PausableThread;
import org.oscim.utils.pool.Pool;
import org.oscim.view.MapView; import org.oscim.view.MapView;
import org.oscim.view.MapViewPosition; import org.oscim.view.MapViewPosition;
@ -57,6 +58,8 @@ import android.os.SystemClock;
public class TextOverlay extends BasicOverlay { public class TextOverlay extends BasicOverlay {
//private final static String TAG = TextOverlay.class.getName(); //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 final MapViewPosition mMapViewPosition;
private TileSet mTileSet; private TileSet mTileSet;
@ -70,8 +73,27 @@ public class TextOverlay extends BasicOverlay {
private TextLayer mNextLayer; private TextLayer mNextLayer;
// local pool, avoids synchronized TextItem.get()/release() // local pool, avoids synchronized TextItem.get()/release()
private Label mPool;
class LabelPool extends Pool<TextItem>{
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 mPrevLabels;
private Label mLabels;
private final float[] mTmpCoords = new float[8]; private final float[] mTmpCoords = new float[8];
@ -89,9 +111,38 @@ public class TextOverlay extends BasicOverlay {
MapTile tile; MapTile tile;
public byte origin; //public byte origin;
public int active; public int active;
public OBB2D bbox; 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 { // class Link {
@ -112,7 +163,7 @@ public class TextOverlay extends BasicOverlay {
@Override @Override
protected void doWork() { protected void doWork() {
SystemClock.sleep(500); SystemClock.sleep(250);
if (!mRun) if (!mRun)
return; return;
@ -153,22 +204,47 @@ public class TextOverlay extends BasicOverlay {
mRelabelCnt = 0; mRelabelCnt = 0;
} }
private Label removeLabel(TextLayer tl, Label l) { // remove Label l from mLabels and return l.next
Label tmp = l; private Label removeLabel(Label l) {
l = (Label) l.next; Label ret = (Label)l.next;
mPool.release(mLabels, l);
TextItem.release(tmp.item); return ret;
tl.removeText(tmp);
tmp.next = mPool;
mPool = tmp;
return l;
} }
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 // check bounding box
if (!TextItem.bboxOverlaps(ti, lp, 150)) { if (!TextItem.bboxOverlaps(ti, lp, 150)) {
@ -187,7 +263,7 @@ public class TextOverlay extends BasicOverlay {
// keep the label with longer segment // keep the label with longer segment
if (lp.length < ti.length) { if (lp.length < ti.length) {
lp = removeLabel(tl, lp); lp = removeLabel(lp);
continue; continue;
} }
@ -207,7 +283,7 @@ public class TextOverlay extends BasicOverlay {
if (!lp.text.caption if (!lp.text.caption
&& (lp.text.priority > ti.text.priority || lp.length < ti.length)) { && (lp.text.priority > ti.text.priority || lp.length < ti.length)) {
lp = removeLabel(tl, lp); lp = removeLabel(lp);
continue; continue;
} }
@ -247,38 +323,29 @@ public class TextOverlay extends BasicOverlay {
private Layers mDebugLayer; private Layers mDebugLayer;
private final static float[] mDebugPoints = new float[4]; 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() { private Label getLabel() {
Label l; Label l = (Label)mPool.get();
if (mPool == null) if (l == null)
l = new Label(); l = new Label();
else {
l = mPool;
mPool = (Label) mPool.next;
l.next = null;
}
l.active = Integer.MAX_VALUE; l.active = Integer.MAX_VALUE;
return l; 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() { boolean updateLabels() {
// could this happen?
if (mTmpLayer == null) if (mTmpLayer == null)
return false; return false;
@ -288,12 +355,6 @@ public class TextOverlay extends BasicOverlay {
if (mTileSet.cnt == 0) if (mTileSet.cnt == 0)
return false; return false;
// reuse text layer
TextLayer tl = mTmpLayer;
mTmpLayer = null;
//mNewLabels = null;
Layers dbg = null; Layers dbg = null;
if (mMapView.getDebugSettings().debugLabels) if (mMapView.getDebugSettings().debugLabels)
dbg = new Layers(); dbg = new Layers();
@ -304,31 +365,24 @@ public class TextOverlay extends BasicOverlay {
synchronized (mMapViewPosition) { synchronized (mMapViewPosition) {
mMapViewPosition.getMapPosition(pos); mMapViewPosition.getMapPosition(pos);
mMapViewPosition.getMapViewProjection(coords); mMapViewPosition.getMapViewProjection(coords);
//mMapViewPosition.getMatrix(null, null, mMVP);
} }
int mw = (mMapView.getWidth() + Tile.SIZE) / 2; int mw = (mMapView.getWidth() + Tile.SIZE) / 2;
int mh = (mMapView.getHeight() + Tile.SIZE) / 2; int mh = (mMapView.getHeight() + Tile.SIZE) / 2;
mSquareRadius = mw * mw + mh * mh; 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; MapTile[] tiles = mTileSet.tiles;
//int zoom = tiles[0].zoomLevel; int zoom = tiles[0].zoomLevel;
int diff = tiles[0].zoomLevel - pos.zoomLevel; // scale of tiles zoom-level relative to current position
float div = FastMath.pow(diff); double scale = pos.scale / (1 << zoom);
double scale = pos.getZoomScale() * div;
//float scale = (float)(pos.absScale / (1 << zoom) );
double angle = Math.toRadians(pos.angle); double angle = Math.toRadians(pos.angle);
float cos = (float) Math.cos(angle); float cos = (float) Math.cos(angle);
float sin = (float) Math.sin(angle); float sin = (float) Math.sin(angle);
int maxx = Tile.SIZE << (pos.zoomLevel - 1); int maxx = Tile.SIZE << (zoom - 1);
Label l = null; Label l = null;
@ -337,72 +391,69 @@ public class TextOverlay extends BasicOverlay {
mRelabelCnt++; mRelabelCnt++;
double tileX = (pos.x * (Tile.SIZE << pos.zoomLevel)); double tileX = (pos.x * (Tile.SIZE << zoom));
double tileY = (pos.y * (Tile.SIZE << pos.zoomLevel)); double tileY = (pos.y * (Tile.SIZE << zoom));
for (l = mPrevLabels; l != null;) { for (l = mPrevLabels; l != null;) {
if (l.text.caption) {
// transform screen coordinates to tile coordinates l = mPool.releaseAndGetNext(l);
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);
continue; continue;
} }
float dx = (float) (l.tile.tileX * Tile.SIZE - tileX * s); int diff = l.tile.zoomLevel - zoom;
float dy = (float) (l.tile.tileY * Tile.SIZE - tileY * s); if (diff > 1 || diff < -1) {
l = mPool.releaseAndGetNext(l);
continue;
}
// flip around date-line float div = FastMath.pow(diff);
if (dx > maxx) float sscale = (float) (pos.scale / (1 << l.tile.zoomLevel));
dx = dx - maxx * 2;
else if (dx < -maxx) if (l.width > l.length * sscale) {
dx = dx + maxx * 2; 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); l.move(l.item, dx, dy, sscale);
if (!l.text.caption) { // set line endpoints relative to view to be able to
// set line endpoints relative to view to be able to // check intersections with label from other tiles
// check intersections with label from other tiles float w = (l.item.x2 - l.item.x1) / 2f;
float width = (l.item.x2 - l.item.x1) / 2f; float h = (l.item.y2 - l.item.y1) / 2f;
float height = (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); if (!wayIsVisible(l)) {
l.x1 = (l.x - width); l = mPool.releaseAndGetNext(l);
l.y2 = (l.y + height); continue;
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;
}
} }
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 */ /* add way labels */
@ -414,12 +465,7 @@ public class TextOverlay extends BasicOverlay {
float dx = (float) (t.tileX * Tile.SIZE - tileX); float dx = (float) (t.tileX * Tile.SIZE - tileX);
float dy = (float) (t.tileY * Tile.SIZE - tileY); float dy = (float) (t.tileY * Tile.SIZE - tileY);
dx = flipLatitude(dx, maxx);
// flip around date-line
if (dx > maxx)
dx = dx - maxx * 2;
else if (dx < -maxx)
dx = dx + maxx * 2;
for (TextItem ti = t.labels; ti != null; ti = ti.next) { 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 // set line endpoints relative to view to be able to
// check intersections with label from other tiles // check intersections with label from other tiles
float width = (ti.x2 - ti.x1) / 2f; float w = (ti.x2 - ti.x1) / 2f;
float height = (ti.y2 - ti.y1) / 2f; float h = (ti.y2 - ti.y1) / 2f;
l.bbox = null; l.bbox = null;
l.x1 = (l.x - width); l.x1 = l.x - w;
l.y1 = (l.y - height); l.y1 = l.y - h;
l.x2 = (l.x + width); l.x2 = l.x + w;
l.y2 = (l.y + height); l.y2 = l.y + h;
if (!wayIsVisible(l)) if (!wayIsVisible(l))
continue; continue;
@ -453,18 +499,22 @@ public class TextOverlay extends BasicOverlay {
byte overlaps = -1; byte overlaps = -1;
if (l.bbox == null) 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 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) if (dbg == null || ti.width < ti.length * scale)
overlaps = checkOverlap(tl, l); overlaps = checkOverlap(l);
if (dbg != null) if (dbg != null)
addDebugBox(dbg, l, ti, overlaps, false, (float) scale); addDebugBox(dbg, l, ti, overlaps, false, (float) scale);
if (overlaps == 0) { if (overlaps == 0) {
tl.addText(l); addLabel(l);
l.item = TextItem.copy(ti); l.item = TextItem.copy(ti);
l.tile = t; l.tile = t;
l.active = mRelabelCnt; l.active = mRelabelCnt;
@ -481,12 +531,7 @@ public class TextOverlay extends BasicOverlay {
float dx = (float) (t.tileX * Tile.SIZE - tileX); float dx = (float) (t.tileX * Tile.SIZE - tileX);
float dy = (float) (t.tileY * Tile.SIZE - tileY); float dy = (float) (t.tileY * Tile.SIZE - tileY);
dx = flipLatitude(dx, maxx);
// flip around date-line
if (dx > maxx)
dx = dx - maxx * 2;
else if (dx < -maxx)
dx = dx + maxx * 2;
for (TextItem ti = t.labels; ti != null; ti = ti.next) { for (TextItem ti = t.labels; ti != null; ti = ti.next) {
if (!ti.text.caption) if (!ti.text.caption)
@ -506,21 +551,20 @@ public class TextOverlay extends BasicOverlay {
if (l.bbox == null) if (l.bbox == null)
l.bbox = new OBB2D(); l.bbox = new OBB2D();
l.bbox.setNormalized(l.x, l.y, cos, -sin, l.width + 6, l.bbox.setNormalized(l.x, l.y, cos, -sin,
l.text.fontHeight + 6); l.width + MIN_CAPTION_DIST,
l.text.fontHeight + MIN_CAPTION_DIST);
boolean overlaps = false; 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)) { if (l.bbox.overlaps(lp.bbox)) {
//Log.d(TAG, "overlap > " + ti2.string + " " + lp.string);
//if (TextItem.bboxOverlaps(ti2, lp, 4)) {
overlaps = true; overlaps = true;
break; break;
} }
} }
if (!overlaps) { if (!overlaps) {
tl.addText(l); addLabel(l);
l.item = TextItem.copy(ti); l.item = TextItem.copy(ti);
l.tile = t; l.tile = t;
l.active = mRelabelCnt; 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) if (ti.text.caption)
continue; continue;
@ -546,17 +589,20 @@ public class TextOverlay extends BasicOverlay {
} }
} }
// keep temporarily used Label // temporarily used Label
if (l != null) { mPool.release(l);
l.next = mPool;
mPool = l;
}
//reuse text layer
TextLayer tl = mTmpLayer;
mTmpLayer = null;
tl.labels = mLabels;
// draw text to bitmaps and create vertices // draw text to bitmaps and create vertices
tl.prepare(); tl.prepare();
// after 'prepare' TextLayer does not need TextItems any longer // after 'prepare' TextLayer does not need TextItems
mPrevLabels = (Label) tl.labels; mPrevLabels = mLabels;
mLabels = null;
tl.labels = null; tl.labels = null;
// remove tile locks // remove tile locks

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package org.oscim.utils.pool;
public class Inlist<T extends Inlist<T>> {
private final static boolean debug = false;
public T next;
static <T extends Inlist<T>> int size(Inlist<T> list) {
int count = 0;
for (Inlist<T> l = list; l != null; l = l.next)
count++;
return count;
}
public static <T extends Inlist<T>> Inlist<T> remove(Inlist<T> list, Inlist<T> item) {
if (item == list) {
return item.next;
}
for (Inlist<T> prev = list, it = list.next; it != null; it = it.next) {
if (it == item) {
prev.next = it.next;
return list;
}
prev = it;
}
return list;
}
static <T extends Inlist<T>> Inlist<T> prepend(T list, T item) {
item.next = list;
return item;
}
static <T extends Inlist<T>> Inlist<T> append(T list, T item) {
if (debug) {
if (item.next != null) {
// warn
item.next = null;
}
}
if (list == null)
return item;
Inlist<T> it = list;
while (it.next != null)
it = it.next;
it.next = item;
return list;
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package org.oscim.utils.pool;
public class Pool<T extends Inlist<T>> {
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;
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package org.oscim.utils.pool;
public abstract class SyncPool<T extends Inlist<T>> {
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;
}
}
}