refactor: TileManager/MapTile
- remove tile from TileManager cache when canceled - changed MapTile.STATE_* to MapTile.State.*
This commit is contained in:
parent
77c933b7d8
commit
a53568f100
@ -16,6 +16,8 @@
|
||||
*/
|
||||
package org.oscim.layers.tile;
|
||||
|
||||
import static org.oscim.tiling.MapTile.State.CANCEL;
|
||||
|
||||
import java.util.concurrent.CancellationException;
|
||||
|
||||
import org.oscim.backend.canvas.Bitmap;
|
||||
@ -135,7 +137,7 @@ public class BitmapTileLayer extends TileLayer<TileLoader> {
|
||||
|
||||
@Override
|
||||
public void setTileImage(Bitmap bitmap) {
|
||||
if (isCanceled() || mTile.state(MapTile.STATE_CANCEL))
|
||||
if (isCanceled() || mTile.state(CANCEL))
|
||||
throw new CancellationException();
|
||||
|
||||
BitmapLayer l = new BitmapLayer(false);
|
||||
|
@ -16,6 +16,8 @@
|
||||
*/
|
||||
package org.oscim.layers.tile.vector;
|
||||
|
||||
import static org.oscim.tiling.MapTile.State.CANCEL;
|
||||
|
||||
import java.util.concurrent.CancellationException;
|
||||
|
||||
import org.oscim.backend.canvas.Bitmap;
|
||||
@ -211,7 +213,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
||||
public void process(MapElement element) {
|
||||
clearState();
|
||||
|
||||
if (isCanceled() || mTile.state(MapTile.STATE_CANCEL))
|
||||
if (isCanceled() || mTile.state(CANCEL))
|
||||
throw new CancellationException();
|
||||
|
||||
mElement = element;
|
||||
|
@ -1,5 +1,8 @@
|
||||
package org.oscim.layers.tile.vector.labeling;
|
||||
|
||||
import static org.oscim.tiling.MapTile.State.NEW_DATA;
|
||||
import static org.oscim.tiling.MapTile.State.READY;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.map.Map;
|
||||
@ -381,7 +384,7 @@ public class LabelPlacement {
|
||||
for (int i = 0, n = mTileSet.cnt; i < n; i++) {
|
||||
MapTile t = tiles[i];
|
||||
synchronized (t) {
|
||||
if (!t.state(MapTile.STATE_READY))
|
||||
if (!t.state(READY | NEW_DATA))
|
||||
continue;
|
||||
|
||||
float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
||||
@ -396,7 +399,7 @@ public class LabelPlacement {
|
||||
for (int i = 0, n = mTileSet.cnt; i < n; i++) {
|
||||
MapTile t = tiles[i];
|
||||
synchronized (t) {
|
||||
if (!t.state(MapTile.STATE_READY))
|
||||
if (!t.state(READY | NEW_DATA))
|
||||
continue;
|
||||
|
||||
float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
||||
@ -437,7 +440,7 @@ public class LabelPlacement {
|
||||
for (int i = 0, n = mTileSet.cnt; i < n; i++) {
|
||||
MapTile t = tiles[i];
|
||||
synchronized (t) {
|
||||
if (!t.state(MapTile.STATE_READY))
|
||||
if (!t.state(READY | NEW_DATA))
|
||||
continue;
|
||||
|
||||
float dx = (float) (t.tileX * Tile.SIZE - tileX);
|
||||
|
@ -16,6 +16,9 @@
|
||||
*/
|
||||
package org.oscim.renderer;
|
||||
|
||||
import static org.oscim.tiling.MapTile.State.NEW_DATA;
|
||||
import static org.oscim.tiling.MapTile.State.READY;
|
||||
|
||||
import org.oscim.backend.GL20;
|
||||
import org.oscim.backend.canvas.Color;
|
||||
import org.oscim.core.MapPosition;
|
||||
@ -168,10 +171,10 @@ public class ExtrusionRenderer extends LayerRenderer {
|
||||
}
|
||||
|
||||
private static ExtrusionLayer getLayer(MapTile t) {
|
||||
if (t.layers != null && t.layers.getExtrusionLayers() != null
|
||||
&& t.state(MapTile.STATE_READY))
|
||||
return (ExtrusionLayer) t.layers.getExtrusionLayers();
|
||||
return null;
|
||||
if (t.layers == null || !t.state(READY | NEW_DATA))
|
||||
return null;
|
||||
|
||||
return t.layers.getExtrusionLayers();
|
||||
}
|
||||
|
||||
private final boolean debug = false;
|
||||
|
@ -17,8 +17,8 @@
|
||||
*/
|
||||
package org.oscim.tiling;
|
||||
|
||||
import static org.oscim.tiling.MapTile.STATE_LOADING;
|
||||
import static org.oscim.tiling.MapTile.STATE_NONE;
|
||||
import static org.oscim.tiling.MapTile.State.LOADING;
|
||||
import static org.oscim.tiling.MapTile.State.NONE;
|
||||
|
||||
/**
|
||||
* A JobQueue keeps the list of pending jobs for a MapView and prioritizes them.
|
||||
@ -34,7 +34,7 @@ public class JobQueue {
|
||||
*/
|
||||
public synchronized void setJobs(MapTile[] tiles) {
|
||||
for (MapTile t : tiles)
|
||||
t.state = STATE_LOADING;
|
||||
t.state = LOADING;
|
||||
|
||||
mJobs = tiles;
|
||||
mCurrentJob = 0;
|
||||
@ -51,7 +51,7 @@ public class JobQueue {
|
||||
MapTile[] tiles = mJobs;
|
||||
|
||||
for (int i = mCurrentJob, n = mJobs.length; i < n; i++) {
|
||||
tiles[i].state = STATE_NONE;
|
||||
tiles[i].state = NONE;
|
||||
tiles[i] = null;
|
||||
}
|
||||
mCurrentJob = 0;
|
||||
|
@ -25,7 +25,8 @@ import org.oscim.utils.quadtree.Node;
|
||||
|
||||
/**
|
||||
* Extends Tile class to hold state and data for concurrent use in
|
||||
* TileManager (Main Thread), TileLoader (Worker Threads) and
|
||||
* TileManager (Main Thread),
|
||||
* TileLoader (Worker Thread) and
|
||||
* TileRenderer (GL Thread).
|
||||
*/
|
||||
public class MapTile extends Tile {
|
||||
@ -34,37 +35,53 @@ public class MapTile extends Tile {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* To be removed: used by GWT backend
|
||||
* */
|
||||
/** To be removed: used by GWT backend */
|
||||
public TileLoader loader;
|
||||
|
||||
public final static byte STATE_NONE = 0;
|
||||
public static final class State {
|
||||
public final static byte NONE = 0;
|
||||
|
||||
/**
|
||||
* STATE_LOADING means the tile is about to be loaded / loading.
|
||||
* Tile belongs to TileLoader thread.
|
||||
*/
|
||||
public final static byte STATE_LOADING = 1 << 0;
|
||||
/**
|
||||
* STATE_LOADING means the tile is about to be loaded / loading.
|
||||
* Tile belongs to TileLoader thread.
|
||||
*/
|
||||
public final static byte LOADING = 1 << 0;
|
||||
|
||||
/**
|
||||
* STATE_NEW_DATA: tile data is prepared for rendering.
|
||||
* While 'locked' it belongs to GL Thread.
|
||||
*/
|
||||
public final static byte STATE_NEW_DATA = 1 << 1;
|
||||
/**
|
||||
* STATE_NEW_DATA: tile data is prepared for rendering.
|
||||
* While 'locked' it belongs to GL Thread.
|
||||
*/
|
||||
public final static byte NEW_DATA = 1 << 1;
|
||||
|
||||
/**
|
||||
* STATE_READY: tile data is uploaded to GL.
|
||||
* While 'locked' it belongs to GL Thread.
|
||||
*/
|
||||
public final static byte STATE_READY = 1 << 2;
|
||||
/**
|
||||
* STATE_READY: tile data is uploaded to GL.
|
||||
* While 'locked' it belongs to GL Thread.
|
||||
*/
|
||||
public final static byte READY = 1 << 2;
|
||||
|
||||
/**
|
||||
* TBD
|
||||
*/
|
||||
public final static byte STATE_ERROR = 1 << 3;
|
||||
/**
|
||||
* STATE_CANCEL: tile is removed from TileManager,
|
||||
* but may still be processed by TileLoader.
|
||||
*/
|
||||
public final static byte CANCEL = 1 << 3;
|
||||
}
|
||||
|
||||
public final static byte STATE_CANCEL = 1 << 4;
|
||||
public MapTile(TileNode node, int tileX, int tileY, byte zoomLevel) {
|
||||
super(tileX, tileY, zoomLevel);
|
||||
this.x = (double) tileX / (1 << zoomLevel);
|
||||
this.y = (double) tileY / (1 << zoomLevel);
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
byte state;
|
||||
|
||||
public boolean state(int testState) {
|
||||
return (state & testState) != 0;
|
||||
}
|
||||
|
||||
public byte getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* absolute tile coordinates: tileX,Y / Math.pow(2, zoomLevel)
|
||||
@ -73,7 +90,7 @@ public class MapTile extends Tile {
|
||||
public final double y;
|
||||
|
||||
/**
|
||||
* distance from map center
|
||||
* current distance from map center
|
||||
*/
|
||||
public float distance;
|
||||
|
||||
@ -111,17 +128,6 @@ public class MapTile extends Tile {
|
||||
public final static int PROXY_GRAMPA = 1 << 5;
|
||||
public final static int PROXY_HOLDER = 1 << 6;
|
||||
|
||||
/** STATE_* */
|
||||
byte state;
|
||||
|
||||
public boolean state(byte testState) {
|
||||
return state == testState;
|
||||
}
|
||||
|
||||
public byte getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/** keep track which tiles are locked as proxy for this tile */
|
||||
byte proxies;
|
||||
|
||||
@ -131,17 +137,12 @@ public class MapTile extends Tile {
|
||||
/** up to 255 Threads may lock a tile */
|
||||
private byte locked;
|
||||
|
||||
// only used GLRenderer when this tile sits in for another tile.
|
||||
// e.g. x:-1,y:0,z:1 for x:1,y:0
|
||||
/**
|
||||
* only used GLRenderer when this tile sits in for another tile.
|
||||
* e.g. x:-1,y:0,z:1 for x:1,y:0
|
||||
*/
|
||||
MapTile holder;
|
||||
|
||||
public MapTile(TileNode node, int tileX, int tileY, byte zoomLevel) {
|
||||
super(tileX, tileY, zoomLevel);
|
||||
this.x = (double) tileX / (1 << zoomLevel);
|
||||
this.y = (double) tileY / (1 << zoomLevel);
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true when tile might be referenced by render thread.
|
||||
*/
|
||||
@ -159,15 +160,15 @@ public class MapTile extends Tile {
|
||||
if (locked++ > 0)
|
||||
return;
|
||||
|
||||
// lock all tiles that could serve as proxy
|
||||
/* lock all tiles that could serve as proxy */
|
||||
MapTile p = node.parent.item;
|
||||
if (p != null && (p.state != 0)) {
|
||||
if (p != null && (p.state != State.NONE)) {
|
||||
proxies |= PROXY_PARENT;
|
||||
p.refs++;
|
||||
}
|
||||
|
||||
p = node.parent.parent.item;
|
||||
if (p != null && (p.state != 0)) {
|
||||
if (p != null && (p.state != State.NONE)) {
|
||||
proxies |= PROXY_GRAMPA;
|
||||
p.refs++;
|
||||
}
|
||||
@ -206,7 +207,7 @@ public class MapTile extends Tile {
|
||||
* for rendering
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return state > STATE_NONE && state < STATE_ERROR;
|
||||
return state > State.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -218,9 +219,7 @@ public class MapTile extends Tile {
|
||||
}
|
||||
|
||||
/**
|
||||
* CAUTION: This function should only be called by {@link TileManager} when
|
||||
* tile is removed from cache or from {@link TileLoader} when
|
||||
* tile has failed to get loaded.
|
||||
* CAUTION: This function may only be called by {@link TileManager}
|
||||
*/
|
||||
protected void clear() {
|
||||
if (layers != null) {
|
||||
@ -231,6 +230,7 @@ public class MapTile extends Tile {
|
||||
TextItem.pool.releaseAll(labels.clear());
|
||||
SymbolItem.pool.releaseAll(symbols.clear());
|
||||
|
||||
state = STATE_NONE;
|
||||
// still needed?
|
||||
state = State.NONE;
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,11 @@
|
||||
|
||||
package org.oscim.tiling;
|
||||
|
||||
import static org.oscim.tiling.MapTile.STATE_CANCEL;
|
||||
import static org.oscim.tiling.MapTile.STATE_LOADING;
|
||||
import static org.oscim.tiling.MapTile.STATE_NEW_DATA;
|
||||
import static org.oscim.tiling.MapTile.State.CANCEL;
|
||||
import static org.oscim.tiling.MapTile.State.LOADING;
|
||||
import static org.oscim.tiling.MapTile.State.NEW_DATA;
|
||||
import static org.oscim.tiling.MapTile.State.NONE;
|
||||
import static org.oscim.tiling.MapTile.State.READY;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -40,6 +42,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TileManager {
|
||||
static final Logger log = LoggerFactory.getLogger(TileManager.class);
|
||||
static final boolean dbg = false;
|
||||
|
||||
public final static Event TILE_LOADED = new Event();
|
||||
public final static Event TILE_REMOVED = new Event();
|
||||
@ -104,12 +107,11 @@ public class TileManager {
|
||||
@Override
|
||||
public void removeItem(MapTile t) {
|
||||
if (t.node == null) {
|
||||
log.debug("BUG already removed " + t);
|
||||
log.error("already removed {}", t);
|
||||
return;
|
||||
}
|
||||
|
||||
super.remove(t.node);
|
||||
|
||||
t.node.item = null;
|
||||
}
|
||||
|
||||
@ -150,8 +152,12 @@ public class TileManager {
|
||||
|
||||
public void init() {
|
||||
/* pass VBOs and VertexItems back to pools */
|
||||
for (int i = 0; i < mTilesSize; i++)
|
||||
clearTile(mTiles[i]);
|
||||
for (int i = 0; i < mTilesSize; i++) {
|
||||
if (mTiles[i] == null)
|
||||
continue;
|
||||
mTiles[i].state = NONE;
|
||||
removeFromCache(mTiles[i]);
|
||||
}
|
||||
|
||||
/* clear references to cached MapTiles */
|
||||
Arrays.fill(mTiles, null);
|
||||
@ -259,7 +265,7 @@ public class TileManager {
|
||||
|
||||
MapTile[] jobs = new MapTile[mJobs.size()];
|
||||
jobs = mJobs.toArray(jobs);
|
||||
updateTileDistances(jobs, jobs.length, pos);
|
||||
updateDistances(jobs, jobs.length, pos);
|
||||
|
||||
/* sets tiles to state == LOADING */
|
||||
jobQueue.setJobs(jobs);
|
||||
@ -269,7 +275,8 @@ public class TileManager {
|
||||
if (mCacheReduce < mCacheLimit / 2) {
|
||||
if (BufferObject.isMaxFill()) {
|
||||
mCacheReduce += 10;
|
||||
log.debug("reduce tile cache " + (mCacheLimit - mCacheReduce));
|
||||
if (dbg)
|
||||
log.debug("reduce cache {}", (mCacheLimit - mCacheReduce));
|
||||
} else
|
||||
mCacheReduce = 0;
|
||||
}
|
||||
@ -322,7 +329,6 @@ public class TileManager {
|
||||
tileSet.setTiles(mCurrentTiles);
|
||||
tileSet.serial = mUpdateSerial;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -348,24 +354,18 @@ public class TileManager {
|
||||
|
||||
if ((zoomLevel > 2) && (mZoomTable == null)) {
|
||||
/* prefetch parent */
|
||||
boolean add = false;
|
||||
|
||||
MapTile p = tile.node.parent.item;
|
||||
|
||||
if (p == null) {
|
||||
p = mIndex.create(x >> 1, y >> 1, zoomLevel - 1);
|
||||
|
||||
addToCache(p);
|
||||
add = true;
|
||||
}
|
||||
|
||||
if (add || !p.isActive()) {
|
||||
// hack to not add tile twice
|
||||
p.state = STATE_LOADING;
|
||||
// hack to not add tile twice to queue
|
||||
p.state = LOADING;
|
||||
mJobs.add(p);
|
||||
} else if (!p.isActive()) {
|
||||
p.state = LOADING;
|
||||
mJobs.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
return tile;
|
||||
}
|
||||
|
||||
@ -391,28 +391,151 @@ public class TileManager {
|
||||
mTilesCount++;
|
||||
}
|
||||
|
||||
private void clearTile(MapTile t) {
|
||||
if (t == null)
|
||||
return;
|
||||
private void removeFromCache(MapTile t) {
|
||||
|
||||
if (t.state != STATE_CANCEL && t.state != STATE_LOADING)
|
||||
if (t.state == NEW_DATA || t.state == READY)
|
||||
events.tell(TILE_REMOVED, t);
|
||||
|
||||
synchronized (t) {
|
||||
// still belongs to TileLoader thread
|
||||
if (t.state != STATE_LOADING)
|
||||
/* still belongs to TileLoader thread, defer clearing to
|
||||
* jobCompleted() */
|
||||
if (t.state != CANCEL)
|
||||
t.clear();
|
||||
|
||||
t.state = STATE_CANCEL;
|
||||
// needed?
|
||||
t.state = CANCEL;
|
||||
|
||||
mIndex.removeItem(t);
|
||||
}
|
||||
|
||||
mTilesCount--;
|
||||
}
|
||||
|
||||
private static void updateTileDistances(MapTile[] tiles, int size, MapPosition pos) {
|
||||
// TODO there is probably a better quad-tree distance function
|
||||
private void limitCache(MapPosition pos, int remove) {
|
||||
MapTile[] tiles = mTiles;
|
||||
int size = mTilesSize;
|
||||
|
||||
/* count tiles that have new data */
|
||||
mTilesForUpload = 0;
|
||||
int newTileCnt = 0;
|
||||
|
||||
/* remove tiles that were never loaded */
|
||||
for (int i = 0; i < size; i++) {
|
||||
MapTile t = tiles[i];
|
||||
if (t == null)
|
||||
continue;
|
||||
|
||||
if (t.state == NEW_DATA)
|
||||
newTileCnt++;
|
||||
|
||||
/* make sure tile cannot be used by GL or MapWorker Thread */
|
||||
if ((t.state != 0) || t.isLocked()) {
|
||||
continue;
|
||||
}
|
||||
removeFromCache(t);
|
||||
tiles[i] = null;
|
||||
remove--;
|
||||
}
|
||||
|
||||
if (remove < CACHE_CLEAR_THRESHOLD && newTileCnt < MAX_TILES_IN_QUEUE)
|
||||
return;
|
||||
|
||||
updateDistances(tiles, size, pos);
|
||||
TileDistanceSort.sort(tiles, 0, size);
|
||||
|
||||
/* sorting also repacks the 'sparse' filled array
|
||||
* so end of mTiles is at mTilesCount now */
|
||||
size = mTilesSize = mTilesCount;
|
||||
|
||||
// log.debug("remove:" + remove + " new:" + newTileCnt);
|
||||
// log.debug("cur: " + mapPosition);
|
||||
|
||||
for (int i = size - 1; i >= 0 && remove > 0; i--) {
|
||||
MapTile t = tiles[i];
|
||||
if (t.isLocked()) {
|
||||
/* dont remove tile used by TileRenderer, or somewhere else
|
||||
* try again in next run. */
|
||||
if (dbg)
|
||||
log.debug("{} locked (state={}, d={})", t, t.state, t.distance);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if (t.state == LOADING) {
|
||||
/* NOTE: when set loading to false the tile could be
|
||||
* added to load queue again while still processed in
|
||||
* VectorTileLoader */
|
||||
t.state = CANCEL;
|
||||
if (dbg)
|
||||
log.debug("{} canceled (d={})", t, t.distance);
|
||||
}
|
||||
|
||||
if (t.state == NEW_DATA) {
|
||||
/* clear unused tile */
|
||||
if (dbg)
|
||||
log.debug("{} unused (d=({})", t, t.distance);
|
||||
newTileCnt--;
|
||||
}
|
||||
|
||||
removeFromCache(t);
|
||||
tiles[i] = null;
|
||||
remove--;
|
||||
}
|
||||
|
||||
remove = (newTileCnt - MAX_TILES_IN_QUEUE) + 10;
|
||||
//int r = remove;
|
||||
for (int i = size - 1; i >= 0 && remove > 0; i--) {
|
||||
MapTile t = tiles[i];
|
||||
if (t != null && t.state == NEW_DATA) {
|
||||
if (!t.isLocked()) {
|
||||
newTileCnt--;
|
||||
|
||||
removeFromCache(t);
|
||||
tiles[i] = null;
|
||||
remove--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mTilesForUpload += newTileCnt;
|
||||
//log.debug("cleanup load queue {} / {} - {}", mTilesForUpload, r, remove);
|
||||
if (dbg)
|
||||
log.debug("cleanup: {} {}", mTilesCount, mTilesForUpload);
|
||||
}
|
||||
|
||||
/**
|
||||
* called from MapWorker Thread when tile is loaded by MapTileLoader
|
||||
*
|
||||
* @param tile
|
||||
* Tile ready for upload in TileRenderLayer
|
||||
* @return caller does not care
|
||||
*/
|
||||
public void jobCompleted(final MapTile tile, final boolean success) {
|
||||
mMap.post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!success || tile.state == CANCEL) {
|
||||
tile.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
tile.state = NEW_DATA;
|
||||
events.tell(TILE_LOADED, tile);
|
||||
|
||||
mTilesForUpload += 1;
|
||||
|
||||
/* locked means the tile is visible or referenced by
|
||||
* a tile that might be visible. */
|
||||
if (tile.isLocked())
|
||||
mMap.render();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static void updateDistances(MapTile[] tiles, int size, MapPosition pos) {
|
||||
/* TODO there is probably a better quad-tree distance function */
|
||||
int zoom = 20;
|
||||
long x = (long) (pos.x * (1 << zoom));
|
||||
long y = (long) (pos.y * (1 << zoom));
|
||||
@ -446,128 +569,6 @@ public class TileManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void limitCache(MapPosition pos, int remove) {
|
||||
MapTile[] tiles = mTiles;
|
||||
int size = mTilesSize;
|
||||
|
||||
// count tiles that have new data
|
||||
mTilesForUpload = 0;
|
||||
int newTileCnt = 0;
|
||||
|
||||
// remove tiles that were never loaded
|
||||
for (int i = 0; i < size; i++) {
|
||||
MapTile t = tiles[i];
|
||||
if (t == null)
|
||||
continue;
|
||||
|
||||
if (t.state == STATE_NEW_DATA)
|
||||
newTileCnt++;
|
||||
|
||||
// make sure tile cannot be used by GL or MapWorker Thread
|
||||
if ((t.state != 0) || t.isLocked()) {
|
||||
continue;
|
||||
}
|
||||
clearTile(t);
|
||||
tiles[i] = null;
|
||||
remove--;
|
||||
}
|
||||
|
||||
if (remove > 10 || newTileCnt > MAX_TILES_IN_QUEUE) {
|
||||
updateTileDistances(tiles, size, pos);
|
||||
|
||||
TileDistanceSort.sort(tiles, 0, size);
|
||||
|
||||
// sorting also repacks the 'sparse' filled array
|
||||
// so end of mTiles is at mTilesCount now
|
||||
size = mTilesSize = mTilesCount;
|
||||
|
||||
// log.debug("remove:" + remove + " new:" + newTileCnt);
|
||||
// log.debug("cur: " + mapPosition);
|
||||
|
||||
for (int i = size - 1; i >= 0 && remove > 0; i--) {
|
||||
MapTile t = tiles[i];
|
||||
if (t.isLocked()) {
|
||||
// dont remove tile used by GLRenderer, or somewhere else
|
||||
// try again in next run.
|
||||
//log.debug("locked " + t
|
||||
// + " " + t.distance
|
||||
// + " " + (t.state == STATE_NEW_DATA)
|
||||
// + " " + (t.state == STATE_LOADING)
|
||||
// + " " + pos.zoomLevel);
|
||||
} else if (t.state == STATE_LOADING) {
|
||||
// NOTE: when set loading to false the tile could be
|
||||
// added to load queue again while still processed in
|
||||
// MapTileLoader => need tile.cancel flag.
|
||||
// t.isLoading = false;
|
||||
log.debug("cancel loading " + t
|
||||
+ " " + t.distance);
|
||||
} else {
|
||||
// clear unused tile
|
||||
|
||||
if (t.state == STATE_NEW_DATA) {
|
||||
// log.debug("limitCache: clear unused " + t
|
||||
// + " " + t.distance);
|
||||
newTileCnt--;
|
||||
}
|
||||
|
||||
remove--;
|
||||
clearTile(t);
|
||||
tiles[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
remove = (newTileCnt - MAX_TILES_IN_QUEUE) + 10;
|
||||
// int r = remove;
|
||||
for (int i = size - 1; i >= 0 && remove > 0; i--) {
|
||||
MapTile t = tiles[i];
|
||||
if (t != null && t.state == STATE_NEW_DATA) {
|
||||
if (!t.isLocked()) {
|
||||
clearTile(t);
|
||||
tiles[i] = null;
|
||||
remove--;
|
||||
newTileCnt--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mTilesForUpload += newTileCnt;
|
||||
// log.debug("cleanup load queue " + tilesForUpload + "/" + r +
|
||||
// " - " + remove);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* called from MapWorker Thread when tile is loaded by MapTileLoader
|
||||
*
|
||||
* @param tile
|
||||
* Tile ready for upload in TileRenderLayer
|
||||
* @return caller does not care
|
||||
*/
|
||||
public void jobCompleted(final MapTile tile, final boolean success) {
|
||||
mMap.post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!success || tile.state == STATE_CANCEL) {
|
||||
tile.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
tile.state = STATE_NEW_DATA;
|
||||
|
||||
events.tell(TILE_LOADED, tile);
|
||||
|
||||
mTilesForUpload += 1;
|
||||
|
||||
/* locked means the tile is visible or referenced by
|
||||
* a tile that might be visible. */
|
||||
if (tile.isLocked())
|
||||
mMap.render();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private final ScanBox mScanBox = new ScanBox() {
|
||||
|
||||
@Override
|
||||
@ -613,4 +614,8 @@ public class TileManager {
|
||||
mNewTiles.cnt = cnt;
|
||||
}
|
||||
};
|
||||
|
||||
public MapTile getTile(int tileX, int tileY, byte zoomLevel) {
|
||||
return mIndex.getTile(tileX, tileY, zoomLevel);
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,8 @@ import static org.oscim.renderer.elements.RenderElement.LINE;
|
||||
import static org.oscim.renderer.elements.RenderElement.MESH;
|
||||
import static org.oscim.renderer.elements.RenderElement.POLYGON;
|
||||
import static org.oscim.renderer.elements.RenderElement.TEXLINE;
|
||||
import static org.oscim.tiling.MapTile.STATE_NEW_DATA;
|
||||
import static org.oscim.tiling.MapTile.STATE_READY;
|
||||
import static org.oscim.tiling.MapTile.State.NEW_DATA;
|
||||
import static org.oscim.tiling.MapTile.State.READY;
|
||||
|
||||
import org.oscim.backend.GL20;
|
||||
import org.oscim.backend.canvas.Color;
|
||||
@ -143,7 +143,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
MapTile t = tiles[i];
|
||||
if (t.isVisible && t.state != STATE_READY) {
|
||||
if (t.isVisible && t.state != READY) {
|
||||
mClipMode = 2;
|
||||
break;
|
||||
}
|
||||
@ -152,7 +152,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
/* draw visible tiles */
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
MapTile t = tiles[i];
|
||||
if (t.isVisible && t.state == STATE_READY)
|
||||
if (t.isVisible && t.state == READY)
|
||||
drawTile(t, pos);
|
||||
|
||||
}
|
||||
@ -173,7 +173,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
MapTile t = tiles[i];
|
||||
if (t.isVisible
|
||||
&& (t.state != STATE_READY)
|
||||
&& (t.state != READY)
|
||||
&& (t.holder == null)) {
|
||||
drawProxyTile(t, pos, true, preferParent);
|
||||
}
|
||||
@ -183,7 +183,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
MapTile t = tiles[i];
|
||||
if (t.isVisible
|
||||
&& (t.state != STATE_READY)
|
||||
&& (t.state != READY)
|
||||
&& (t.holder == null))
|
||||
drawProxyTile(t, pos, false, false);
|
||||
}
|
||||
@ -218,17 +218,17 @@ public class TileRenderer extends LayerRenderer {
|
||||
if (!tile.isVisible)
|
||||
continue;
|
||||
|
||||
if (tile.state == STATE_READY)
|
||||
if (tile.state == READY)
|
||||
continue;
|
||||
|
||||
if (tile.state == STATE_NEW_DATA) {
|
||||
if (tile.state == NEW_DATA) {
|
||||
uploadCnt += uploadTileData(tile);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tile.holder != null) {
|
||||
/* load tile that is referenced by this holder */
|
||||
if (tile.holder.state == STATE_NEW_DATA)
|
||||
if (tile.holder.state == NEW_DATA)
|
||||
uploadCnt += uploadTileData(tile.holder);
|
||||
|
||||
tile.state = tile.holder.state;
|
||||
@ -238,7 +238,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
/* check near relatives than can serve as proxy */
|
||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||
MapTile t = tile.node.parent.item;
|
||||
if (t.state == STATE_NEW_DATA)
|
||||
if (t.state == NEW_DATA)
|
||||
uploadCnt += uploadTileData(t);
|
||||
|
||||
/* dont load child proxies */
|
||||
@ -250,7 +250,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
continue;
|
||||
|
||||
MapTile t = tile.node.child(i);
|
||||
if (t != null && t.state == STATE_NEW_DATA)
|
||||
if (t != null && t.state == NEW_DATA)
|
||||
uploadCnt += uploadTileData(t);
|
||||
}
|
||||
}
|
||||
@ -258,7 +258,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
}
|
||||
|
||||
private static int uploadTileData(MapTile tile) {
|
||||
tile.state = STATE_READY;
|
||||
tile.state = READY;
|
||||
|
||||
/* tile might contain extrusion or label layers */
|
||||
if (tile.layers == null)
|
||||
@ -338,7 +338,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
tileSet.cnt = 0;
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
MapTile t = newTiles[i];
|
||||
if (t.isVisible && t.state == STATE_READY) {
|
||||
if (t.isVisible && t.state == READY) {
|
||||
t.lock();
|
||||
tileSet.tiles[tileSet.cnt++] = t;
|
||||
}
|
||||
@ -424,15 +424,15 @@ public class TileRenderer extends LayerRenderer {
|
||||
if (ci == null)
|
||||
continue;
|
||||
|
||||
if (ci.state == MapTile.STATE_READY || ci.fadeTime > 0)
|
||||
if (ci.state == READY || ci.fadeTime > 0)
|
||||
maxFade = Math.min(maxFade, ci.fadeTime);
|
||||
}
|
||||
MapTile p = t.node.parent();
|
||||
if (p != null && (p.state == MapTile.STATE_READY || p.fadeTime > 0)) {
|
||||
if (p != null && (p.state == READY || p.fadeTime > 0)) {
|
||||
maxFade = Math.min(maxFade, p.fadeTime);
|
||||
|
||||
p = p.node.parent();
|
||||
if (p != null && (p.state == MapTile.STATE_READY || p.fadeTime > 0))
|
||||
if (p != null && (p.state == READY || p.fadeTime > 0))
|
||||
maxFade = Math.min(maxFade, p.fadeTime);
|
||||
}
|
||||
|
||||
@ -544,7 +544,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
|
||||
MapTile c = tile.node.child(i);
|
||||
|
||||
if (c.state == STATE_READY) {
|
||||
if (c.state == READY) {
|
||||
drawTile(c, pos);
|
||||
drawn++;
|
||||
}
|
||||
@ -567,7 +567,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
/* draw parent proxy */
|
||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||
proxy = r.parent.item;
|
||||
if (proxy.state == STATE_READY) {
|
||||
if (proxy.state == READY) {
|
||||
//log.debug("1. draw parent " + proxy);
|
||||
drawTile(proxy, pos);
|
||||
}
|
||||
@ -576,12 +576,12 @@ public class TileRenderer extends LayerRenderer {
|
||||
/* check if parent was already drawn */
|
||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||
proxy = r.parent.item;
|
||||
if (proxy.state == STATE_READY)
|
||||
if (proxy.state == READY)
|
||||
return;
|
||||
}
|
||||
|
||||
proxy = r.parent.parent.item;
|
||||
if (proxy.state == STATE_READY)
|
||||
if (proxy.state == READY)
|
||||
drawTile(proxy, pos);
|
||||
}
|
||||
} else {
|
||||
@ -589,7 +589,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
if (parent) {
|
||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||
proxy = r.parent.item;
|
||||
if (proxy != null && proxy.state == STATE_READY) {
|
||||
if (proxy != null && proxy.state == READY) {
|
||||
//log.debug("2. draw parent " + proxy);
|
||||
drawTile(proxy, pos);
|
||||
return;
|
||||
@ -602,7 +602,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
/* check if parent was already drawn */
|
||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||
proxy = r.parent.item;
|
||||
if (proxy.state == STATE_READY)
|
||||
if (proxy.state == READY)
|
||||
return;
|
||||
}
|
||||
/* this will do nothing, just to check */
|
||||
@ -610,7 +610,7 @@ public class TileRenderer extends LayerRenderer {
|
||||
return;
|
||||
|
||||
proxy = r.parent.parent.item;
|
||||
if (proxy.state == STATE_READY)
|
||||
if (proxy.state == READY)
|
||||
drawTile(proxy, pos);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user