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);
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));
}
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<SymbolItem> {
public static SymbolItem get() {
synchronized (lock) {
if (pool == null)
return new SymbolItem();
public final static SyncPool<SymbolItem> pool = new SyncPool<SymbolItem>() {
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;
}

View File

@ -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;
}
}

View File

@ -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<TextItem> {
//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<TextItem> pool = new SyncPool<TextItem>(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;

View File

@ -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;
}
}

View File

@ -12,10 +12,14 @@
* 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;
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<TextureItem> {
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<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;
@ -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<Bitmap>(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;
}
}
}
}

View File

@ -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);

View File

@ -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<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 int used;
public VertexPoolItem next;
// must be multiple of
// 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 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 +

View File

@ -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<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 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

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;
}
}
}