keep tile loading state in JobTile.state
This commit is contained in:
parent
60637f7440
commit
a8b25d07ad
@ -41,7 +41,8 @@ public class JobQueue {
|
||||
|
||||
for (int i = 0, n = tiles.size(); i < n; i++) {
|
||||
JobTile tile = tiles.get(i);
|
||||
tile.isLoading = true;
|
||||
//tile.isLoading = true;
|
||||
tile.state = JobTile.STATE_LOADING;
|
||||
mPriorityQueue.offer(tile);
|
||||
}
|
||||
}
|
||||
@ -50,10 +51,10 @@ public class JobQueue {
|
||||
* Removes all jobs from this queue.
|
||||
*/
|
||||
public synchronized void clear() {
|
||||
|
||||
JobTile t;
|
||||
while ((t = mPriorityQueue.poll()) != null)
|
||||
t.isLoading = false;
|
||||
t.state = JobTile.STATE_NONE;
|
||||
//t.isLoading = false;
|
||||
|
||||
mPriorityQueue.clear();
|
||||
}
|
||||
|
@ -16,10 +16,13 @@ package org.oscim.generator;
|
||||
|
||||
import org.oscim.core.Tile;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class JobTile extends Tile implements Comparable<JobTile> {
|
||||
private final static String TAG = JobTile.class.getName();
|
||||
// public final static int LOADING = 1;
|
||||
// public final static int NEWDATA = 1 << 1;
|
||||
// public final static int READY = 1 << 2;
|
||||
@ -27,10 +30,27 @@ public class JobTile extends Tile implements Comparable<JobTile> {
|
||||
// public final static int CANCELED = 1 << 3;
|
||||
// public int state;
|
||||
|
||||
public final static int STATE_NONE = 0;
|
||||
public final static int STATE_LOADING = 1 << 0;
|
||||
public final static int STATE_NEW_DATA = 1 << 1;
|
||||
public final static int STATE_READY = 1 << 2;
|
||||
|
||||
public void clearState() {
|
||||
state = STATE_NONE;
|
||||
}
|
||||
|
||||
public void setLoading() {
|
||||
if (state != STATE_NONE)
|
||||
Log.d(TAG, "wrong state: " + state);
|
||||
|
||||
state = STATE_LOADING;
|
||||
}
|
||||
|
||||
/**
|
||||
* tile is in JobQueue
|
||||
*/
|
||||
public boolean isLoading;
|
||||
//public boolean isLoading;
|
||||
public byte state;
|
||||
|
||||
/**
|
||||
* distance from map center.
|
||||
|
@ -21,6 +21,8 @@ import static android.opengl.GLES20.GL_DYNAMIC_DRAW;
|
||||
import static android.opengl.GLES20.GL_ONE;
|
||||
import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA;
|
||||
import static android.opengl.GLES20.GL_POLYGON_OFFSET_FILL;
|
||||
import static org.oscim.generator.JobTile.STATE_NEW_DATA;
|
||||
import static org.oscim.generator.JobTile.STATE_READY;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@ -166,6 +168,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
holder = new MapTile(x, y, mZoom);
|
||||
holder.isVisible = true;
|
||||
holder.holder = tile;
|
||||
tile.isVisible = true;
|
||||
tiles[cnt + mHolderCount++] = holder;
|
||||
}
|
||||
}
|
||||
@ -281,20 +284,19 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean uploadTileData(MapTile tile) {
|
||||
if (tile.layers != null) {
|
||||
tile.isReady = uploadLayers(tile.layers, tile.vbo, true);
|
||||
|
||||
if (!tile.isReady) {
|
||||
Log.d(TAG, "uploadTileData " + tile + " is empty!");
|
||||
private static void uploadTileData(MapTile tile) {
|
||||
if (tile.layers == null) {
|
||||
BufferObject.release(tile.vbo);
|
||||
tile.vbo = null;
|
||||
} else if (!uploadLayers(tile.layers, tile.vbo, true)) {
|
||||
Log.d(TAG, "uploadTileData " + tile + " failed!");
|
||||
tile.layers.clear();
|
||||
tile.layers = null;
|
||||
BufferObject.release(tile.vbo);
|
||||
tile.vbo = null;
|
||||
}
|
||||
}
|
||||
tile.newData = false;
|
||||
// Log.d(TAG, "uploaded " + tile.isReady + " " + tile);
|
||||
|
||||
return tile.isReady;
|
||||
tile.state = STATE_READY;
|
||||
}
|
||||
|
||||
private static boolean uploadOverlayData(RenderOverlay renderOverlay) {
|
||||
@ -307,10 +309,10 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
return renderOverlay.isReady;
|
||||
}
|
||||
|
||||
private static void checkBufferUsage() {
|
||||
private static void checkBufferUsage(boolean force) {
|
||||
// try to clear some unused vbo when exceding limit
|
||||
|
||||
if (mBufferMemoryUsage < LIMIT_BUFFERS) {
|
||||
if (!force && mBufferMemoryUsage < LIMIT_BUFFERS) {
|
||||
if (CACHE_TILES < CACHE_TILES_MAX)
|
||||
CACHE_TILES += 50;
|
||||
return;
|
||||
@ -457,23 +459,23 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
if (!tile.isVisible)
|
||||
continue;
|
||||
|
||||
if (tile.newData) {
|
||||
if (tile.state == STATE_NEW_DATA) {
|
||||
uploadTileData(tile);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tile.holder != null) {
|
||||
// load tile that is referenced by this holder
|
||||
if (tile.holder.newData)
|
||||
if (tile.holder.state == STATE_NEW_DATA)
|
||||
uploadTileData(tile.holder);
|
||||
|
||||
tile.isReady = tile.holder.isReady;
|
||||
tile.state = tile.holder.state;
|
||||
|
||||
} else if (!tile.isReady) {
|
||||
} else if (tile.state != STATE_READY) {
|
||||
// check near relatives than can serve as proxy
|
||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||
MapTile rel = tile.rel.parent.tile;
|
||||
if (rel.newData)
|
||||
if (rel.state == STATE_NEW_DATA)
|
||||
uploadTileData(rel);
|
||||
|
||||
continue;
|
||||
@ -483,14 +485,14 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
continue;
|
||||
|
||||
MapTile rel = tile.rel.child[c].tile;
|
||||
if (rel != null && rel.newData)
|
||||
if (rel != null && rel.state == STATE_NEW_DATA)
|
||||
uploadTileData(rel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uploadCnt > 0)
|
||||
checkBufferUsage();
|
||||
checkBufferUsage(false);
|
||||
|
||||
tilesChanged |= (uploadCnt > 0);
|
||||
|
||||
@ -507,7 +509,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
MapTile t = tiles[i];
|
||||
if (t.isVisible && t.isReady)
|
||||
if (t.isVisible && t.state == STATE_READY)
|
||||
drawTile(t);
|
||||
}
|
||||
|
||||
@ -517,7 +519,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
// TODO draw proxies for placeholder...
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
MapTile t = tiles[i];
|
||||
if (t.isVisible && !t.isReady && (t.holder == null))
|
||||
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null))
|
||||
drawProxyTile(t);
|
||||
}
|
||||
|
||||
@ -577,6 +579,11 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
mapPosition.viewMatrix, 0);
|
||||
PolygonRenderer.debugDraw(mMVPMatrix, mDebugCoords, 1);
|
||||
}
|
||||
|
||||
if (GlUtils.checkGlOutOfMemory("finish")) {
|
||||
checkBufferUsage(true);
|
||||
// TODO also throw out some textures etc
|
||||
}
|
||||
}
|
||||
|
||||
// used to not draw a tile twice per frame.
|
||||
@ -598,6 +605,9 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
if (tile.holder != null)
|
||||
tile = tile.holder;
|
||||
|
||||
if (tile.layers == null)
|
||||
return;
|
||||
|
||||
GLES20.glPolygonOffset(0, mDrawCount++);
|
||||
|
||||
// seems there are not infinite offset units possible
|
||||
@ -652,7 +662,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
|
||||
MapTile c = tile.rel.child[i].tile;
|
||||
|
||||
if (c.isReady) {
|
||||
if (c.state == STATE_READY) {
|
||||
drawTile(c);
|
||||
drawn++;
|
||||
}
|
||||
@ -669,7 +679,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
if (!drawProxyChild(tile)) {
|
||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||
MapTile t = tile.rel.parent.tile;
|
||||
if (t.isReady) {
|
||||
if (t.state == STATE_READY) {
|
||||
drawTile(t);
|
||||
drawn = true;
|
||||
}
|
||||
@ -677,7 +687,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
|
||||
if (!drawn && (tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
||||
MapTile t = tile.rel.parent.parent.tile;
|
||||
if (t.isReady)
|
||||
if (t.state == STATE_READY)
|
||||
drawTile(t);
|
||||
|
||||
}
|
||||
@ -686,14 +696,14 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
// prefer drawing parent
|
||||
MapTile t = tile.rel.parent.tile;
|
||||
|
||||
if (t != null && t.isReady) {
|
||||
if (t != null && t.state == STATE_READY) {
|
||||
drawTile(t);
|
||||
|
||||
} else if (!drawProxyChild(tile)) {
|
||||
|
||||
if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
||||
t = tile.rel.parent.parent.tile;
|
||||
if (t.isReady)
|
||||
if (t.state == STATE_READY)
|
||||
drawTile(t);
|
||||
}
|
||||
}
|
||||
@ -789,4 +799,33 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
void clearBuffer() {
|
||||
mNewSurface = true;
|
||||
}
|
||||
|
||||
public static void enableVertexArrays(int va1, int va2) {
|
||||
if (va1 > 1 || va2 > 1)
|
||||
Log.d(TAG, "FIXME: enableVertexArrays...");
|
||||
|
||||
if ((va1 == 0 || va2 == 0)) {
|
||||
if (!vertexArray[0]) {
|
||||
GLES20.glEnableVertexAttribArray(0);
|
||||
vertexArray[0] = true;
|
||||
}
|
||||
} else {
|
||||
if (vertexArray[0]) {
|
||||
GLES20.glDisableVertexAttribArray(0);
|
||||
vertexArray[0] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((va1 == 1 || va2 == 1)) {
|
||||
if (!vertexArray[1]) {
|
||||
GLES20.glEnableVertexAttribArray(1);
|
||||
vertexArray[1] = true;
|
||||
}
|
||||
} else {
|
||||
if (vertexArray[1]) {
|
||||
GLES20.glDisableVertexAttribArray(1);
|
||||
vertexArray[1] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,12 +37,12 @@ public final class MapTile extends JobTile {
|
||||
/**
|
||||
* tile has new data to upload to gl
|
||||
*/
|
||||
boolean newData;
|
||||
//boolean newData;
|
||||
|
||||
/**
|
||||
* tile is loaded and ready for drawing.
|
||||
*/
|
||||
boolean isReady;
|
||||
//boolean isReady;
|
||||
|
||||
/**
|
||||
* tile is in view region.
|
||||
@ -80,7 +80,7 @@ public final class MapTile extends JobTile {
|
||||
}
|
||||
|
||||
boolean isActive() {
|
||||
return isLoading || newData || isReady;
|
||||
return state != 0;
|
||||
}
|
||||
|
||||
boolean isLocked() {
|
||||
@ -91,18 +91,22 @@ public final class MapTile extends JobTile {
|
||||
|
||||
locked++;
|
||||
|
||||
if (locked > 1 || isReady || newData)
|
||||
if (locked > 1)
|
||||
return;
|
||||
|
||||
//if (isReady || newData)
|
||||
// return;
|
||||
|
||||
MapTile p = rel.parent.tile;
|
||||
|
||||
if (p != null && (p.isReady || p.newData || p.isLoading)) {
|
||||
if (p != null && (p.state != 0)) {
|
||||
proxies |= PROXY_PARENT;
|
||||
p.refs++;
|
||||
}
|
||||
|
||||
// FIXME handle root-tile case?
|
||||
p = rel.parent.parent.tile;
|
||||
if (p != null && (p.isReady || p.newData || p.isLoading)) {
|
||||
if (p != null && (p.state != 0)) {
|
||||
proxies |= PROXY_GRAMPA;
|
||||
p.refs++;
|
||||
}
|
||||
@ -110,7 +114,7 @@ public final class MapTile extends JobTile {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (rel.child[j] != null) {
|
||||
p = rel.child[j].tile;
|
||||
if (p != null && (p.isReady || p.newData || p.isLoading)) {
|
||||
if (p != null && (p.state != 0)) {
|
||||
proxies |= (1 << j);
|
||||
p.refs++;
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
*/
|
||||
package org.oscim.renderer;
|
||||
|
||||
import static org.oscim.generator.JobTile.STATE_NONE;
|
||||
|
||||
import org.oscim.core.MercatorProjection;
|
||||
import org.oscim.core.Tag;
|
||||
import org.oscim.core.Tile;
|
||||
@ -38,7 +40,6 @@ import org.oscim.view.MapView;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Paint;
|
||||
import android.util.FloatMath;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
@ -395,13 +396,10 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
||||
mDebugDrawPolygons = !debugSettings.mDisablePolygons;
|
||||
mDebugDrawUnmatched = debugSettings.mDrawUnmatchted;
|
||||
|
||||
if (tile.newData || tile.isReady || tile.layers != null) {
|
||||
if (tile.layers != null) {
|
||||
// should be fixed now.
|
||||
Log.d(TAG, "XXX tile already loaded "
|
||||
+ tile + " "
|
||||
+ tile.newData + " "
|
||||
+ tile.isReady + " "
|
||||
+ tile.isLoading);
|
||||
+ tile + " " + tile.state);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -415,8 +413,8 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
||||
|
||||
// acount for area changes with latitude
|
||||
mProjectionScaleFactor = 0.5f + 0.5f * (
|
||||
FloatMath.sin((float) (Math.abs(MercatorProjection
|
||||
.pixelYToLatitude(tile.pixelY, tile.zoomLevel)) * (Math.PI / 180))));
|
||||
(float) Math.sin(Math.abs(MercatorProjection
|
||||
.pixelYToLatitude(tile.pixelY, tile.zoomLevel)) * (Math.PI / 180)));
|
||||
|
||||
mLayers = new Layers();
|
||||
|
||||
@ -426,7 +424,9 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
||||
mLayers = null;
|
||||
mLabels = null;
|
||||
mCurLineLayer = null;
|
||||
tile.isLoading = false;
|
||||
|
||||
// FIXME add STATE_FAILED?
|
||||
tile.state = STATE_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 Hannes Janetzek
|
||||
* Copyright 2012 OpenScienceMap
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
@ -12,8 +12,14 @@
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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.Collections;
|
||||
|
||||
@ -25,9 +31,11 @@ import org.oscim.renderer.layer.VertexPool;
|
||||
import org.oscim.view.MapView;
|
||||
import org.oscim.view.MapViewPosition;
|
||||
|
||||
import android.util.FloatMath;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @author Hannes Janetzek
|
||||
*/
|
||||
public class TileManager {
|
||||
static final String TAG = TileManager.class.getSimpleName();
|
||||
|
||||
@ -266,11 +274,7 @@ public class TileManager {
|
||||
td = new TileSet(newTiles.length);
|
||||
mTileSets.add(td);
|
||||
}
|
||||
// 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;
|
||||
|
||||
// unlock previously active tiles
|
||||
@ -442,9 +446,7 @@ public class TileManager {
|
||||
|
||||
private static void clearTile(MapTile t) {
|
||||
|
||||
t.newData = false;
|
||||
t.isLoading = false;
|
||||
t.isReady = false;
|
||||
t.state = STATE_NONE;
|
||||
|
||||
if (t.layers != null) {
|
||||
t.layers.clear();
|
||||
@ -486,7 +488,7 @@ public class TileManager {
|
||||
dx %= center;
|
||||
dy %= center;
|
||||
//t.distance = ((dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy)) * 0.25f;
|
||||
t.distance = FloatMath.sqrt((dx * dx + dy * dy)) * 0.25f;
|
||||
t.distance = (float) Math.sqrt((dx * dx + dy * dy)) * 0.25f;
|
||||
} else if (diff > 0) {
|
||||
// tile zoom level is child of current
|
||||
|
||||
@ -501,7 +503,7 @@ public class TileManager {
|
||||
dx %= center;
|
||||
dy %= center;
|
||||
//t.distance = ((dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy));
|
||||
t.distance = FloatMath.sqrt((dx * dx + dy * dy));
|
||||
t.distance = (float) Math.sqrt((dx * dx + dy * dy));
|
||||
|
||||
} else {
|
||||
// tile zoom level is parent of current
|
||||
@ -510,7 +512,7 @@ public class TileManager {
|
||||
dx %= center;
|
||||
dy %= center;
|
||||
//t.distance = ((dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy)) * (-diff * 0.5f);
|
||||
t.distance = FloatMath.sqrt((dx * dx + dy * dy)) * (-diff * 0.5f);
|
||||
t.distance = (float) Math.sqrt((dx * dx + dy * dy)) * (-diff * 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -545,7 +547,7 @@ public class TileManager {
|
||||
// dont remove tile used by GLRenderer, or somewhere else
|
||||
Log.d(TAG, "limitCache: tile still locked " + t + " " + t.distance);
|
||||
mTiles.add(t);
|
||||
} else if (t.isLoading) {
|
||||
} 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()
|
||||
@ -573,8 +575,8 @@ public class TileManager {
|
||||
// remove tiles already uploaded to vbo
|
||||
for (int i = 0; i < size;) {
|
||||
MapTile t = mTilesLoaded.get(i);
|
||||
// t.rel == null means tile was removed in limitCache
|
||||
if (!t.newData || t.rel == null) {
|
||||
// t.rel == null means tile was removed in limitCache -- but then newdata is false anyway?
|
||||
if (t.state == STATE_READY || t.state == STATE_NONE) {// || t.rel == null) {
|
||||
mTilesLoaded.remove(i);
|
||||
size--;
|
||||
continue;
|
||||
@ -614,7 +616,7 @@ public class TileManager {
|
||||
public synchronized boolean passTile(JobTile jobTile) {
|
||||
MapTile tile = (MapTile) jobTile;
|
||||
|
||||
if (!tile.isLoading) {
|
||||
if (tile.state != STATE_LOADING) {
|
||||
// no one should be able to use this tile now, TileGenerator passed
|
||||
// it, GL-Thread does nothing until newdata is set.
|
||||
//Log.d(TAG, "passTile: failed loading " + tile);
|
||||
@ -631,12 +633,15 @@ public class TileManager {
|
||||
|
||||
if (tile.vbo == null) {
|
||||
Log.d(TAG, "no VBOs left for " + tile);
|
||||
tile.isLoading = false;
|
||||
//tile.isLoading = false;
|
||||
clearTile(tile);
|
||||
return true;
|
||||
}
|
||||
|
||||
tile.newData = true;
|
||||
tile.isLoading = false;
|
||||
tile.state = STATE_NEW_DATA;
|
||||
|
||||
//tile.newData = true;
|
||||
//tile.isLoading = false;
|
||||
|
||||
mMapView.render();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user