- handle limiting of unused loaded tiles in limitCache
- remove unused tiles based on distance to map center
This commit is contained in:
parent
10381ae4ea
commit
7df1ceeff1
@ -255,6 +255,8 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
}
|
||||
|
||||
private static void uploadTileData(MapTile tile) {
|
||||
TileManager.tilesForUpload--;
|
||||
|
||||
if (tile.layers == null) {
|
||||
BufferObject.release(tile.vbo);
|
||||
tile.vbo = null;
|
||||
|
@ -18,7 +18,6 @@ package org.oscim.renderer;
|
||||
import static org.oscim.generator.JobTile.STATE_LOADING;
|
||||
import static org.oscim.generator.JobTile.STATE_NEW_DATA;
|
||||
import static org.oscim.generator.JobTile.STATE_NONE;
|
||||
import static org.oscim.generator.JobTile.STATE_READY;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -37,13 +36,17 @@ import android.util.Log;
|
||||
/**
|
||||
* @author Hannes Janetzek
|
||||
* @TODO
|
||||
* - prefetching to cache file
|
||||
* - this class should probably not be in 'renderer' -> tilemap?
|
||||
* - make it general for reuse in tile-overlays
|
||||
*/
|
||||
public class TileManager {
|
||||
static final String TAG = TileManager.class.getSimpleName();
|
||||
|
||||
private static final int MAX_TILES_IN_QUEUE = 40;
|
||||
// TODO this should depend on the number of
|
||||
// tiles that could be displayed
|
||||
private static final int MAX_TILES_IN_QUEUE = 50;
|
||||
|
||||
private static final int CACHE_THRESHOLD = 30;
|
||||
|
||||
private final MapView mMapView;
|
||||
@ -63,9 +66,6 @@ public class TileManager {
|
||||
// new jobs for MapWorkers
|
||||
private ArrayList<JobTile> mJobs;
|
||||
|
||||
// tiles that have new data to upload, see passTile()
|
||||
private ArrayList<MapTile> mTilesLoaded;
|
||||
|
||||
private boolean mInitialized;
|
||||
|
||||
// private static MapPosition mCurPosition, mDrawPosition;
|
||||
@ -75,6 +75,8 @@ public class TileManager {
|
||||
|
||||
private static int mUpdateCnt;
|
||||
static Object tilelock = new Object();
|
||||
static volatile int tilesForUpload;
|
||||
|
||||
private static TileSet mCurrentTiles;
|
||||
/* package */static TileSet mNewTiles;
|
||||
|
||||
@ -138,10 +140,11 @@ public class TileManager {
|
||||
|
||||
mJobs = new ArrayList<JobTile>();
|
||||
mTiles = new MapTile[GLRenderer.CACHE_TILES];
|
||||
mTilesLoaded = new ArrayList<MapTile>(30);
|
||||
|
||||
mTilesSize = 0;
|
||||
mUpdateCnt = 0;
|
||||
tilesForUpload = 0;
|
||||
|
||||
mInitialized = false;
|
||||
}
|
||||
|
||||
@ -182,8 +185,6 @@ public class TileManager {
|
||||
mTilesSize = 0;
|
||||
mTilesCount = 0;
|
||||
|
||||
mTilesLoaded.clear();
|
||||
|
||||
for (TileSet td : mTileSets) {
|
||||
Arrays.fill(td.tiles, null);
|
||||
td.cnt = 0;
|
||||
@ -233,10 +234,9 @@ public class TileManager {
|
||||
mMapView.render();
|
||||
|
||||
int remove = mTilesCount - GLRenderer.CACHE_TILES;
|
||||
if (remove > CACHE_THRESHOLD)
|
||||
if (remove > CACHE_THRESHOLD ||
|
||||
tilesForUpload > (MAX_TILES_IN_QUEUE + 10))
|
||||
limitCache(mapPosition, remove);
|
||||
|
||||
limitLoadQueue();
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,9 +282,12 @@ public class TileManager {
|
||||
return td;
|
||||
}
|
||||
|
||||
// public void releaseTiles(TileSet tiles) {
|
||||
//
|
||||
// }
|
||||
/**
|
||||
* @param tiles ...
|
||||
*/
|
||||
public void releaseTiles(TileSet tiles) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* set mNewTiles for the visible tiles and pass it to GLRenderer, add jobs
|
||||
@ -403,12 +406,10 @@ public class TileManager {
|
||||
if (p == null) {
|
||||
p = new MapTile(x >> 1, y >> 1, (byte) (zoomLevel - 1));
|
||||
QuadTree.add(p);
|
||||
|
||||
p.state = STATE_LOADING;
|
||||
mJobs.add(p);
|
||||
|
||||
} else if (!p.isActive()) {
|
||||
//Log.d(TAG, "prefetch parent " + p);
|
||||
p.state = STATE_LOADING;
|
||||
mJobs.add(p);
|
||||
}
|
||||
@ -505,18 +506,11 @@ public class TileManager {
|
||||
remove--;
|
||||
}
|
||||
|
||||
if (remove > 10) {
|
||||
if (remove > 10 || tilesForUpload > MAX_TILES_IN_QUEUE) {
|
||||
updateTileDistances(tiles, size, mapPosition);
|
||||
|
||||
// double start, end;
|
||||
// start = SystemClock.uptimeMillis();
|
||||
|
||||
TileDistanceSort.sort(tiles, 0, size);
|
||||
|
||||
//end = SystemClock.uptimeMillis();
|
||||
//Log.d(TAG, "sort took " + (end - start) +
|
||||
// "limitCache: repacked: " + mTilesSize + " to: " + mTilesCount);
|
||||
|
||||
// sorting also repacks the 'sparse' filled array
|
||||
// so end of mTiles is at mTilesCount now
|
||||
mTilesSize = size = mTilesCount;
|
||||
@ -528,66 +522,33 @@ public class TileManager {
|
||||
Log.d(TAG, "limitCache: tile still locked " + t + " " + t.distance);
|
||||
//mTiles.add(t);
|
||||
} else if (t.state == STATE_LOADING) {
|
||||
// NOTE: if we add tile back and set loading=false, on next
|
||||
// limitCache the tile will be removed. clearTile could
|
||||
// interfere with TileGenerator. so clear in passTile()
|
||||
// instead.
|
||||
// ... no, this does not work either: when set loading to
|
||||
// false tile could be added to load queue while still
|
||||
// processed in TileGenerator => need tile.cancel flag.
|
||||
// NOTE: when set loading to false the tile could be
|
||||
// added to load queue again while still processed in
|
||||
// TileGenerator => need tile.cancel flag.
|
||||
// t.isLoading = false;
|
||||
//mTiles.add(t);
|
||||
Log.d(TAG, "limitCache: cancel loading " + t + " " + t.distance);
|
||||
} else {
|
||||
if (t.state == STATE_NEW_DATA)
|
||||
tilesForUpload--;
|
||||
|
||||
clearTile(t);
|
||||
tiles[size - i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void limitLoadQueue() {
|
||||
int size = mTilesLoaded.size();
|
||||
remove = (tilesForUpload - MAX_TILES_IN_QUEUE);
|
||||
//Log.d(TAG, "cleanup load queue " + tilesForUpload + "/" + remove);
|
||||
|
||||
if (size < MAX_TILES_IN_QUEUE)
|
||||
return;
|
||||
|
||||
synchronized (mTilesLoaded) {
|
||||
// remove tiles already uploaded to vbo
|
||||
for (int i = 0; i < size;) {
|
||||
MapTile t = mTilesLoaded.get(i);
|
||||
if (t.state == STATE_READY || t.state == STATE_NONE) {
|
||||
mTilesLoaded.remove(i);
|
||||
size--;
|
||||
continue;
|
||||
for (int i = 1; i < size && remove > 0; i++) {
|
||||
MapTile t = tiles[size - i];
|
||||
if (t != null && t.state == STATE_NEW_DATA && !t.isLocked()) {
|
||||
//Log.d(TAG, "remove from load queue " + t);
|
||||
clearTile(t);
|
||||
tiles[size - i] = null;
|
||||
remove--;
|
||||
tilesForUpload--;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (size < MAX_TILES_IN_QUEUE)
|
||||
return;
|
||||
|
||||
// clear loaded but not used tiles
|
||||
for (int i = 0, n = size - MAX_TILES_IN_QUEUE / 2; i < n; n--) {
|
||||
MapTile t = mTilesLoaded.get(i);
|
||||
|
||||
if (t.isLocked()) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
mTilesLoaded.remove(i);
|
||||
|
||||
// remove reference from mTiles
|
||||
MapTile[] tiles = mTiles;
|
||||
for (int j = 0, m = mTilesSize; j < m; j++) {
|
||||
if (t == tiles[j]) {
|
||||
mTiles[j] = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
clearTile(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -595,8 +556,8 @@ public class TileManager {
|
||||
/**
|
||||
* called from MapWorker Thread when tile is loaded by TileGenerator
|
||||
* @param jobTile
|
||||
* ...
|
||||
* @return ...
|
||||
* Tile ready for upload to GL
|
||||
* @return ... caller does not care
|
||||
*/
|
||||
public synchronized boolean passTile(JobTile jobTile) {
|
||||
MapTile tile = (MapTile) jobTile;
|
||||
@ -617,13 +578,12 @@ public class TileManager {
|
||||
|
||||
tile.state = STATE_NEW_DATA;
|
||||
|
||||
//if (tile.isVisible)
|
||||
mMapView.render();
|
||||
// locked means the tile is visible or referenced by
|
||||
// a tile that might be visible.
|
||||
if (tile.isLocked())
|
||||
mMapView.render();
|
||||
|
||||
synchronized (mTilesLoaded) {
|
||||
//if (!mTilesLoaded.contains(tile))
|
||||
mTilesLoaded.add(tile);
|
||||
}
|
||||
tilesForUpload++;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -633,10 +593,5 @@ public class TileManager {
|
||||
|
||||
mWidth = w;
|
||||
mHeight = h;
|
||||
|
||||
// size changed does not mean gl surface was recreated
|
||||
// FIXME iirc this was the case before honeycomb
|
||||
//if (mWidth > 0 && mHeight > 0)
|
||||
// mInitialized = true;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user