use BufferObject.loadBufferData
This commit is contained in:
parent
8ac661d727
commit
b463ca7e3b
@ -31,10 +31,12 @@ public class TileRenderLayer extends RenderLayer {
|
||||
private final static String TAG = TileRenderLayer.class.getName();
|
||||
|
||||
private final TileManager mTileManager;
|
||||
private int mUploadSerial;
|
||||
|
||||
public TileRenderLayer(MapView mapView, TileManager tileManager) {
|
||||
super(mapView);
|
||||
mTileManager = tileManager;
|
||||
mUploadSerial = 0;
|
||||
}
|
||||
|
||||
boolean mFaded;
|
||||
@ -66,7 +68,10 @@ public class TileRenderLayer extends RenderLayer {
|
||||
tileCnt += mNumTileHolder;
|
||||
|
||||
/* prepare tile for rendering */
|
||||
compileTileLayers(tiles, tileCnt);
|
||||
if (compileTileLayers(tiles, tileCnt) > 0){
|
||||
mUploadSerial++;
|
||||
BufferObject.checkBufferUsage(false);
|
||||
}
|
||||
|
||||
TileRenderer.draw(tiles, tileCnt, pos, m, mFaded);
|
||||
}
|
||||
@ -103,14 +108,14 @@ public class TileRenderLayer extends RenderLayer {
|
||||
continue;
|
||||
|
||||
if (tile.state == STATE_NEW_DATA) {
|
||||
uploadTileData(tile);
|
||||
uploadCnt += uploadTileData(tile);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tile.holder != null) {
|
||||
// load tile that is referenced by this holder
|
||||
if (tile.holder.state == STATE_NEW_DATA)
|
||||
uploadTileData(tile.holder);
|
||||
uploadCnt += uploadTileData(tile.holder);
|
||||
|
||||
tile.state = tile.holder.state;
|
||||
continue;
|
||||
@ -120,7 +125,7 @@ public class TileRenderLayer extends RenderLayer {
|
||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||
MapTile rel = tile.rel.parent.item;
|
||||
if (rel.state == STATE_NEW_DATA)
|
||||
uploadTileData(rel);
|
||||
uploadCnt += uploadTileData(rel);
|
||||
|
||||
// dont load child proxies
|
||||
continue;
|
||||
@ -132,21 +137,17 @@ public class TileRenderLayer extends RenderLayer {
|
||||
|
||||
MapTile rel = tile.rel.get(i);
|
||||
if (rel != null && rel.state == STATE_NEW_DATA)
|
||||
uploadTileData(rel);
|
||||
uploadCnt += uploadTileData(rel);
|
||||
}
|
||||
}
|
||||
|
||||
if (uploadCnt > 0)
|
||||
GLRenderer.checkBufferUsage(false);
|
||||
|
||||
return uploadCnt;
|
||||
}
|
||||
|
||||
private static void uploadTileData(MapTile tile) {
|
||||
private static int uploadTileData(MapTile tile) {
|
||||
tile.state = STATE_READY;
|
||||
|
||||
if (tile.layers == null)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
int newSize = tile.layers.getSize();
|
||||
if (newSize > 0) {
|
||||
@ -161,8 +162,10 @@ public class TileRenderLayer extends RenderLayer {
|
||||
tile.layers.vbo = null;
|
||||
tile.layers.clear();
|
||||
tile.layers = null;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private final Object tilelock = new Object();
|
||||
@ -202,8 +205,10 @@ public class TileRenderLayer extends RenderLayer {
|
||||
}
|
||||
|
||||
// same tiles as before
|
||||
if (tileSet.serial == mDrawTiles.serial)
|
||||
return false;
|
||||
//if (tileSet.serial == mDrawTiles.serial)
|
||||
//return false;
|
||||
|
||||
int prevSerial = tileSet.serial;
|
||||
|
||||
// ensure tiles keep visible state
|
||||
synchronized (tilelock) {
|
||||
@ -229,8 +234,10 @@ public class TileRenderLayer extends RenderLayer {
|
||||
tileSet.tiles[tileSet.cnt++] = t;
|
||||
}
|
||||
}
|
||||
tileSet.serial = mUploadSerial;
|
||||
}
|
||||
return true;
|
||||
|
||||
return prevSerial != tileSet.serial;
|
||||
}
|
||||
|
||||
public void releaseTiles(TileSet td) {
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
package org.oscim.renderer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
import android.util.Log;
|
||||
@ -23,6 +23,11 @@ import android.util.Log;
|
||||
public final class BufferObject {
|
||||
private final static String TAG = BufferObject.class.getName();
|
||||
|
||||
private static final int MB = 1024 * 1024;
|
||||
private static final int LIMIT_BUFFERS = 16 * MB;
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// GL id
|
||||
public int id;
|
||||
|
||||
@ -35,16 +40,25 @@ public final class BufferObject {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void uploadArrayBuffer(ByteBuffer buf, int newSize, int type){
|
||||
int bufferType;
|
||||
|
||||
public void loadBufferData(ShortBuffer buf, int newSize, int type){
|
||||
boolean clear = false;
|
||||
|
||||
if (type != bufferType){
|
||||
if (bufferType != 0)
|
||||
clear = true;
|
||||
bufferType = type;
|
||||
}
|
||||
|
||||
GLES20.glBindBuffer(type, id);
|
||||
|
||||
// reuse memory allocated for vbo when possible and allocated
|
||||
// memory is less then four times the new data
|
||||
if (size > newSize && size < newSize * 4){
|
||||
if (!clear && (size > newSize) && (size < newSize * 4)){
|
||||
GLES20.glBufferSubData(type, 0, newSize, buf);
|
||||
} else {
|
||||
//mBufferMemoryUsage += newSize - layers.vbo.size;
|
||||
mBufferMemoryUsage += newSize - size;
|
||||
|
||||
size = newSize;
|
||||
|
||||
@ -61,6 +75,21 @@ public final class BufferObject {
|
||||
}
|
||||
|
||||
// ---------------------------- pool ----------------------------
|
||||
// bytes currently loaded in VBOs
|
||||
private static int mBufferMemoryUsage;
|
||||
|
||||
public static void checkBufferUsage(boolean force) {
|
||||
// try to clear some unused vbo when exceding limit
|
||||
if (mBufferMemoryUsage < LIMIT_BUFFERS)
|
||||
return;
|
||||
|
||||
Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / MB + "MB");
|
||||
|
||||
mBufferMemoryUsage -= BufferObject.limitUsage(1024*1024);
|
||||
|
||||
Log.d(TAG, "now: " + mBufferMemoryUsage / MB + "MB");
|
||||
}
|
||||
|
||||
private static BufferObject pool;
|
||||
static int counter = 0;
|
||||
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
package org.oscim.renderer;
|
||||
|
||||
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
||||
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;
|
||||
|
||||
@ -53,7 +52,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
private static final int MB = 1024 * 1024;
|
||||
private static final int SHORT_BYTES = 2;
|
||||
private static final int CACHE_TILES_MAX = 250;
|
||||
private static final int LIMIT_BUFFERS = 16 * MB;
|
||||
|
||||
|
||||
public static final float COORD_SCALE = 8.0f;
|
||||
|
||||
@ -71,9 +70,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
|
||||
private static short[] mFillCoords;
|
||||
|
||||
// bytes currently loaded in VBOs
|
||||
private static int mBufferMemoryUsage;
|
||||
|
||||
public class Matrices {
|
||||
// do not modify any of these
|
||||
public final Matrix4 viewproj = new Matrix4();
|
||||
@ -98,11 +94,8 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
(-screenWidth / 2) * ratio * scale,
|
||||
(-screenHeight / 2) * ratio * scale,
|
||||
ratio);
|
||||
//
|
||||
// mvp.setTransScale(-screenWidth / ratio,
|
||||
// screenHeight / ratio, ratio);
|
||||
|
||||
mvp.multiplyMM(proj, mvp);
|
||||
mvp.multiplyLhs(proj);
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,41 +206,10 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
}
|
||||
newSize *= SHORT_BYTES;
|
||||
|
||||
GLES20.glBindBuffer(GL_ARRAY_BUFFER, layers.vbo.id);
|
||||
|
||||
// reuse memory allocated for vbo when possible and allocated
|
||||
// memory is less then four times the new data
|
||||
if (layers.vbo.size > newSize && layers.vbo.size < newSize * 4
|
||||
&& mBufferMemoryUsage < LIMIT_BUFFERS) {
|
||||
GLES20.glBufferSubData(GL_ARRAY_BUFFER, 0, newSize, sbuf);
|
||||
} else {
|
||||
mBufferMemoryUsage += newSize - layers.vbo.size;
|
||||
layers.vbo.size = newSize;
|
||||
GLES20.glBufferData(GL_ARRAY_BUFFER, layers.vbo.size, sbuf, GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
layers.vbo.loadBufferData(sbuf, newSize, GL_ARRAY_BUFFER);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void checkBufferUsage(boolean force) {
|
||||
// try to clear some unused vbo when exceding limit
|
||||
|
||||
if (!force && mBufferMemoryUsage < LIMIT_BUFFERS) {
|
||||
if (CACHE_TILES < CACHE_TILES_MAX)
|
||||
CACHE_TILES += 50;
|
||||
return;
|
||||
}
|
||||
|
||||
Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / MB + "MB");
|
||||
|
||||
mBufferMemoryUsage -= BufferObject.limitUsage(2 * MB);
|
||||
|
||||
Log.d(TAG, "now: " + mBufferMemoryUsage / MB + "MB");
|
||||
|
||||
if (mBufferMemoryUsage > LIMIT_BUFFERS && CACHE_TILES > 100)
|
||||
CACHE_TILES -= 50;
|
||||
}
|
||||
|
||||
private long lastDraw = 0;
|
||||
|
||||
@Override
|
||||
@ -303,11 +265,11 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
if (changed)
|
||||
mMapViewPosition.getMapViewProjection(mMatrices.mapPlane);
|
||||
|
||||
mMapViewPosition.getMatrix(mMatrices.view, null, mMatrices.viewproj);
|
||||
mMapViewPosition.getMatrix(mMatrices.view, mMatrices.proj, mMatrices.viewproj);
|
||||
|
||||
if (debugView) {
|
||||
mMatrices.mvp.setScale(0.5f, 0.5f, 1);
|
||||
mMatrices.viewproj.multiplyMM(mMatrices.mvp, mMatrices.viewproj);
|
||||
mMatrices.viewproj.multiplyLhs(mMatrices.mvp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,7 +298,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
}
|
||||
|
||||
if (GlUtils.checkGlOutOfMemory("finish")) {
|
||||
checkBufferUsage(true);
|
||||
BufferObject.checkBufferUsage(true);
|
||||
// TODO also throw out some textures etc
|
||||
}
|
||||
}
|
||||
@ -361,7 +323,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
// modify this to scale only the view, to see better which tiles
|
||||
// are rendered
|
||||
mMatrices.mvp.setScale(0.5f, 0.5f, 1);
|
||||
mMatrices.proj.multiplyMM(mMatrices.mvp, mMatrices.proj);
|
||||
mMatrices.proj.multiplyLhs(mMatrices.mvp);
|
||||
}
|
||||
|
||||
GLES20.glViewport(0, 0, width, height);
|
||||
@ -373,10 +335,13 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
||||
GLES20.glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
//mBufferMemoryUsage = 0;
|
||||
|
||||
if (!mNewSurface) {
|
||||
mMapView.redrawMap(false);
|
||||
return;
|
||||
}
|
||||
|
||||
mNewSurface = false;
|
||||
|
||||
// set initial temp buffer size
|
||||
@ -407,16 +372,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
indices.length * 2, shortBuffer, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
mBufferMemoryUsage = 0;
|
||||
//mDrawTiles = null;
|
||||
|
||||
int numTiles = (screenWidth / (Tile.SIZE / 2) + 2)
|
||||
* (screenHeight / (Tile.SIZE / 2) + 2);
|
||||
|
||||
// Set up vertex buffer objects
|
||||
int numVBO = (CACHE_TILES + (numTiles * 2));
|
||||
BufferObject.init(numVBO);
|
||||
|
||||
if (mClearColor != null)
|
||||
mUpdateColor = true;
|
||||
|
||||
@ -432,6 +387,9 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
// classes that require GL context for initialization
|
||||
Layers.initRenderer();
|
||||
|
||||
// Set up some vertex buffer objects
|
||||
BufferObject.init(CACHE_TILES);
|
||||
|
||||
mNewSurface = true;
|
||||
}
|
||||
|
||||
|
||||
@ -99,7 +99,7 @@ public abstract class BasicRenderLayer extends RenderLayer {
|
||||
@Override
|
||||
public void compile() {
|
||||
int newSize = layers.getSize();
|
||||
if (newSize == 0) {
|
||||
if (newSize <= 0) {
|
||||
BufferObject.release(layers.vbo);
|
||||
layers.vbo = null;
|
||||
isReady = false;
|
||||
@ -107,15 +107,13 @@ public abstract class BasicRenderLayer extends RenderLayer {
|
||||
}
|
||||
|
||||
if (layers.vbo == null) {
|
||||
layers.vbo = BufferObject.get(0);
|
||||
layers.vbo = BufferObject.get(newSize);
|
||||
|
||||
if (layers.vbo == null)
|
||||
return;
|
||||
}
|
||||
|
||||
if (newSize > 0) {
|
||||
if (GLRenderer.uploadLayers(layers, newSize, true))
|
||||
isReady = true;
|
||||
}
|
||||
if (GLRenderer.uploadLayers(layers, newSize, true))
|
||||
isReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,12 +387,6 @@ public class ExtrusionLayer extends Layer {
|
||||
if (mNumVertices == 0 || compiled)
|
||||
return;
|
||||
|
||||
vboVertices = BufferObject.get(0);
|
||||
vboIndices = BufferObject.get(0);
|
||||
|
||||
// upload indices
|
||||
//sbuf.clear();
|
||||
|
||||
mNumIndices = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (VertexItem vi = mIndices[i]; vi != null; vi = vi.next) {
|
||||
@ -403,10 +397,9 @@ public class ExtrusionLayer extends Layer {
|
||||
}
|
||||
|
||||
sbuf.flip();
|
||||
vboIndices.size = mNumIndices * 2;
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, vboIndices.id);
|
||||
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER,
|
||||
vboIndices.size, sbuf, GLES20.GL_DYNAMIC_DRAW);
|
||||
int size = mNumIndices*2;
|
||||
vboIndices = BufferObject.get(size);
|
||||
vboIndices.loadBufferData(sbuf,size, GLES20.GL_ELEMENT_ARRAY_BUFFER);
|
||||
|
||||
// upload vertices
|
||||
sbuf.clear();
|
||||
@ -414,10 +407,9 @@ public class ExtrusionLayer extends Layer {
|
||||
sbuf.put(vi.vertices, 0, vi.used);
|
||||
|
||||
sbuf.flip();
|
||||
vboVertices.size = mNumVertices * 4 * 2;
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboVertices.id);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,
|
||||
vboVertices.size, sbuf, GLES20.GL_DYNAMIC_DRAW);
|
||||
size = mNumVertices * 4 * 2;
|
||||
vboVertices = BufferObject.get(size);
|
||||
vboVertices.loadBufferData(sbuf, size, GLES20.GL_ARRAY_BUFFER);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user