use a DirectByteBuffer pool in GLRenderer
This commit is contained in:
parent
75ef8f83e1
commit
52b2fadd7d
@ -4,7 +4,6 @@ import org.oscim.awt.AwtGraphics;
|
|||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.backend.GLAdapter;
|
import org.oscim.backend.GLAdapter;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
||||||
@ -26,7 +25,6 @@ public class Main {
|
|||||||
CanvasAdapter.g = AwtGraphics.INSTANCE;
|
CanvasAdapter.g = AwtGraphics.INSTANCE;
|
||||||
GLAdapter.INSTANCE = new GdxGLAdapter();
|
GLAdapter.INSTANCE = new GdxGLAdapter();
|
||||||
Tile.SIZE = 256;
|
Tile.SIZE = 256;
|
||||||
GLRenderer.alwaysAllocBuffer = true;
|
|
||||||
|
|
||||||
new SharedLibraryLoader().load("vtm-jni");
|
new SharedLibraryLoader().load("vtm-jni");
|
||||||
|
|
||||||
|
|||||||
@ -66,9 +66,7 @@ public final class BufferObject {
|
|||||||
mBufferMemoryUsage += newSize - size;
|
mBufferMemoryUsage += newSize - size;
|
||||||
size = newSize;
|
size = newSize;
|
||||||
GL.glBufferData(type, size, buf, GL20.GL_DYNAMIC_DRAW);
|
GL.glBufferData(type, size, buf, GL20.GL_DYNAMIC_DRAW);
|
||||||
//GL.glBufferData(type, size, buf, GL20.GL_STATIC_DRAW);
|
|
||||||
}
|
}
|
||||||
//GL.glFinish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bindArrayBuffer() {
|
public void bindArrayBuffer() {
|
||||||
|
|||||||
@ -14,7 +14,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.renderer;
|
package org.oscim.renderer;
|
||||||
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
@ -32,16 +31,16 @@ import org.oscim.renderer.sublayers.Layers;
|
|||||||
import org.oscim.theme.IRenderTheme;
|
import org.oscim.theme.IRenderTheme;
|
||||||
import org.oscim.utils.GlUtils;
|
import org.oscim.utils.GlUtils;
|
||||||
import org.oscim.utils.Matrix4;
|
import org.oscim.utils.Matrix4;
|
||||||
|
import org.oscim.utils.pool.Inlist;
|
||||||
|
import org.oscim.utils.pool.Pool;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
import org.oscim.view.MapViewPosition;
|
import org.oscim.view.MapViewPosition;
|
||||||
|
|
||||||
|
|
||||||
public class GLRenderer {
|
public class GLRenderer {
|
||||||
private static final String TAG = GLRenderer.class.getName();
|
private static final String TAG = GLRenderer.class.getName();
|
||||||
|
|
||||||
private static final GL20 GL = GLAdapter.INSTANCE;
|
private static final GL20 GL = GLAdapter.INSTANCE;
|
||||||
|
|
||||||
private static final int MB = 1024 * 1024;
|
|
||||||
private static final int SHORT_BYTES = 2;
|
private static final int SHORT_BYTES = 2;
|
||||||
private static final int CACHE_TILES_MAX = 250;
|
private static final int CACHE_TILES_MAX = 250;
|
||||||
|
|
||||||
@ -55,11 +54,6 @@ public class GLRenderer {
|
|||||||
private static MapViewPosition mMapViewPosition;
|
private static MapViewPosition mMapViewPosition;
|
||||||
private static MapPosition mMapPosition;
|
private static MapPosition mMapPosition;
|
||||||
|
|
||||||
private static ShortBuffer shortBuffer;
|
|
||||||
private static FloatBuffer floatBuffer;
|
|
||||||
private static IntBuffer intBuffer;
|
|
||||||
private static int tmpBufferSize;
|
|
||||||
|
|
||||||
private static short[] mFillCoords;
|
private static short[] mFillCoords;
|
||||||
|
|
||||||
public class Matrices {
|
public class Matrices {
|
||||||
@ -73,8 +67,8 @@ public class GLRenderer {
|
|||||||
public final Matrix4 mvp = new Matrix4();
|
public final Matrix4 mvp = new Matrix4();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set MVP so that coordinates are in screen pixel coordinates
|
* Set MVP so that coordinates are in screen pixel coordinates with 0,0
|
||||||
* with 0,0 being center
|
* being center
|
||||||
*/
|
*/
|
||||||
public void useScreenCoordinates(boolean center, float scale) {
|
public void useScreenCoordinates(boolean center, float scale) {
|
||||||
float ratio = (1f / (scale * screenWidth));
|
float ratio = (1f / (scale * screenWidth));
|
||||||
@ -93,7 +87,7 @@ public class GLRenderer {
|
|||||||
|
|
||||||
private static Matrices mMatrices;
|
private static Matrices mMatrices;
|
||||||
|
|
||||||
//private
|
// private
|
||||||
static float[] mClearColor = null;
|
static float[] mClearColor = null;
|
||||||
|
|
||||||
public static int mQuadIndicesID;
|
public static int mQuadIndicesID;
|
||||||
@ -135,62 +129,99 @@ public class GLRenderer {
|
|||||||
mClearColor = GlUtils.colorToFloat(t.getMapBackground());
|
mClearColor = GlUtils.colorToFloat(t.getMapBackground());
|
||||||
mUpdateColor = true;
|
mUpdateColor = true;
|
||||||
}
|
}
|
||||||
public static boolean alwaysAllocBuffer = false;
|
|
||||||
|
|
||||||
/**
|
static class BufferItem extends Inlist<BufferItem> {
|
||||||
* Only use on GL Thread!
|
|
||||||
* Get a native ShortBuffer for temporary use.
|
|
||||||
*/
|
|
||||||
public static ShortBuffer getShortBuffer(int size) {
|
|
||||||
if (alwaysAllocBuffer || tmpBufferSize < size * 2)
|
|
||||||
growBuffer(size * 2);
|
|
||||||
else
|
|
||||||
shortBuffer.clear();
|
|
||||||
|
|
||||||
return shortBuffer;
|
ShortBuffer shortBuffer;
|
||||||
}
|
FloatBuffer floatBuffer;
|
||||||
|
IntBuffer intBuffer;
|
||||||
|
int tmpBufferSize;
|
||||||
|
|
||||||
/**
|
void growBuffer(int size) {
|
||||||
* Only use on GL Thread!
|
|
||||||
* Get a native FloatBuffer for temporary use.
|
|
||||||
*/
|
|
||||||
public static FloatBuffer getFloatBuffer(int size) {
|
|
||||||
if (alwaysAllocBuffer || tmpBufferSize < size * 4)
|
|
||||||
growBuffer(size * 4);
|
|
||||||
else
|
|
||||||
floatBuffer.clear();
|
|
||||||
|
|
||||||
return floatBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only use on GL Thread!
|
|
||||||
* Get a native IntBuffer for temporary use.
|
|
||||||
*/
|
|
||||||
public static IntBuffer getIntBuffer(int size) {
|
|
||||||
if (alwaysAllocBuffer || tmpBufferSize < size * 4)
|
|
||||||
growBuffer(size * 4);
|
|
||||||
else
|
|
||||||
intBuffer.clear();
|
|
||||||
|
|
||||||
return intBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void growBuffer(int size) {
|
|
||||||
Log.d(TAG, "grow buffer " + size);
|
Log.d(TAG, "grow buffer " + size);
|
||||||
|
// 32kb min size
|
||||||
|
if (size < (1 << 15))
|
||||||
|
size = (1 << 15);
|
||||||
|
|
||||||
ByteBuffer buf = ByteBuffer
|
ByteBuffer buf = ByteBuffer
|
||||||
.allocateDirect(size)
|
.allocateDirect(size)
|
||||||
.order(ByteOrder.nativeOrder());
|
.order(ByteOrder.nativeOrder());
|
||||||
|
|
||||||
floatBuffer = buf.asFloatBuffer();
|
this.floatBuffer = buf.asFloatBuffer();
|
||||||
shortBuffer = buf.asShortBuffer();
|
this.shortBuffer = buf.asShortBuffer();
|
||||||
intBuffer = buf.asIntBuffer();
|
this.intBuffer = buf.asIntBuffer();
|
||||||
tmpBufferSize = size;
|
this.tmpBufferSize = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static class BufferPool extends Pool<BufferItem>{
|
||||||
|
private BufferItem mUsedBuffers;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BufferItem createItem() {
|
||||||
|
// unused;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferItem get(int size){
|
||||||
|
BufferItem b = pool;
|
||||||
|
|
||||||
|
if (b == null){
|
||||||
|
b = new BufferItem();
|
||||||
|
} else {
|
||||||
|
pool = b.next;
|
||||||
|
b.next = null;
|
||||||
|
}
|
||||||
|
if (b.tmpBufferSize < size)
|
||||||
|
b.growBuffer(size);
|
||||||
|
|
||||||
|
mUsedBuffers = Inlist.push(mUsedBuffers, b);
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void releaseBuffers(){
|
||||||
|
mBufferPool.releaseAll(mUsedBuffers);
|
||||||
|
mUsedBuffers = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// Do not use the same buffer to upload data within a frame twice
|
||||||
|
// - Contrary to what the OpenGL doc says data seems *not* to be
|
||||||
|
// *always* copied after glBufferData returns...
|
||||||
|
// - Somehow it does always copy when using Android GL bindings
|
||||||
|
// but not when using libgdx bindings (LWJGL or AndroidGL20)
|
||||||
|
private static BufferPool mBufferPool = new BufferPool();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only use on GL Thread! Get a native ShortBuffer for temporary use.
|
||||||
|
*/
|
||||||
|
public static ShortBuffer getShortBuffer(int size) {
|
||||||
|
BufferItem b = mBufferPool.get(size * 2);
|
||||||
|
b.shortBuffer.clear();
|
||||||
|
return b.shortBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only use on GL Thread! Get a native FloatBuffer for temporary use.
|
||||||
|
*/
|
||||||
|
public static FloatBuffer getFloatBuffer(int size) {
|
||||||
|
BufferItem b = mBufferPool.get(size * 4);
|
||||||
|
b.floatBuffer.clear();
|
||||||
|
return b.floatBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only use on GL Thread! Get a native IntBuffer for temporary use.
|
||||||
|
*/
|
||||||
|
public static IntBuffer getIntBuffer(int size) {
|
||||||
|
BufferItem b = mBufferPool.get(size * 4);
|
||||||
|
b.intBuffer.clear();
|
||||||
|
return b.intBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean uploadLayers(Layers layers, int newSize,
|
public static boolean uploadLayers(Layers layers, int newSize,
|
||||||
boolean addFill) {
|
boolean addFill) {
|
||||||
|
|
||||||
// add fill coordinates
|
// add fill coordinates
|
||||||
if (addFill)
|
if (addFill)
|
||||||
newSize += 8;
|
newSize += 8;
|
||||||
@ -217,17 +248,7 @@ public class GLRenderer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//private long lastDraw = 0;
|
|
||||||
|
|
||||||
public void onDrawFrame() {
|
public void onDrawFrame() {
|
||||||
//long start = SystemClock.uptimeMillis();
|
|
||||||
//long wait = 30 - (start - lastDraw);
|
|
||||||
//if (wait > 5) {
|
|
||||||
// //Log.d(TAG, "wait " + wait);
|
|
||||||
// SystemClock.sleep(wait);
|
|
||||||
// lastDraw = start + wait;
|
|
||||||
//} else
|
|
||||||
// lastDraw = start;
|
|
||||||
|
|
||||||
// prevent main thread recreating all tiles (updateMap)
|
// prevent main thread recreating all tiles (updateMap)
|
||||||
// while rendering is going on.
|
// while rendering is going on.
|
||||||
@ -237,13 +258,11 @@ public class GLRenderer {
|
|||||||
} finally {
|
} finally {
|
||||||
drawlock.unlock();
|
drawlock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mBufferPool.releaseBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void draw() {
|
private static void draw() {
|
||||||
//long start = 0;
|
|
||||||
|
|
||||||
//if (MapView.debugFrameTime)
|
|
||||||
// start = SystemClock.uptimeMillis();
|
|
||||||
|
|
||||||
if (mUpdateColor) {
|
if (mUpdateColor) {
|
||||||
float cc[] = mClearColor;
|
float cc[] = mClearColor;
|
||||||
@ -302,14 +321,9 @@ public class GLRenderer {
|
|||||||
renderLayer.render(mMapPosition, mMatrices);
|
renderLayer.render(mMapPosition, mMatrices);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (MapView.debugFrameTime) {
|
|
||||||
// GL.glFinish();
|
|
||||||
// Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start));
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (GlUtils.checkGlOutOfMemory("finish")) {
|
if (GlUtils.checkGlOutOfMemory("finish")) {
|
||||||
BufferObject.checkBufferUsage(true);
|
BufferObject.checkBufferUsage(true);
|
||||||
// TODO also throw out some textures etc
|
// FIXME also throw out some textures etc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,8 +358,6 @@ public class GLRenderer {
|
|||||||
GL.glDisable(GL20.GL_CULL_FACE);
|
GL.glDisable(GL20.GL_CULL_FACE);
|
||||||
GL.glBlendFunc(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
|
GL.glBlendFunc(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
//mBufferMemoryUsage = 0;
|
|
||||||
|
|
||||||
if (!mNewSurface) {
|
if (!mNewSurface) {
|
||||||
mMapView.updateMap(false);
|
mMapView.updateMap(false);
|
||||||
return;
|
return;
|
||||||
@ -353,9 +365,6 @@ public class GLRenderer {
|
|||||||
|
|
||||||
mNewSurface = false;
|
mNewSurface = false;
|
||||||
|
|
||||||
// set initial temp buffer size
|
|
||||||
growBuffer(MB >> 2);
|
|
||||||
|
|
||||||
// upload quad indices used by Texture- and LineTexRenderer
|
// upload quad indices used by Texture- and LineTexRenderer
|
||||||
int[] vboIds = GlUtils.glGenBuffers(1);
|
int[] vboIds = GlUtils.glGenBuffers(1);
|
||||||
|
|
||||||
@ -371,14 +380,14 @@ public class GLRenderer {
|
|||||||
indices[i + 4] = (short) (j + 1);
|
indices[i + 4] = (short) (j + 1);
|
||||||
indices[i + 5] = (short) (j + 3);
|
indices[i + 5] = (short) (j + 3);
|
||||||
}
|
}
|
||||||
GLRenderer.getShortBuffer(indices.length);
|
ShortBuffer buf = GLRenderer.getShortBuffer(indices.length);
|
||||||
shortBuffer.put(indices);
|
buf.put(indices);
|
||||||
shortBuffer.flip();
|
buf.flip();
|
||||||
|
|
||||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER,
|
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER,
|
||||||
mQuadIndicesID);
|
mQuadIndicesID);
|
||||||
GL.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER,
|
GL.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER,
|
||||||
indices.length * 2, shortBuffer, GL20.GL_STATIC_DRAW);
|
indices.length * 2, buf, GL20.GL_STATIC_DRAW);
|
||||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
if (mClearColor != null)
|
if (mClearColor != null)
|
||||||
@ -404,8 +413,4 @@ public class GLRenderer {
|
|||||||
private boolean mNewSurface;
|
private boolean mNewSurface;
|
||||||
|
|
||||||
public static final boolean debugView = false;
|
public static final boolean debugView = false;
|
||||||
|
|
||||||
// void clearBuffer() {
|
|
||||||
// mNewSurface = true;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,16 +64,6 @@ public class ExtrusionRenderLayer extends RenderLayer {
|
|||||||
|
|
||||||
private final static int SHADER = 0;
|
private final static int SHADER = 0;
|
||||||
|
|
||||||
private static ShortBuffer getShortBuffer(int size) {
|
|
||||||
ByteBuffer buf = ByteBuffer
|
|
||||||
.allocateDirect(size)
|
|
||||||
.order(ByteOrder.nativeOrder());
|
|
||||||
|
|
||||||
return buf.asShortBuffer();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private boolean initShader() {
|
private boolean initShader() {
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
@ -134,8 +124,8 @@ public class ExtrusionRenderLayer extends RenderLayer {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!el.compiled) {
|
if (!el.compiled) {
|
||||||
int bytes = el.mNumVertices * 8 * 2;
|
int numShorts = el.mNumVertices * 8;
|
||||||
el.compile(getShortBuffer(bytes));
|
el.compile(GLRenderer.getShortBuffer(numShorts));
|
||||||
GlUtils.checkGlError("...");
|
GlUtils.checkGlError("...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ package org.oscim.utils.pool;
|
|||||||
|
|
||||||
public abstract class Pool<T extends Inlist<T>> {
|
public abstract class Pool<T extends Inlist<T>> {
|
||||||
|
|
||||||
T pool;
|
protected T pool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param item release resources
|
* @param item release resources
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user