use BufferObject.loadBufferData
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user