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; package org.oscim.renderer;
import java.nio.ByteBuffer;
import android.opengl.GLES20; import android.opengl.GLES20;
import android.util.Log; import android.util.Log;
@ -33,6 +35,23 @@ public final class BufferObject {
this.id = id; 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 ---------------------------- // ---------------------------- pool ----------------------------
private static BufferObject pool; private static BufferObject pool;
static int counter = 0; 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.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer; import java.nio.ShortBuffer;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@ -65,6 +66,9 @@ public class GLRenderer implements GLSurfaceView.Renderer {
private static MapPosition mMapPosition; private static MapPosition mMapPosition;
private static ShortBuffer shortBuffer; private static ShortBuffer shortBuffer;
private static FloatBuffer floatBuffer;
private static int tmpBufferSize;
private static short[] mFillCoords; private static short[] mFillCoords;
// bytes currently loaded in VBOs // bytes currently loaded in VBOs
@ -128,27 +132,51 @@ public class GLRenderer implements GLSurfaceView.Renderer {
mUpdateColor = true; 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, public static boolean uploadLayers(Layers layers, int newSize,
boolean addFill) { boolean addFill) {
GLES20.glBindBuffer(GL_ARRAY_BUFFER, layers.vbo.id);
// add fill coordinates // add fill coordinates
if (addFill) if (addFill)
newSize += 8; newSize += 8;
ShortBuffer sbuf = shortBuffer; ShortBuffer sbuf = getShortBuffer(newSize);
if (sbuf.capacity() < newSize) {
shortBuffer = sbuf = ByteBuffer
.allocateDirect(newSize * SHORT_BYTES)
.order(ByteOrder.nativeOrder())
.asShortBuffer();
} else {
sbuf.clear();
// if (addFill)
// sbuf.position(8);
}
if (addFill) if (addFill)
sbuf.put(mFillCoords, 0, 8); sbuf.put(mFillCoords, 0, 8);
@ -166,6 +194,8 @@ public class GLRenderer implements GLSurfaceView.Renderer {
} }
newSize *= SHORT_BYTES; newSize *= SHORT_BYTES;
GLES20.glBindBuffer(GL_ARRAY_BUFFER, layers.vbo.id);
// reuse memory allocated for vbo when possible and allocated // reuse memory allocated for vbo when possible and allocated
// memory is less then four times the new data // memory is less then four times the new data
if (layers.vbo.size > newSize && layers.vbo.size < newSize * 4 if (layers.vbo.size > newSize && layers.vbo.size < newSize * 4
@ -222,8 +252,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
} }
} }
private static void draw() { private static void draw() {
long start = 0; long start = 0;
@ -264,7 +292,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
} }
} }
/* update layers*/ /* update layers */
RenderLayer[] overlays = mMapView.getLayerManager().getRenderLayers(); RenderLayer[] overlays = mMapView.getLayerManager().getRenderLayers();
for (int i = 0, n = overlays.length; i < n; i++) for (int i = 0, n = overlays.length; i < n; i++)
@ -332,9 +360,8 @@ public class GLRenderer implements GLSurfaceView.Renderer {
} }
mNewSurface = false; mNewSurface = false;
ByteBuffer bbuf = ByteBuffer.allocateDirect(MB >> 2) // set initial temp buffer size
.order(ByteOrder.nativeOrder()); growBuffer(MB >> 2);
shortBuffer = bbuf.asShortBuffer();
// upload quad indices used by Texture- and LineTexRenderer // upload quad indices used by Texture- and LineTexRenderer
int[] vboIds = new int[1]; int[] vboIds = new int[1];

View File

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

View File

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