fix: unlock tiles properly onResume

This commit is contained in:
Hannes Janetzek 2012-11-07 23:13:57 +01:00
parent 7dd171dc24
commit dd64d6da26
7 changed files with 61 additions and 84 deletions

View File

@ -140,12 +140,6 @@ public class MapDatabase implements IMapDatabase {
mLastRequest = SystemClock.elapsedRealtime(); mLastRequest = SystemClock.elapsedRealtime();
// FIXME remove this stuff
if (!mTile.isLoading) {
Log.d(TAG, "loading canceled " + mTile);
result = QueryResult.FAILED;
}
cacheFinish(tile, f, result == QueryResult.SUCCESS); cacheFinish(tile, f, result == QueryResult.SUCCESS);
return result; return result;

View File

@ -180,12 +180,9 @@ public class MapDatabase implements IMapDatabase {
try { try {
if (USE_LW_HTTP) { if (USE_LW_HTTP) {
if (lwHttpSendRequest(tile)) { if (lwHttpSendRequest(tile) && lwHttpReadHeader() > 0) {
if (lwHttpReadHeader() > 0) {
cacheBegin(tile, f); cacheBegin(tile, f);
decode(); decode();
}
} else { } else {
result = QueryResult.FAILED; result = QueryResult.FAILED;
} }
@ -254,12 +251,6 @@ public class MapDatabase implements IMapDatabase {
if (USE_APACHE_HTTP) if (USE_APACHE_HTTP)
mRequest = null; mRequest = null;
// FIXME remove this stuff
if (!mTile.isLoading) {
Log.d(TAG, "loading canceled " + mTile);
result = QueryResult.FAILED;
}
cacheFinish(tile, f, result == QueryResult.SUCCESS); cacheFinish(tile, f, result == QueryResult.SUCCESS);
return result; return result;
@ -877,6 +868,7 @@ public class MapDatabase implements IMapDatabase {
mBufferSize += len; mBufferSize += len;
} }
return read; return read;
} }

View File

@ -14,8 +14,8 @@
*/ */
package org.oscim.generator; package org.oscim.generator;
import org.oscim.renderer.TileManager;
import org.oscim.renderer.TileGenerator; import org.oscim.renderer.TileGenerator;
import org.oscim.renderer.TileManager;
import org.oscim.utils.PausableThread; import org.oscim.utils.PausableThread;
/** /**
@ -66,9 +66,9 @@ public class MapWorker extends PausableThread {
// Log.d("...", "load: " + tile); // Log.d("...", "load: " + tile);
boolean success = mMapGenerator.executeJob(tile); mMapGenerator.executeJob(tile);
if (!isInterrupted() && success) { if (!isInterrupted()) {
mTileManager.passTile(tile); mTileManager.passTile(tile);
} }
} }

View File

@ -301,17 +301,16 @@ public class GLRenderer implements GLSurfaceView.Renderer {
} }
private static boolean uploadTileData(MapTile tile) { private static boolean uploadTileData(MapTile tile) {
// synchronized (tile) { if (tile.layers != null) {
tile.isReady = uploadLayers(tile.layers, tile.vbo, true); tile.isReady = uploadLayers(tile.layers, tile.vbo, true);
if (!tile.isReady) { if (!tile.isReady) {
tile.layers.clear(); tile.layers.clear();
tile.layers = null; tile.layers = null;
} }
}
tile.newData = false; tile.newData = false;
// Log.d(TAG, "uploaded " + tile.isReady + " " + tile); // Log.d(TAG, "uploaded " + tile.isReady + " " + tile);
// }
return tile.isReady; return tile.isReady;
} }
@ -728,16 +727,14 @@ public class GLRenderer implements GLSurfaceView.Renderer {
@Override @Override
public void onSurfaceChanged(GL10 glUnused, int width, int height) { public void onSurfaceChanged(GL10 glUnused, int width, int height) {
Log.d(TAG, "SurfaceChanged:" + width + " " + height); Log.d(TAG, "SurfaceChanged:" + mNewSurface + " " + width + " " + height);
mDrawTiles = null;
if (width <= 0 || height <= 0) if (width <= 0 || height <= 0)
return; return;
boolean changed = true; // boolean changed = true;
if (mWidth == width || mHeight == height) // if (mWidth == width || mHeight == height)
changed = false; // changed = false;
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
@ -767,13 +764,14 @@ public class GLRenderer implements GLSurfaceView.Renderer {
GLES20.glViewport(0, 0, width, height); GLES20.glViewport(0, 0, width, height);
if (!changed && !mNewSurface) { if (!mNewSurface) {
mMapView.redrawMap(); mMapView.redrawMap();
return; return;
} }
mNewSurface = false; mNewSurface = false;
mBufferMemoryUsage = 0; mBufferMemoryUsage = 0;
mDrawTiles = null;
int numTiles = (mWidth / (Tile.TILE_SIZE / 2) + 2) int numTiles = (mWidth / (Tile.TILE_SIZE / 2) + 2)
* (mHeight / (Tile.TILE_SIZE / 2) + 2); * (mHeight / (Tile.TILE_SIZE / 2) + 2);
@ -791,7 +789,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
vertexArray[0] = false; vertexArray[0] = false;
vertexArray[1] = false; vertexArray[1] = false;
// FIXME this should be synchronized
mMapView.redrawMap(); mMapView.redrawMap();
} }
@ -800,10 +797,8 @@ public class GLRenderer implements GLSurfaceView.Renderer {
// String ext = GLES20.glGetString(GLES20.GL_EXTENSIONS); // String ext = GLES20.glGetString(GLES20.GL_EXTENSIONS);
// Log.d(TAG, "Extensions: " + ext); // Log.d(TAG, "Extensions: " + ext);
// GLES20.GL_POLYGON_OFFSET_UNITS
LineRenderer.init(); LineRenderer.init();
PolygonRenderer.init(); PolygonRenderer.init();
// TextRenderer.init();
TextureRenderer.init(); TextureRenderer.init();
TextureObject.init(10); TextureObject.init(10);
@ -818,4 +813,8 @@ public class GLRenderer implements GLSurfaceView.Renderer {
private boolean mNewSurface; private boolean mNewSurface;
private static final boolean debugView = false; private static final boolean debugView = false;
void clearBuffer() {
mNewSurface = true;
}
} }

View File

@ -423,7 +423,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
mLayers = new Layers(); mLayers = new Layers();
if (mMapDatabase.executeQuery(tile, this) != QueryResult.SUCCESS) { if (mMapDatabase.executeQuery(tile, this) != QueryResult.SUCCESS) {
Log.d(TAG, "Failed loading: " + tile); //Log.d(TAG, "Failed loading: " + tile);
mLayers.clear(); mLayers.clear();
mLayers = null; mLayers = null;
mLabels = null; mLabels = null;

View File

@ -16,7 +16,6 @@ package org.oscim.renderer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.locks.ReentrantLock;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;
@ -61,7 +60,7 @@ public class TileManager {
private static float[] mTileCoords = new float[8]; private static float[] mTileCoords = new float[8];
static int mUpdateCnt; static int mUpdateCnt;
static ReentrantLock tilelock = new ReentrantLock(); static Object tilelock = new Object();
static Tiles mCurrentTiles; static Tiles mCurrentTiles;
/* package */static Tiles mNewTiles; /* package */static Tiles mNewTiles;
@ -134,12 +133,12 @@ public class TileManager {
} }
private TileManager(MapView mapView) { private TileManager(MapView mapView) {
Log.d(TAG, "init TileManager");
mMapView = mapView; mMapView = mapView;
mMapViewPosition = mapView.getMapViewPosition(); mMapViewPosition = mapView.getMapViewPosition();
mJobList = new ArrayList<JobTile>(); mJobList = new ArrayList<JobTile>();
mTiles = new ArrayList<MapTile>(); mTiles = new ArrayList<MapTile>(200);
mTilesLoaded = new ArrayList<MapTile>(30); mTilesLoaded = new ArrayList<MapTile>(30);
// this is probably a good place to init these // this is probably a good place to init these
@ -165,45 +164,40 @@ public class TileManager {
if (mMapView == null) if (mMapView == null)
return; return;
// FIXME too messy!
if (clear || mInitial) { if (clear || mInitial) {
// make sure onDrawFrame is not running // make sure onDrawFrame is not running, and labeling thread?
GLRenderer.drawlock.lock(); GLRenderer.drawlock.lock();
// remove all tiles references
// clear all tiles references
Log.d(TAG, "CLEAR " + mInitial); Log.d(TAG, "CLEAR " + mInitial);
mUpdateCnt = 0;
if (clear) { if (clear) {
// pass VBOs and VertexItems back to pools
for (MapTile t : mTiles) for (MapTile t : mTiles)
clearTile(t); clearTile(t);
} else { } else {
VertexPool.init(); VertexPool.init();
} }
//VertexPool.init();
QuadTree.init();
mTiles.clear(); mTiles.clear();
mTilesLoaded.clear(); mTilesLoaded.clear();
QuadTree.init();
// set up TileData arrays that are passed to gl-thread // set up TileData arrays that are passed to gl-thread
int num = mWidth; int num = Math.max(mWidth, mHeight);
if (mWidth < mHeight)
num = mHeight;
int size = Tile.TILE_SIZE >> 1; int size = Tile.TILE_SIZE >> 1;
int numTiles = (num * num) / (size * size) * 4; int numTiles = (num * num) / (size * size) * 4;
// mRenderer.clearTiles(numTiles);
mNewTiles = new Tiles(numTiles); mNewTiles = new Tiles(numTiles);
mCurrentTiles = new Tiles(numTiles); mCurrentTiles = new Tiles(numTiles);
// MapInfo mapInfo = mMapView.getMapDatabase().getMapInfo();
// if (mapInfo != null)
// mZoomLevels = mapInfo.zoomLevel;
GLRenderer.drawlock.unlock(); GLRenderer.drawlock.unlock();
// .. make sure mMapPosition will be updated // .. make sure mMapPosition will be updated
mMapPosition.zoomLevel = -1; mMapPosition.zoomLevel = -1;
mInitial = false; mInitial = false;
} }
@ -253,8 +247,7 @@ public class TileManager {
return td; return td;
// dont flip new/currentTiles while copying // dont flip new/currentTiles while copying
TileManager.tilelock.lock(); synchronized (TileManager.tilelock) {
try {
MapTile[] newTiles = mCurrentTiles.tiles; MapTile[] newTiles = mCurrentTiles.tiles;
int cnt = mCurrentTiles.cnt; int cnt = mCurrentTiles.cnt;
@ -264,9 +257,13 @@ public class TileManager {
MapTile[] nextTiles; MapTile[] nextTiles;
if (td == null) if (td == null) {
td = new Tiles(newTiles.length); td = new Tiles(newTiles.length);
} else if (td.serial > mUpdateCnt) {
Log.d(TAG, "ignore previous tile data " + td.cnt);
// tile data was cleared, ignore tiles
td.cnt = 0;
}
nextTiles = td.tiles; nextTiles = td.tiles;
// unlock previously active tiles // unlock previously active tiles
@ -278,8 +275,6 @@ public class TileManager {
td.serial = mUpdateCnt; td.serial = mUpdateCnt;
td.cnt = cnt; td.cnt = cnt;
} finally {
TileManager.tilelock.unlock();
} }
return td; return td;
@ -313,7 +308,7 @@ public class TileManager {
MapTile[] newTiles = mNewTiles.tiles; MapTile[] newTiles = mNewTiles.tiles;
MapTile[] curTiles = mCurrentTiles.tiles; MapTile[] curTiles = mCurrentTiles.tiles;
boolean changed = false; boolean changed = (mNewTiles.cnt != mCurrentTiles.cnt);
for (int i = 0, n = mNewTiles.cnt; i < n && !changed; i++) { for (int i = 0, n = mNewTiles.cnt; i < n && !changed; i++) {
MapTile t = newTiles[i]; MapTile t = newTiles[i];
@ -330,8 +325,7 @@ public class TileManager {
} }
if (changed) { if (changed) {
TileManager.tilelock.lock(); synchronized (TileManager.tilelock) {
try {
for (int i = 0, n = mNewTiles.cnt; i < n; i++) for (int i = 0, n = mNewTiles.cnt; i < n; i++)
newTiles[i].lock(); newTiles[i].lock();
@ -343,8 +337,6 @@ public class TileManager {
mNewTiles = tmp; mNewTiles = tmp;
mUpdateCnt++; mUpdateCnt++;
} finally {
TileManager.tilelock.unlock();
} }
// Log.d(TAG, "tiles: " + tileCounter + " " + BufferObject.counter // Log.d(TAG, "tiles: " + tileCounter + " " + BufferObject.counter
@ -615,12 +607,12 @@ public class TileManager {
public synchronized boolean passTile(JobTile jobTile) { public synchronized boolean passTile(JobTile jobTile) {
MapTile tile = (MapTile) jobTile; MapTile tile = (MapTile) jobTile;
// if (!tile.isLoading) { if (!tile.isLoading) {
// // no one should be able to use this tile now, TileGenerator passed // no one should be able to use this tile now, TileGenerator passed
// // it, GL-Thread does nothing until newdata is set. // it, GL-Thread does nothing until newdata is set.
// Log.d(TAG, "passTile: canceled " + tile); //Log.d(TAG, "passTile: failed loading " + tile);
// return true; return true;
// } }
if (tile.vbo != null) { if (tile.vbo != null) {
// BAD Things(tm) happend... // BAD Things(tm) happend...

View File

@ -99,6 +99,8 @@ public class MapView extends RelativeLayout {
private String mRenderTheme; private String mRenderTheme;
private Map<String, String> mMapOptions; private Map<String, String> mMapOptions;
private boolean mClearTiles;
/** /**
* @param context * @param context
* the enclosing MapActivity instance. * the enclosing MapActivity instance.
@ -310,14 +312,15 @@ public class MapView extends RelativeLayout {
mOverlayManager.onUpdate(mMapPosition, changed); mOverlayManager.onUpdate(mMapPosition, changed);
} }
mTileManager.updateMap(false); mTileManager.updateMap(mClearTiles);
mClearTiles = false;
} }
public void clearAndRedrawMap() { public void clearAndRedrawMap() {
if (mPausing || this.getWidth() == 0 || this.getHeight() == 0) if (mPausing || this.getWidth() == 0 || this.getHeight() == 0)
return; return;
if (AndroidUtils.currentThreadIsUiThread()) //if (AndroidUtils.currentThreadIsUiThread())
mTileManager.updateMap(true); mTileManager.updateMap(true);
} }
@ -415,28 +418,25 @@ public class MapView extends RelativeLayout {
if (debugDatabase) if (debugDatabase)
return; return;
TileGenerator tileGenerator;
Log.i(TAG, "setMapDatabase " + mapDatabaseType.name()); Log.i(TAG, "setMapDatabase " + mapDatabaseType.name());
if (mMapDatabaseType == mapDatabaseType) if (mMapDatabaseType == mapDatabaseType)
return; return;
mMapDatabaseType = mapDatabaseType; mMapDatabaseType = mapDatabaseType;
mapWorkersPause(true); mapWorkersPause(true);
for (MapWorker mapWorker : mMapWorkers) { for (MapWorker mapWorker : mMapWorkers) {
tileGenerator = mapWorker.getMapGenerator(); TileGenerator tileGenerator = mapWorker.getMapGenerator();
tileGenerator.setMapDatabase(MapDatabaseFactory tileGenerator.setMapDatabase(MapDatabaseFactory
.createMapDatabase(mapDatabaseType)); .createMapDatabase(mapDatabaseType));
} }
mJobQueue.clear(); mJobQueue.clear();
mClearTiles = true;
setMapOptions(null); setMapOptions(null);
mapWorkersProceed(); mapWorkersProceed();
} }