From d91402da3c603d9c6d7b3403a6d9fef948c7c4b3 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Thu, 19 Sep 2013 22:44:12 +0200 Subject: [PATCH] add getters for MapTile state, modify 'state' only within package - clear tile in TileManager when loading has failed --- .../layers/tile/vector/VectorTileLoader.java | 63 +------------ .../gdx/emu/org/oscim/tiling/TileLoader.java | 20 ++-- vtm/src/org/oscim/layers/tile/TileLayer.java | 5 +- .../layers/tile/vector/VectorTileLoader.java | 17 +--- .../tile/vector/labeling/TextRenderer.java | 6 +- .../org/oscim/renderer/ExtrusionRenderer.java | 4 +- vtm/src/org/oscim/tiling/MapTile.java | 94 ++++++++++++------- vtm/src/org/oscim/tiling/TileLoader.java | 14 ++- vtm/src/org/oscim/tiling/TileManager.java | 13 +-- 9 files changed, 93 insertions(+), 143 deletions(-) diff --git a/vtm-gdx-html/src/org/oscim/gdx/emu/org/oscim/layers/tile/vector/VectorTileLoader.java b/vtm-gdx-html/src/org/oscim/gdx/emu/org/oscim/layers/tile/vector/VectorTileLoader.java index 73bbb67c..a5622c19 100644 --- a/vtm-gdx-html/src/org/oscim/gdx/emu/org/oscim/layers/tile/vector/VectorTileLoader.java +++ b/vtm-gdx-html/src/org/oscim/gdx/emu/org/oscim/layers/tile/vector/VectorTileLoader.java @@ -66,9 +66,6 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac public static final byte STROKE_MIN_ZOOM_LEVEL = 12; public static final byte STROKE_MAX_ZOOM_LEVEL = 17; - //private static final Tag[] debugTagWay = { new Tag("debug", "way") }; - //private static final Tag[] debugTagArea = { new Tag("debug", "area") }; - // replacement for variable value tags that should not be matched by RenderTheme // FIXME make this general, maybe subclass tags private static final Tag mTagEmptyName = new Tag(Tag.TAG_KEY_NAME, null, false); @@ -109,24 +106,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac */ public VectorTileLoader(TileManager tileManager) { super(tileManager); - mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE, true); - - // MapElement m = mDebugWay = new MapElement(); - // m.startLine(); - // int s = Tile.SIZE; - // m.addPoint(0, 0); - // m.addPoint(0, s); - // m.addPoint(s, s); - // m.addPoint(s, 0); - // m.addPoint(0, 0); - // m.tags = new Tag[] { new Tag("debug", "box") }; - // m.type = GeometryType.LINE; - // - // m = mDebugPoint = new MapElement(); - // m.startPoints(); - // m.addPoint(s >> 1, 10); - // m.type = GeometryType.POINT; } @Override @@ -144,7 +124,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac if (mTile.layers != null) { // should be fixed now. - Log.d(TAG, "BUG tile already loaded " + mTile + " " + mTile.state); + Log.d(TAG, "BUG tile already loaded " + mTile + " " + mTile.getState()); mTile = null; return false; } @@ -168,20 +148,6 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac return false; } - // if (debug.drawTileFrames) { - // // draw tile coordinate - // mTagName = new Tag("name", mTile.toString(), false); - // mElement = mDebugPoint; - // RenderInstruction[] ri; - // ri = renderTheme.matchNode(debugTagWay, (byte) 0); - // renderNode(ri); - // - // // draw tile box - // mElement = mDebugWay; - // mDrawingLayer = 100 * renderLevels; - // ri = renderTheme.matchWay(mDebugWay.tags, (byte) 0, false); - // renderWay(ri); - // } return true; } @@ -191,17 +157,6 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac mTile = null; return; } - - mTile.layers.clear(); - mTile.layers = null; - TextItem.pool.releaseAll(mTile.labels); - mTile.labels = null; - // FIXME add STATE_FAILED? - // in passTile everything but STATE_LOADING is considered failed. - mTile.state = MapTile.STATE_NONE; - - mTile.loader.jobCompleted(mTile, false); - mTile = null; } Tag[] mFilterTags = new Tag[1]; @@ -317,18 +272,6 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac mElement = null; } - //private void debugUnmatched(boolean closed, TagSet tags) { - // Log.d(TAG, "DBG way not matched: " + closed + " " - // + Arrays.deepToString(tags)); - // - // mTagName = new Tag("name", tags[0].key + ":" - // + tags[0].value, false); - // - // mElement.tags = closed ? debugTagArea : debugTagWay; - // RenderInstruction[] ri = renderTheme.matchElement(mElement, mTile.zoomLevel); - // renderWay(ri); - //} - private void renderWay(RenderInstruction[] ri) { if (ri == null) return; @@ -351,10 +294,6 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac mCurLineLayer = null; } - // @Override - // public void renderWaterBackground() { - // } - // ----------------- RenderThemeCallback ----------------- @Override public void renderWay(Line line, int level) { diff --git a/vtm-gdx-html/src/org/oscim/gdx/emu/org/oscim/tiling/TileLoader.java b/vtm-gdx-html/src/org/oscim/gdx/emu/org/oscim/tiling/TileLoader.java index 71275ae1..e96826c7 100644 --- a/vtm-gdx-html/src/org/oscim/gdx/emu/org/oscim/tiling/TileLoader.java +++ b/vtm-gdx-html/src/org/oscim/gdx/emu/org/oscim/tiling/TileLoader.java @@ -38,7 +38,7 @@ public abstract class TileLoader { boolean isInterrupted; - void interrupt() { + public void interrupt() { isInterrupted = true; // cancel loading } @@ -96,24 +96,24 @@ public abstract class TileLoader { } public void jobCompleted(MapTile tile, boolean success) { - if (success) { - if (!isInterrupted) { - // pass tile to main thread - mTileManager.passTile(tile); - } + //if (success) { + if (!isInterrupted) { + // pass tile to main thread + mTileManager.passTile(tile, success); } + //} + mWorking = false; - if (!mPausing && !mTileManager.jobQueue.isEmpty()){ + if (!mPausing && !mTileManager.jobQueue.isEmpty()) { - Gdx.app.postRunnable(new Runnable(){ + Gdx.app.postRunnable(new Runnable() { @Override public void run() { go(); } - } - ); + }); } } } diff --git a/vtm/src/org/oscim/layers/tile/TileLayer.java b/vtm/src/org/oscim/layers/tile/TileLayer.java index ebbedac5..902ce749 100644 --- a/vtm/src/org/oscim/layers/tile/TileLayer.java +++ b/vtm/src/org/oscim/layers/tile/TileLayer.java @@ -99,10 +99,7 @@ public abstract class TileLayer extends Layer implements M void notifyLoaders() { for (int i = 0; i < mNumTileLoader; i++) { - T m = mTileLoader.get(i); - synchronized (m) { - m.go(); - } + mTileLoader.get(i).go(); } } diff --git a/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java b/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java index 3154d8a4..03392b7a 100644 --- a/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java +++ b/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java @@ -14,8 +14,6 @@ */ package org.oscim.layers.tile.vector; -import static org.oscim.tiling.MapTile.STATE_NONE; - import org.oscim.backend.Log; import org.oscim.core.GeometryBuffer.GeometryType; import org.oscim.core.MapElement; @@ -46,7 +44,6 @@ import org.oscim.tiling.source.ITileDataSink; import org.oscim.tiling.source.ITileDataSource; import org.oscim.tiling.source.ITileDataSource.QueryResult; import org.oscim.utils.LineClipper; -import org.oscim.utils.pool.Inlist; public class VectorTileLoader extends TileLoader implements IRenderTheme.Callback, ITileDataSink { @@ -120,7 +117,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac if (mTile.layers != null) { // should be fixed now. - Log.d(TAG, "BUG tile already loaded " + mTile + " " + mTile.state); + Log.d(TAG, "BUG tile already loaded " + mTile + " " + mTile.getState()); mTile = null; return false; } @@ -142,15 +139,6 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac // query database, which calls renderWay and renderPOI // callbacks while processing map tile data. if (mTileDataSource.executeQuery(mTile, this) != QueryResult.SUCCESS) { - - //Log.d(TAG, "Failed loading: " + tile); - mTile.layers.clear(); - mTile.layers = null; - TextItem.pool.releaseAll(mTile.labels); - mTile.labels = null; - // FIXME add STATE_FAILED? - // in passTile everything but STATE_LOADING is considered failed. - mTile.state = STATE_NONE; mTile = null; return false; } @@ -478,8 +466,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac it.y = mElement.points[1]; it.texRegion = symbol.texture; it.billboard = true; - - mTile.symbols = Inlist.push(mTile.symbols, it); + mTile.addSymbol(it); } @Override diff --git a/vtm/src/org/oscim/layers/tile/vector/labeling/TextRenderer.java b/vtm/src/org/oscim/layers/tile/vector/labeling/TextRenderer.java index bfe0b92e..6ee61b1b 100644 --- a/vtm/src/org/oscim/layers/tile/vector/labeling/TextRenderer.java +++ b/vtm/src/org/oscim/layers/tile/vector/labeling/TextRenderer.java @@ -403,7 +403,7 @@ class TextRenderer extends ElementRenderer { /* add way labels */ for (int i = 0, n = mTileSet.cnt; i < n; i++) { MapTile t = tiles[i]; - if (t.state != MapTile.STATE_READY) + if (!t.state(MapTile.STATE_READY)) continue; float dx = (float) (t.tileX * Tile.SIZE - tileX); @@ -469,7 +469,7 @@ class TextRenderer extends ElementRenderer { /* add caption */ for (int i = 0, n = mTileSet.cnt; i < n; i++) { MapTile t = tiles[i]; - if (t.state != MapTile.STATE_READY) + if (!t.state(MapTile.STATE_READY)) continue; float dx = (float) (t.tileX * Tile.SIZE - tileX); @@ -550,7 +550,7 @@ class TextRenderer extends ElementRenderer { for (int i = 0, n = mTileSet.cnt; i < n; i++) { MapTile t = tiles[i]; - if (t.state != MapTile.STATE_READY) + if (!t.state(MapTile.STATE_READY)) continue; float dx = (float) (t.tileX * Tile.SIZE - tileX); diff --git a/vtm/src/org/oscim/renderer/ExtrusionRenderer.java b/vtm/src/org/oscim/renderer/ExtrusionRenderer.java index f7ae114d..3efb7f90 100644 --- a/vtm/src/org/oscim/renderer/ExtrusionRenderer.java +++ b/vtm/src/org/oscim/renderer/ExtrusionRenderer.java @@ -139,7 +139,7 @@ public class ExtrusionRenderer extends LayerRenderer { for (int i = 0; i < mTileSet.cnt; i++) { MapTile t = tiles[i]; for (byte j = 0; j < 4; j++) { - if ((t.proxies & (1 << j)) == 0) + if (!t.hasProxy(1 << j)) continue; MapTile c = t.rel.get(j); @@ -168,7 +168,7 @@ public class ExtrusionRenderer extends LayerRenderer { private static ExtrusionLayer getLayer(MapTile t) { if (t.layers != null && t.layers.extrusionLayers != null - && t.state == MapTile.STATE_READY) + && t.state(MapTile.STATE_READY)) return (ExtrusionLayer) t.layers.extrusionLayers; return null; } diff --git a/vtm/src/org/oscim/tiling/MapTile.java b/vtm/src/org/oscim/tiling/MapTile.java index c6bd7836..0abaf826 100644 --- a/vtm/src/org/oscim/tiling/MapTile.java +++ b/vtm/src/org/oscim/tiling/MapTile.java @@ -19,41 +19,45 @@ import org.oscim.renderer.BufferObject; import org.oscim.renderer.elements.ElementLayers; import org.oscim.renderer.elements.SymbolItem; import org.oscim.renderer.elements.TextItem; +import org.oscim.utils.pool.Inlist; import org.oscim.utils.quadtree.QuadTree; /** * Extends Tile class to hold state and data for concurrent use in * TileManager (Main Thread), TileLoader (Worker Threads) and - * Rendering (GL Thread). + * TileRenderer (GL Thread). */ public class MapTile extends Tile { - public final static int STATE_NONE = 0; - + /** + * + * */ public TileLoader loader; + public final static byte STATE_NONE = 0; + /** * STATE_LOADING means the tile is about to be loaded / loading. - * it belongs to TileLoader thread. + * Tile belongs to TileLoader thread. */ - public final static int STATE_LOADING = 1 << 0; + public final static byte STATE_LOADING = 1 << 0; /** - * STATE_NEW_DATA: tile data is prepared for rendering. While - * 'locked' it belongs to GL Thread. + * STATE_NEW_DATA: tile data is prepared for rendering. + * While 'locked' it belongs to GL Thread. */ - public final static int STATE_NEW_DATA = 1 << 1; + public final static byte STATE_NEW_DATA = 1 << 1; /** - * STATE_READY: tile data is uploaded to GL.While - * 'locked' it belongs to GL Thread. + * STATE_READY: tile data is uploaded to GL. + * While 'locked' it belongs to GL Thread. */ - public final static int STATE_READY = 1 << 2; + public final static byte STATE_READY = 1 << 2; /** * TBD */ - public final static int STATE_ERROR = 1 << 3; + public final static byte STATE_ERROR = 1 << 3; /** * absolute tile coordinates: tileX,Y / Math.pow(2, zoomLevel) @@ -61,9 +65,6 @@ public class MapTile extends Tile { public double x; public double y; - /** STATE_* */ - public byte state; - /** * distance from map center */ @@ -75,9 +76,16 @@ public class MapTile extends Tile { */ public TextItem labels; public SymbolItem symbols; - public ElementLayers layers; + public void addLabel(TextItem it) { + labels = Inlist.push(labels, it); + } + + public void addSymbol(SymbolItem it) { + symbols = Inlist.push(symbols, it); + } + /** * Tile is in view region. Set by GLRenderer. */ @@ -102,8 +110,19 @@ 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 */ - public byte proxies; + byte proxies; /** counting the tiles that use this tile as proxy */ byte refs; @@ -122,12 +141,18 @@ public class MapTile extends Tile { } /** - * @return true when tile might be referenced by another thread. + * @return true when tile might be referenced by render thread. */ boolean isLocked() { return locked > 0 || refs > 0; } + /** + * Set this tile to be locked, i.e. to no be modified or cleared + * while rendering. Renderable parent, grand-parent and children + * will also be locked. Dont forget to unlock when tile is not longer + * used. This function should only be called through {@link TileManager} + */ void lock() { if (locked++ > 0) return; @@ -154,6 +179,9 @@ public class MapTile extends Tile { } } + /** + * Unlocks this tile when it cannot be used by render-thread. + */ void unlock() { if (--locked > 0 || proxies == 0) return; @@ -171,29 +199,27 @@ public class MapTile extends Tile { proxies = 0; } - public void addLabel(TextItem t) { - t.next = labels; - labels = t; - } - /** - * @return true if tile is loading, has new data or is ready for rendering + * @return true if tile is loading, has new data or is ready + * for rendering */ public boolean isActive() { return state > STATE_NONE && state < STATE_ERROR; } - public void setLoading() { - //if (state != STATE_NONE) - // Log.wtf(TAG, "wrong state: " + state); - - state = STATE_LOADING; - } - - public void clearState() { - state = STATE_NONE; + /** + * Test whether it is save to access a proxy item through + * this.rel.* + */ + public boolean hasProxy(int proxy) { + return (proxies & proxy) != 0; } + /** + * 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. + */ protected void clear() { if (layers != null) { // TODO move this to layers clear @@ -211,5 +237,7 @@ public class MapTile extends Tile { layers = null; labels = null; symbols = null; + + state = STATE_NONE; } } diff --git a/vtm/src/org/oscim/tiling/TileLoader.java b/vtm/src/org/oscim/tiling/TileLoader.java index a000bbd4..996b9bf3 100644 --- a/vtm/src/org/oscim/tiling/TileLoader.java +++ b/vtm/src/org/oscim/tiling/TileLoader.java @@ -32,8 +32,10 @@ public abstract class TileLoader extends PausableThread { protected abstract boolean executeJob(MapTile tile); - public void go(){ - notify(); + public void go() { + synchronized (this) { + notify(); + } } @Override @@ -43,18 +45,20 @@ public abstract class TileLoader extends PausableThread { if (tile == null) return; + boolean success = false; + try { - executeJob(tile); + success = executeJob(tile); } catch (Exception e) { e.printStackTrace(); return; } if (!isInterrupted()) { - // pass tile to main thread - mTileManager.passTile(tile); + mTileManager.passTile(tile, success); } } + public void jobCompleted(MapTile tile, boolean success) { } diff --git a/vtm/src/org/oscim/tiling/TileManager.java b/vtm/src/org/oscim/tiling/TileManager.java index 1718bfbc..e5d7bcae 100644 --- a/vtm/src/org/oscim/tiling/TileManager.java +++ b/vtm/src/org/oscim/tiling/TileManager.java @@ -528,14 +528,11 @@ public class TileManager { * Tile ready for upload in TileRenderLayer * @return caller does not care */ - public boolean passTile(MapTile tile) { + public void passTile(MapTile tile, boolean success) { - if (tile.state != STATE_LOADING) { - // - should rather be STATE_FAILED - // no one should be able to use this tile now, MapTileLoader passed - // it, GL-Thread does nothing until newdata is set. - // Log.d(TAG, "passTile: failed loading " + tile); - return true; + if (!success) { + tile.clear(); + return; } tile.state = STATE_NEW_DATA; @@ -547,8 +544,6 @@ public class TileManager { // a tile that might be visible. if (tile.isLocked()) mMap.render(); - - return true; } private final ScanBox mScanBox = new ScanBox() {