share one native ByteBuffer in GLThread

This commit is contained in:
Hannes Janetzek 2013-04-29 05:49:40 +02:00
parent 8bea920253
commit 42bd0661c1
4 changed files with 107 additions and 73 deletions

View File

@ -15,6 +15,8 @@
package org.oscim.renderer;
import java.nio.ByteBuffer;
import android.opengl.GLES20;
import android.util.Log;
@ -33,6 +35,23 @@ public final class BufferObject {
this.id = id;
}
public void uploadArrayBuffer(ByteBuffer buf, int newSize, int 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){
GLES20.glBufferSubData(type, 0, newSize, buf);
} else {
//mBufferMemoryUsage += newSize - layers.vbo.size;
size = newSize;
GLES20.glBufferData(type, size, buf, GLES20.GL_DYNAMIC_DRAW);
}
}
// ---------------------------- pool ----------------------------
private static BufferObject pool;
static int counter = 0;

View File

@ -21,6 +21,7 @@ import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.concurrent.locks.ReentrantLock;
@ -65,6 +66,9 @@ public class GLRenderer implements GLSurfaceView.Renderer {
private static MapPosition mMapPosition;
private static ShortBuffer shortBuffer;
private static FloatBuffer floatBuffer;
private static int tmpBufferSize;
private static short[] mFillCoords;
// bytes currently loaded in VBOs
@ -128,27 +132,51 @@ public class GLRenderer implements GLSurfaceView.Renderer {
mUpdateColor = true;
}
/**
* Only use on GL Thread!
* Get a native ShortBuffer for temporary use.
*/
public static ShortBuffer getShortBuffer(int size) {
if (tmpBufferSize < size * 2)
growBuffer(size * 2);
else
shortBuffer.clear();
return shortBuffer;
}
/**
* Only use on GL Thread!
* Get a native FloatBuffer for temporary use.
*/
public static FloatBuffer getFloatBuffer(int size) {
if (tmpBufferSize < size * 4)
growBuffer(size * 4);
else
floatBuffer.clear();
return floatBuffer;
}
private static void growBuffer(int size) {
Log.d(TAG, "grow buffer " + size);
ByteBuffer buf = ByteBuffer
.allocateDirect(size)
.order(ByteOrder.nativeOrder());
floatBuffer = buf.asFloatBuffer();
shortBuffer = buf.asShortBuffer();
tmpBufferSize = size;
}
public static boolean uploadLayers(Layers layers, int newSize,
boolean addFill) {
GLES20.glBindBuffer(GL_ARRAY_BUFFER, layers.vbo.id);
// add fill coordinates
if (addFill)
newSize += 8;
ShortBuffer sbuf = shortBuffer;
if (sbuf.capacity() < newSize) {
shortBuffer = sbuf = ByteBuffer
.allocateDirect(newSize * SHORT_BYTES)
.order(ByteOrder.nativeOrder())
.asShortBuffer();
} else {
sbuf.clear();
// if (addFill)
// sbuf.position(8);
}
ShortBuffer sbuf = getShortBuffer(newSize);
if (addFill)
sbuf.put(mFillCoords, 0, 8);
@ -166,6 +194,8 @@ 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
@ -222,8 +252,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
}
}
private static void draw() {
long start = 0;
@ -264,7 +292,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
}
}
/* update layers*/
/* update layers */
RenderLayer[] overlays = mMapView.getLayerManager().getRenderLayers();
for (int i = 0, n = overlays.length; i < n; i++)
@ -332,9 +360,8 @@ public class GLRenderer implements GLSurfaceView.Renderer {
}
mNewSurface = false;
ByteBuffer bbuf = ByteBuffer.allocateDirect(MB >> 2)
.order(ByteOrder.nativeOrder());
shortBuffer = bbuf.asShortBuffer();
// set initial temp buffer size
growBuffer(MB >> 2);
// upload quad indices used by Texture- and LineTexRenderer
int[] vboIds = new int[1];

View File

@ -37,9 +37,10 @@ import android.util.Log;
public class ExtrusionLayer extends Layer {
private final static String TAG = ExtrusionLayer.class.getName();
private static final float S = GLRenderer.COORD_SCALE;
private final VertexItem mVertices;
private VertexItem mVertices;
private VertexItem mCurVertices;
private final VertexItem mIndices[], mCurIndices[];
private VertexItem mIndices[];
private final VertexItem mCurIndices[];
private LineClipper mClipper;
// indices for:
@ -48,10 +49,8 @@ public class ExtrusionLayer extends Layer {
public int mNumIndices = 0;
public int mNumVertices = 0;
public int mIndicesBufferID;
public int mVertexBufferID;
private BufferObject mIndiceBO;
private BufferObject mVertexBO;
public BufferObject vboIndices;
public BufferObject vboVertices;
//private final static int IND_EVEN_SIDE = 0;
//private final static int IND_ODD_SIDE = 1;
@ -154,7 +153,7 @@ public class ExtrusionLayer extends Layer {
if (simpleOutline && (convex || len <= 8))
addRoofSimple(startVertex, len);
else if (!complexOutline) {
else if (!complexOutline) {
complexOutline = true;
// keep start postion of polygon and defer roof building
// as it modifies the geometry array.
@ -387,13 +386,12 @@ public class ExtrusionLayer extends Layer {
if (mNumVertices == 0 || compiled)
return;
mVertexBO = BufferObject.get(0);
mIndiceBO = BufferObject.get(0);
mIndicesBufferID = mIndiceBO.id;
mVertexBufferID = mVertexBO.id;
vboVertices = BufferObject.get(0);
vboIndices = BufferObject.get(0);
// upload indices
sbuf.clear();
//sbuf.clear();
mNumIndices = 0;
for (int i = 0; i < 4; i++) {
for (VertexItem vi = mIndices[i]; vi != null; vi = vi.next) {
@ -404,10 +402,10 @@ public class ExtrusionLayer extends Layer {
}
sbuf.flip();
mIndiceBO.size = mNumIndices * 2;
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
vboIndices.size = mNumIndices * 2;
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, vboIndices.id);
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER,
mIndiceBO.size, sbuf, GLES20.GL_DYNAMIC_DRAW);
vboIndices.size, sbuf, GLES20.GL_DYNAMIC_DRAW);
// upload vertices
sbuf.clear();
@ -415,19 +413,21 @@ public class ExtrusionLayer extends Layer {
sbuf.put(vi.vertices, 0, vi.used);
sbuf.flip();
mVertexBO.size = mNumVertices * 4 * 2;
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
vboVertices.size = mNumVertices * 4 * 2;
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboVertices.id);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,
mVertexBO.size, sbuf, GLES20.GL_DYNAMIC_DRAW);
vboVertices.size, sbuf, GLES20.GL_DYNAMIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
for (VertexItem i : mIndices)
VertexItem.pool.releaseAll(i);
for (int i = 0; i < 4; i++)
VertexItem.pool.releaseAll(mIndices[i]);
VertexItem.pool.releaseAll(mVertices);
mIndices = null;
mVertices = null;
mClipper = null;
compiled = true;
@ -436,15 +436,17 @@ public class ExtrusionLayer extends Layer {
@Override
protected void clear() {
if (compiled) {
BufferObject.release(mIndiceBO);
BufferObject.release(mVertexBO);
mIndiceBO = null;
mVertexBO = null;
//GLES20.glDeleteBuffers(2, mVboIds, 0);
BufferObject.release(vboIndices);
BufferObject.release(vboVertices);
vboIndices = null;
vboVertices = null;
} else {
for (int i = 0; i < 4; i++)
VertexItem.pool.releaseAll(mIndices[i]);
mIndices = null;
VertexItem.pool.releaseAll(mVertices);
for (VertexItem i : mIndices)
VertexItem.pool.releaseAll(i);
mVertices = null;
}
}
@ -501,7 +503,8 @@ public class ExtrusionLayer extends Layer {
* @param ioffset offset used to add offset to indices
* @return number of triangles in io buffer
*/
public static native int triangulate(float[] points, int pos, int len, int numRings, ShortBuffer io,
public static native int triangulate(float[] points, int pos, int len, int numRings,
ShortBuffer io,
int ioffset);
static {

View File

@ -14,10 +14,6 @@
*/
package org.oscim.renderer.overlays;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;
import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.layers.tile.MapTile;
@ -58,9 +54,9 @@ public class ExtrusionOverlay extends RenderLayer {
private boolean initialized = false;
// FIXME sum up size used while filling layer only up to:
public int mBufferSize = 65536;
//public int mBufferSize = 65536;
private TileSet mTileSet;
private ShortBuffer mShortBuffer;
private MapTile[] mTiles;
private int mTileCnt;
@ -87,11 +83,6 @@ public class ExtrusionOverlay extends RenderLayer {
hVertexPosition[i] = GLES20.glGetAttribLocation(shaderProgram[i], "a_pos");
hLightPosition[i] = GLES20.glGetAttribLocation(shaderProgram[i], "a_light");
}
ByteBuffer buf = ByteBuffer.allocateDirect(mBufferSize)
.order(ByteOrder.nativeOrder());
mShortBuffer = buf.asShortBuffer();
}
int ready = 0;
@ -121,16 +112,10 @@ public class ExtrusionOverlay extends RenderLayer {
continue;
if (!el.compiled) {
// FIXME check 'bytes'?
int verticesBytes = el.mNumVertices * 8 * 2;
if (verticesBytes > mBufferSize) {
mBufferSize = verticesBytes;
Log.d(TAG, "realloc extrusion buffer " + verticesBytes);
ByteBuffer buf = ByteBuffer.allocateDirect(verticesBytes)
.order(ByteOrder.nativeOrder());
mShortBuffer = buf.asShortBuffer();
}
el.compile(mShortBuffer);
el.compile(GLRenderer.getShortBuffer(verticesBytes));
GlUtils.checkGlError("...");
}
@ -205,8 +190,8 @@ public class ExtrusionOverlay extends RenderLayer {
setMatrix(pos, m, tiles[i], 0);
m.mvp.setAsUniform(uExtMatrix);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.vboIndices.id);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.vboVertices.id);
GLES20.glVertexAttribPointer(uExtVertexPosition, 3,
GLES20.GL_SHORT, false, 8, 0);
@ -257,8 +242,8 @@ public class ExtrusionOverlay extends RenderLayer {
setMatrix(pos, m, t, d);
m.mvp.setAsUniform(uExtMatrix);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.vboIndices.id);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.vboVertices.id);
GLES20.glVertexAttribPointer(uExtVertexPosition, 3,
GLES20.GL_SHORT, false, 8, 0);
@ -283,8 +268,8 @@ public class ExtrusionOverlay extends RenderLayer {
setMatrix(pos, m, t, d);
m.mvp.setAsUniform(uExtMatrix);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.vboIndices.id);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.vboVertices.id);
GLES20.glVertexAttribPointer(uExtVertexPosition, 3,
GLES20.GL_SHORT, false, 8, 0);