diff --git a/src/org/oscim/layers/Layer.java b/src/org/oscim/layers/Layer.java index c9925d97..879164c3 100644 --- a/src/org/oscim/layers/Layer.java +++ b/src/org/oscim/layers/Layer.java @@ -18,7 +18,7 @@ import org.oscim.core.MapPosition; import org.oscim.renderer.RenderLayer; import org.oscim.view.MapView; -public class Layer { +public abstract class Layer { public Layer(MapView mapView) { mMapView = mapView; } @@ -45,7 +45,6 @@ public class Layer { return mEnabled; } - /** * Called before each frame render request (on main thread). * @@ -53,12 +52,15 @@ public class Layer { * current MapPosition * @param changed * true when MapPosition has changed since last call + * @param clear + * Clear all resources that depend on previous map state. Most + * importantly all resources from previous GL context (hold by + * RenderLayer) */ - public void onUpdate(MapPosition mapPosition, boolean changed) { + public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) { } - /** * Override to perform clean up of resources before shutdown. By default * does nothing. @@ -69,6 +71,5 @@ public class Layer { public void destroy() { // TODO Auto-generated method stub - } } diff --git a/src/org/oscim/layers/overlay/BuildingOverlay.java b/src/org/oscim/layers/overlay/BuildingOverlay.java index 91ad372b..73c7cef8 100644 --- a/src/org/oscim/layers/overlay/BuildingOverlay.java +++ b/src/org/oscim/layers/overlay/BuildingOverlay.java @@ -70,7 +70,7 @@ public class BuildingOverlay extends Overlay { private boolean mActive = false; @Override - public void onUpdate(MapPosition mapPosition, boolean changed) { + public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) { boolean show = mapPosition.scale >= (1 << MIN_ZOOM); if (show && mActive) diff --git a/src/org/oscim/layers/overlay/LabelingOverlay.java b/src/org/oscim/layers/overlay/LabelingOverlay.java index 2cb82f57..619e5b0b 100644 --- a/src/org/oscim/layers/overlay/LabelingOverlay.java +++ b/src/org/oscim/layers/overlay/LabelingOverlay.java @@ -14,6 +14,7 @@ */ package org.oscim.layers.overlay; +import org.oscim.core.MapPosition; import org.oscim.layers.tile.TileRenderLayer; import org.oscim.renderer.layers.TextRenderLayer; import org.oscim.view.MapView; @@ -34,6 +35,12 @@ public class LabelingOverlay extends Overlay { mLayer = mTextLayer; } + @Override + public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) { + if (clear) + mTextLayer.clearLabels(); + } + private int multi; @Override diff --git a/src/org/oscim/layers/overlay/MapScaleBar.java b/src/org/oscim/layers/overlay/MapScaleBar.java index dee64334..7687101c 100644 --- a/src/org/oscim/layers/overlay/MapScaleBar.java +++ b/src/org/oscim/layers/overlay/MapScaleBar.java @@ -95,7 +95,7 @@ public class MapScaleBar extends Layer { } @Override - public void onUpdate(MapPosition mapPosition, boolean changed) { + public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) { double latitude = MercatorProjection.toLatitude(mapPosition.y); if (!mRedrawNeeded) { diff --git a/src/org/oscim/layers/tile/TileLayer.java b/src/org/oscim/layers/tile/TileLayer.java index 76b190a2..c84e3017 100644 --- a/src/org/oscim/layers/tile/TileLayer.java +++ b/src/org/oscim/layers/tile/TileLayer.java @@ -24,9 +24,8 @@ public abstract class TileLayer extends Layer { //private final static String TAG = TileLayer.class.getName(); private final static int MAX_ZOOMLEVEL = 17; - private boolean mClearMap = true; - protected final TileManager mTileManager; + protected final TileRenderLayer mRenderLayer; protected final int mNumTileLoader = 4; protected final ArrayList mTileLoader; @@ -52,7 +51,7 @@ public abstract class TileLayer extends Layer { // RenderLayer is working in GL Thread and actually // drawing loaded tiles to screen. - mLayer = new TileRenderLayer(mapView, mTileManager); + mLayer = mRenderLayer = new TileRenderLayer(mapView, mTileManager); } abstract protected T createLoader(TileManager tm); @@ -62,11 +61,11 @@ public abstract class TileLayer extends Layer { } @Override - public void onUpdate(MapPosition mapPosition, boolean changed) { + public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) { - if (mClearMap) { + if (clear) { + mRenderLayer.clearTiles(); mTileManager.init(mMapView.getWidth(), mMapView.getHeight()); - mClearMap = false; changed = true; } if (changed) @@ -75,11 +74,7 @@ public abstract class TileLayer extends Layer { @Override public void destroy() { - - mTileManager.destroy(); - for (T tileWorker : mTileLoader) { - tileWorker.pause(); tileWorker.interrupt(); tileWorker.cleanup(); @@ -91,11 +86,7 @@ public abstract class TileLayer extends Layer { Thread.currentThread().interrupt(); } } - } - - protected void clearMap() { - // clear tile and overlay data before next draw - mClearMap = true; + mTileManager.destroy(); } void notifyLoaders() { diff --git a/src/org/oscim/layers/tile/TileManager.java b/src/org/oscim/layers/tile/TileManager.java index d135b5e0..035f5350 100644 --- a/src/org/oscim/layers/tile/TileManager.java +++ b/src/org/oscim/layers/tile/TileManager.java @@ -68,7 +68,8 @@ public class TileManager { // current end position in mTiles private int mTilesSize; - // counter for tiles with new data not uploaded to GL + // counter for tiles with new data not + // yet uploaded to GL private volatile int mTilesForUpload; // new tile jobs for MapWorkers @@ -80,12 +81,13 @@ public class TileManager { // lock for TileSets while updating MapTile locks private final Object mTilelock = new Object(); - // need to keep track of TileSets to clear on reset... - private final ArrayList mTileSets = new ArrayList(4); + // need to keep track of TileSets to clear on reset. + //private final ArrayList mTileSets = new ArrayList(4); private TileSet mCurrentTiles; /* package */TileSet mNewTiles; + // job queue filled in TileManager and polled by TileLoaders final JobQueue jobQueue; private final QuadTreeIndex mIndex = new QuadTreeIndex() { @@ -139,7 +141,7 @@ public class TileManager { // ... free static pools } - public synchronized void init(int width, int height) { + public void init(int width, int height) { // sync with GLRender thread // ... and labeling thread? @@ -150,29 +152,24 @@ public class TileManager { for (int i = 0; i < mTilesSize; i++) clearTile(mTiles[i]); } - //else { + + // FIXME any of this still needed? // mInitialized is set when surface changed // and VBOs might be lost // VertexPool.init(); - //} // clear cache index - //QuadTree.init(); + // QuadTree.init(); // clear references to cached MapTiles Arrays.fill(mTiles, null); mTilesSize = 0; mTilesCount = 0; - // clear all references to previous tiles - for (TileSet td : mTileSets) { - Arrays.fill(td.tiles, null); - td.cnt = 0; - } - // set up TileSet large enough to hold current tiles int num = Math.max(width, height); int size = Tile.SIZE >> 1; int numTiles = (num * num) / (size * size) * 4; + mNewTiles = new TileSet(numTiles); mCurrentTiles = new TileSet(numTiles); Log.d(TAG, "max tiles: " + numTiles); @@ -278,7 +275,7 @@ public class TileManager { limitCache(pos, remove); } - /** only used in setmapDatabase -- deprecate?*/ + /** only used in setmapDatabase -- deprecate? */ public void clearJobs() { jobQueue.clear(); } @@ -288,13 +285,19 @@ public class TileManager { * Tiles remain locked in cache until the set is unlocked by either passing * it again to this function or to releaseTiles. If passed TileSet is null * it will be allocated. + * + * @param tileSet to be updated + * @return true if TileSet has changed */ - public TileSet getActiveTiles(TileSet td) { + public boolean getActiveTiles(TileSet tileSet) { if (mCurrentTiles == null) - return td; + return false; - if (td != null && td.serial == mUpdateSerial) - return td; + if (tileSet == null) + return false; + + if (tileSet.serial == mUpdateSerial) + return false; // dont flip new/currentTiles while copying synchronized (mTilelock) { @@ -306,26 +309,24 @@ public class TileManager { newTiles[i].lock(); MapTile[] nextTiles; - - if (td == null) { - td = new TileSet(newTiles.length); - mTileSets.add(td); - } - - nextTiles = td.tiles; + nextTiles = tileSet.tiles; // unlock previously active tiles - for (int i = 0, n = td.cnt; i < n; i++) + for (int i = 0, n = tileSet.cnt; i < n; i++) nextTiles[i].unlock(); + if (nextTiles.length != mCurrentTiles.tiles.length) { + tileSet.tiles = nextTiles = new MapTile[mCurrentTiles.tiles.length]; + } + // copy newTiles to nextTiles System.arraycopy(newTiles, 0, nextTiles, 0, cnt); - td.serial = mUpdateSerial; - td.cnt = cnt; + tileSet.serial = mUpdateSerial; + tileSet.cnt = cnt; } - return td; + return true; } // /** @@ -392,8 +393,9 @@ public class TileManager { if (mTilesSize == mTiles.length) { if (mTilesSize > mTilesCount) { - //Log.d(TAG, "repack: " + mTiles.length + " / " + mTilesCount); TileDistanceSort.sort(mTiles, 0, mTilesSize); + // sorting also repacks the 'sparse' filled array + // so end of mTiles is at mTilesCount now mTilesSize = mTilesCount; } @@ -551,10 +553,10 @@ public class TileManager { * called from MapWorker Thread when tile is loaded by MapTileLoader * * @param tile - * Tile ready for upload to GL - * @return ... caller does not care + * Tile ready for upload in TileRenderLayer + * @return caller does not care */ - public synchronized boolean passTile(MapTile tile) { + public boolean passTile(MapTile tile) { if (tile.state != STATE_LOADING) { // - should rather be STATE_FAILED @@ -565,6 +567,8 @@ public class TileManager { } tile.state = STATE_NEW_DATA; + + // is volatile mTilesForUpload++; // locked means the tile is visible or referenced by diff --git a/src/org/oscim/layers/tile/TileRenderLayer.java b/src/org/oscim/layers/tile/TileRenderLayer.java index a0543c84..6e2d4acf 100644 --- a/src/org/oscim/layers/tile/TileRenderLayer.java +++ b/src/org/oscim/layers/tile/TileRenderLayer.java @@ -48,24 +48,15 @@ public class TileRenderLayer extends RenderLayer { mMapPosition.copy(pos); - int serial = 0; - if (mDrawTiles != null) - serial = mDrawTiles.getSerial(); - + boolean tilesChanged; synchronized (tilelock) { // get current tiles to draw - mDrawTiles = mTileManager.getActiveTiles(mDrawTiles); + tilesChanged = mTileManager.getActiveTiles(mDrawTiles); } - if (mDrawTiles == null || mDrawTiles.cnt == 0) + if (mDrawTiles.cnt == 0) return; - boolean tilesChanged = false; - - // check if tiles have changed. - if (serial != mDrawTiles.getSerial()) - tilesChanged = true; - int tileCnt = mDrawTiles.cnt; MapTile[] tiles = mDrawTiles.tiles; @@ -90,6 +81,14 @@ public class TileRenderLayer extends RenderLayer { } + public void clearTiles() { + // Clear all references to MapTiles as all current + // tiles will also be removed from TileManager. + GLRenderer.drawlock.lock(); + mDrawTiles = new TileSet(); + GLRenderer.drawlock.unlock(); + } + /** compile tile layer data and upload to VBOs */ private static int compileTileLayers(MapTile[] tiles, int tileCnt) { int uploadCnt = 0; @@ -189,10 +188,22 @@ public class TileRenderLayer extends RenderLayer { } } - // get a TileSet of currently visible tiles - public TileSet getVisibleTiles(TileSet td) { - if (mDrawTiles == null) - return td; + /** + * Update tileSet with currently visible tiles + * get a TileSet of currently visible tiles + */ + public boolean getVisibleTiles(TileSet tileSet) { + if (tileSet == null) + return false; + + if (mDrawTiles == null) { + releaseTiles(tileSet); + return false; + } + + // same tiles as before + if (tileSet.serial == mDrawTiles.serial) + return false; // ensure tiles keep visible state synchronized (tilelock) { @@ -200,24 +211,26 @@ public class TileRenderLayer extends RenderLayer { MapTile[] newTiles = mDrawTiles.tiles; int cnt = mDrawTiles.cnt; - if (td == null) - td = new TileSet(newTiles.length); - // unlock previous tiles - for (int i = 0; i < td.cnt; i++) - td.tiles[i].unlock(); + for (int i = 0; i < tileSet.cnt; i++) + tileSet.tiles[i].unlock(); + + // ensure same size + if (tileSet.tiles.length != mDrawTiles.tiles.length) { + tileSet.tiles = new MapTile[mDrawTiles.tiles.length]; + } // lock tiles to not be removed from cache - td.cnt = 0; + tileSet.cnt = 0; for (int i = 0; i < cnt; i++) { MapTile t = newTiles[i]; if (t.isVisible && t.state == STATE_READY) { t.lock(); - td.tiles[td.cnt++] = t; + tileSet.tiles[tileSet.cnt++] = t; } } } - return td; + return true; } public void releaseTiles(TileSet td) { @@ -236,7 +249,7 @@ public class TileRenderLayer extends RenderLayer { // happens rarely, unless you live on Fidschi /* package */int mNumTileHolder; - /* package */TileSet mDrawTiles; + /* package */TileSet mDrawTiles = new TileSet(); // scanline fill class used to check tile visibility private final ScanBox mScanBox = new ScanBox() { @@ -301,4 +314,5 @@ public class TileRenderLayer extends RenderLayer { } } }; + } diff --git a/src/org/oscim/layers/tile/TileSet.java b/src/org/oscim/layers/tile/TileSet.java index daa89cbd..e81e2b18 100644 --- a/src/org/oscim/layers/tile/TileSet.java +++ b/src/org/oscim/layers/tile/TileSet.java @@ -14,9 +14,9 @@ */ package org.oscim.layers.tile; +import java.util.Arrays; import java.util.Comparator; - /** * use with TileManager.getActiveTiles(TileSet) to get the current tiles. tiles * are locked to not be modifed until getActiveTiles passes them back on a @@ -28,18 +28,19 @@ public final class TileSet { int serial; - public int getSerial(){ + public int getSerial() { return serial; } - TileSet() { + public TileSet() { + tiles = new MapTile[1]; } public TileSet(int numTiles) { tiles = new MapTile[numTiles]; } - public MapTile getTile(int x, int y){ + public MapTile getTile(int x, int y) { for (int i = 0; i < cnt; i++) if (tiles[i].tileX == x && tiles[i].tileY == y) return tiles[i]; @@ -47,6 +48,11 @@ public final class TileSet { return null; } + public void clear() { + Arrays.fill(tiles, null); + cnt = 0; + } + public static Comparator coordComparator = new CoordComparator(); public static class CoordComparator implements Comparator { diff --git a/src/org/oscim/layers/tile/vector/MapTileLayer.java b/src/org/oscim/layers/tile/vector/MapTileLayer.java index a1f2339a..2457695a 100644 --- a/src/org/oscim/layers/tile/vector/MapTileLayer.java +++ b/src/org/oscim/layers/tile/vector/MapTileLayer.java @@ -104,7 +104,7 @@ public class MapTileLayer extends TileLayer { else MapView.enableClosePolygons = false; - clearMap(); + mMapView.clearMap(); resumeLoaders(); @@ -168,7 +168,7 @@ public class MapTileLayer extends TileLayer { mRenderTheme = internalRenderTheme.name(); } - clearMap(); + mMapView.clearMap(); return ret; } @@ -194,7 +194,7 @@ public class MapTileLayer extends TileLayer { mRenderTheme = renderThemePath; } - clearMap(); + mMapView.clearMap(); } private boolean setRenderTheme(Theme theme) { diff --git a/src/org/oscim/renderer/layers/ExtrusionRenderLayer.java b/src/org/oscim/renderer/layers/ExtrusionRenderLayer.java index e30a9f2e..9856376c 100644 --- a/src/org/oscim/renderer/layers/ExtrusionRenderLayer.java +++ b/src/org/oscim/renderer/layers/ExtrusionRenderLayer.java @@ -41,6 +41,7 @@ public class ExtrusionRenderLayer extends RenderLayer { public ExtrusionRenderLayer(MapView mapView, org.oscim.layers.tile.TileRenderLayer tileRenderLayer) { super(mapView); mTileLayer = tileRenderLayer; + mTileSet = new TileSet(); } private static int[] shaderProgram = new int[2]; @@ -56,7 +57,7 @@ public class ExtrusionRenderLayer extends RenderLayer { // FIXME sum up size used while filling layer only up to: //public int mBufferSize = 65536; - private TileSet mTileSet; + private final TileSet mTileSet; private MapTile[] mTiles; private int mTileCnt; @@ -85,18 +86,15 @@ public class ExtrusionRenderLayer extends RenderLayer { } } - int ready = 0; - mTileSet = mTileLayer.getVisibleTiles(mTileSet); - if (mTileSet == null) - return; - - MapTile[] tiles = mTileSet.tiles; - // FIXME just release tiles in this case if (mAlpha == 0 || pos.zoomLevel < 16) { isReady = false; return; } + int ready = 0; + mTileLayer.getVisibleTiles(mTileSet); + MapTile[] tiles = mTileSet.tiles; + // keep a list of tiles available for rendering if (mTiles == null || mTiles.length < mTileSet.cnt * 4) mTiles = new MapTile[mTileSet.cnt * 4]; @@ -104,9 +102,6 @@ public class ExtrusionRenderLayer extends RenderLayer { ExtrusionLayer el; if (pos.zoomLevel >= 17) { for (int i = 0; i < mTileSet.cnt; i++) { - if (!tiles[i].isVisible) - continue; - el = getLayer(tiles[i]); if (el == null) continue; @@ -123,12 +118,9 @@ public class ExtrusionRenderLayer extends RenderLayer { mTiles[ready++] = tiles[i]; } } else if (pos.zoomLevel == 16) { + // check if proxy children are ready for (int i = 0; i < mTileSet.cnt; i++) { - if (!tiles[i].isVisible) - continue; - MapTile t = tiles[i]; - for (byte j = 0; j < 4; j++) { if ((t.proxies & (1 << j)) != 0) { MapTile c = t.rel.get(j); diff --git a/src/org/oscim/renderer/layers/TextRenderLayer.java b/src/org/oscim/renderer/layers/TextRenderLayer.java index 8fd55043..4d9d23a5 100644 --- a/src/org/oscim/renderer/layers/TextRenderLayer.java +++ b/src/org/oscim/renderer/layers/TextRenderLayer.java @@ -57,6 +57,7 @@ import org.oscim.view.MapViewPosition; import android.opengl.GLES20; import android.os.SystemClock; +import android.util.Log; public class TextRenderLayer extends BasicRenderLayer { private final static String TAG = TextRenderLayer.class.getName(); @@ -64,7 +65,7 @@ public class TextRenderLayer extends BasicRenderLayer { private final static float MIN_WAY_DIST = 3; private final MapViewPosition mMapViewPosition; - private TileSet mTileSet; + private final TileSet mTileSet; private final LabelThread mThread; private MapPosition mTmpPos; @@ -170,15 +171,18 @@ public class TextRenderLayer extends BasicRenderLayer { @Override protected void doWork() { SystemClock.sleep(250); + if (!mRun) return; - mRun = false; + synchronized (this) { - if (updateLabels()) { - mMapView.render(); - } else { - mRun = true; + if (updateLabels()) { + mRun = false; + mMapView.render(); + } else { + mRun = true; + } } } @@ -202,8 +206,10 @@ public class TextRenderLayer extends BasicRenderLayer { mMapViewPosition = mapView.getMapViewPosition(); mTileLayer = baseLayer; + mTileSet = new TileSet(); layers.textureLayers = new TextLayer(); mTmpLayer = new TextLayer(); + //mActiveTiles = new HashMap(); mTmpPos = new MapPosition(); mThread = new LabelThread(); @@ -348,9 +354,7 @@ public class TextRenderLayer extends BasicRenderLayer { return false; // get current tiles - mTileSet = mTileLayer.getVisibleTiles(mTileSet); - if (mTileSet == null) - return false; + mTileLayer.getVisibleTiles(mTileSet); if (mTileSet.cnt == 0) return false; @@ -613,10 +617,10 @@ public class TextRenderLayer extends BasicRenderLayer { mTileLayer.releaseTiles(mTileSet); // pass new labels for rendering - synchronized (this) { + //synchronized (this) { mNextLayer = tl; mDebugLayer = dbg; - } + //} return true; } @@ -774,4 +778,14 @@ public class TextRenderLayer extends BasicRenderLayer { // mRun = false; // } } + + public void clearLabels() { + Log.d(TAG, "clearLabels"); + synchronized (mThread) { + mRun = false; + mPool.releaseAll(mPrevLabels); + mPrevLabels = null; + mTileSet.clear(); + } + } } diff --git a/src/org/oscim/utils/pool/Pool.java b/src/org/oscim/utils/pool/Pool.java index a5e6d532..b59d8885 100644 --- a/src/org/oscim/utils/pool/Pool.java +++ b/src/org/oscim/utils/pool/Pool.java @@ -37,6 +37,22 @@ public abstract class Pool> { pool = item; } + public void releaseAll(T item) { + if (item == null) + return; + + while (item != null) { + T next = item.next; + + clearItem(item); + + item.next = pool; + pool = item; + + item = next; + } + } + // remove 'item' from 'list' and add back to pool public T release(T list, T item) { if (item == null) @@ -44,7 +60,6 @@ public abstract class Pool> { clearItem(item); - if (item == list) { T ret = item.next; diff --git a/src/org/oscim/view/LayerManager.java b/src/org/oscim/view/LayerManager.java index fc3f68c3..f96385ba 100644 --- a/src/org/oscim/view/LayerManager.java +++ b/src/org/oscim/view/LayerManager.java @@ -95,6 +95,24 @@ public class LayerManager extends AbstractList implements OnGestureListen o.onDetach(); } + public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) { + if (mDirtyLayers) + updateLayers(); + + for (Layer l : mLayers) + l.onUpdate(mapPosition, changed, clear); + } + + public void destroy() { + if (mDirtyLayers) + updateLayers(); + + for (Layer l : mLayers) { + l.destroy(); + } + } + + Layer[] mLayers; InputLayer[] mInputLayer; @@ -371,22 +389,7 @@ public class LayerManager extends AbstractList implements OnGestureListen return false; } - public void onUpdate(MapPosition mapPosition, boolean changed) { - if (mDirtyLayers) - updateLayers(); - for (Layer l : mLayers) - l.onUpdate(mapPosition, changed); - } - - public void destroy() { - if (mDirtyLayers) - updateLayers(); - - for (Layer l : mLayers) { - l.destroy(); - } - } // /** // * Gets the optional TilesLayer class. diff --git a/src/org/oscim/view/MapView.java b/src/org/oscim/view/MapView.java index 70208a19..c9d4aea9 100644 --- a/src/org/oscim/view/MapView.java +++ b/src/org/oscim/view/MapView.java @@ -66,6 +66,7 @@ public class MapView extends RelativeLayout { private int mWidth; private int mHeight; + private boolean mInitialized; // FIXME: keep until old pbmap reader is removed public static boolean enableClosePolygons = false; @@ -133,6 +134,7 @@ public class MapView extends RelativeLayout { addView(mGLView, params); + clearMap(); redrawMap(false); } @@ -147,7 +149,7 @@ public class MapView extends RelativeLayout { mRotationEnabled = true; - //mLayerManager.add(new GenericOverlay(this, new GridOverlay(this))); + //mLayerManager.add(new GenericOverlay(this, new GridRenderLayer(this))); mLayerManager.add(new BuildingOverlay(this, baseLayer.getTileLayer())); mLayerManager.add(new LabelingOverlay(this, baseLayer.getTileLayer())); @@ -161,8 +163,6 @@ public class MapView extends RelativeLayout { public MapTileLayer setBaseMap(BitmapTileLayer tileLayer) { mLayerManager.add(0, new MapEventLayer(this)); mLayerManager.add(1, tileLayer); - - //mRotationEnabled = true; return null; } @@ -170,6 +170,11 @@ public class MapView extends RelativeLayout { mLayerManager.destroy(); } + public void onStop() { + Log.d(TAG, "onStop"); + //mLayerManager.destroy(); + } + private boolean mPausing = false; void onPause() { @@ -181,18 +186,12 @@ public class MapView extends RelativeLayout { } void onResume() { - if (this.mCompassEnabled) mCompass.enable(); mPausing = false; } - public void onStop() { - Log.d(TAG, "onStop"); - //mLayerManager.destroy(); - } - @Override public boolean onTouchEvent(MotionEvent motionEvent) { @@ -212,11 +211,13 @@ public class MapView extends RelativeLayout { mWidth = width; mHeight = height; - if (width != 0 && height != 0) + mInitialized = (mWidth > 0 && mWidth > 0); + + if (mInitialized) mMapViewPosition.setViewport(width, height); } - boolean mWaitRedraw; + /* private */boolean mWaitRedraw; private final Runnable mRedrawRequest = new Runnable() { @Override @@ -229,49 +230,62 @@ public class MapView extends RelativeLayout { /** * Request to redraw the map when a global state like position, * datasource or theme has changed. This will trigger a call - * to onUpdate() to all Layers. + * to onUpdate() for all Layers. * * @param requestRender * also request to draw a frame */ public void redrawMap(boolean requestRender) { - if (requestRender) { - if (!(mPausing || mWidth == 0 || mHeight == 0)) - mGLView.requestRender(); - } + if (requestRender && !mClearMap && !mPausing && mInitialized) + mGLView.requestRender(); + if (!mWaitRedraw) { mWaitRedraw = true; post(mRedrawRequest); } } + private boolean mClearMap; + + public void clearMap(){ + mClearMap = true; + } /** * Request to render a frame. Use this for animations. */ public void render() { - mGLView.requestRender(); + if (mClearMap) + redrawMap(false); + else + mGLView.requestRender(); } /** - * Calculates all necessary tiles and adds jobs accordingly. + * Update all Layers on Main thread. * - * @param forceRedraw TODO + * @param forceRedraw also render frame + * FIXME (does nothing atm) */ void redrawMapInternal(boolean forceRedraw) { - boolean changed = false; + boolean changed = forceRedraw; - if (mPausing || mWidth == 0 || mHeight == 0) + if (mPausing || !mInitialized) return; - if (forceRedraw) { + if (forceRedraw && !mClearMap) mGLView.requestRender(); - changed = true; - } // get the current MapPosition changed |= mMapViewPosition.getMapPosition(mMapPosition); - mLayerManager.onUpdate(mMapPosition, changed); + mLayerManager.onUpdate(mMapPosition, changed, mClearMap); + + // delay redraw until all layers had the chance to clear + // their state. + if (mClearMap){ + mGLView.requestRender(); + mClearMap =false; + } } /**