Reduce buffer streaming VRAM usage
This commit is contained in:
parent
eb6131cacf
commit
a6958812bb
|
@ -1190,8 +1190,8 @@ public class EaglerAdapterGL30 extends EaglerAdapterImpl2 {
|
||||||
bindTheShader();
|
bindTheShader();
|
||||||
|
|
||||||
StreamBufferInstance sb = shader.streamBuffer.getBuffer(bl);
|
StreamBufferInstance sb = shader.streamBuffer.getBuffer(bl);
|
||||||
_wglBindVertexArray0(sb.vertexArray);
|
_wglBindVertexArray0(sb.getVertexArray());
|
||||||
_wglBindBuffer(_wGL_ARRAY_BUFFER, sb.vertexBuffer);
|
_wglBindBuffer(_wGL_ARRAY_BUFFER, sb.getVertexBuffer());
|
||||||
if (!shader.bufferIsInitialized) {
|
if (!shader.bufferIsInitialized) {
|
||||||
shader.bufferIsInitialized = true;
|
shader.bufferIsInitialized = true;
|
||||||
_wglBufferData(_wGL_ARRAY_BUFFER, blankUploadArray, _wGL_DYNAMIC_DRAW);
|
_wglBufferData(_wGL_ARRAY_BUFFER, blankUploadArray, _wGL_DYNAMIC_DRAW);
|
||||||
|
@ -1625,15 +1625,17 @@ public class EaglerAdapterGL30 extends EaglerAdapterImpl2 {
|
||||||
long millis = steadyTimeMillis();
|
long millis = steadyTimeMillis();
|
||||||
long remaining = timerPtr[0] - millis;
|
long remaining = timerPtr[0] - millis;
|
||||||
if(remaining > 0) {
|
if(remaining > 0) {
|
||||||
if(isWebGL) {
|
if(isWebGL && immediateContinueSupported()) {
|
||||||
immediateContinue(); // cannot stack setTimeouts, or it will throttle
|
immediateContinue(); // cannot stack setTimeouts, or it will throttle
|
||||||
millis = steadyTimeMillis();
|
millis = steadyTimeMillis();
|
||||||
remaining = timerPtr[0] - millis;
|
remaining = timerPtr[0] - millis;
|
||||||
if(remaining > 0) {
|
if(remaining > 0) {
|
||||||
sleep((int)remaining);
|
sleep((int)remaining);
|
||||||
|
millis = steadyTimeMillis();
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
sleep((int)remaining);
|
sleep((int)remaining);
|
||||||
|
millis = steadyTimeMillis();
|
||||||
}
|
}
|
||||||
blocked = true;
|
blocked = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,48 @@ import static net.lax1dude.eaglercraft.EaglerAdapter.*;
|
||||||
|
|
||||||
public class StreamBuffer {
|
public class StreamBuffer {
|
||||||
|
|
||||||
|
public static final int poolSize = 16;
|
||||||
|
|
||||||
public final int initialSize;
|
public final int initialSize;
|
||||||
public final int initialCount;
|
public final int initialCount;
|
||||||
public final int maxCount;
|
public final int maxCount;
|
||||||
|
|
||||||
|
protected static final PoolInstance[] pool = new PoolInstance[poolSize];
|
||||||
|
protected static int poolBufferID = 0;
|
||||||
|
|
||||||
|
static {
|
||||||
|
for(int i = 0; i < poolSize; ++i) {
|
||||||
|
pool[i] = new PoolInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class PoolInstance {
|
||||||
|
|
||||||
|
protected BufferGL vertexBuffer = null;
|
||||||
|
protected int vertexBufferSize = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PoolInstance fillPoolInstance() {
|
||||||
|
PoolInstance ret = pool[poolBufferID++];
|
||||||
|
if(poolBufferID > poolSize - 1) {
|
||||||
|
poolBufferID = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void resizeInstance(PoolInstance instance, int requiredMemory) {
|
||||||
|
if(instance.vertexBuffer == null) {
|
||||||
|
instance.vertexBuffer = _wglCreateBuffer();
|
||||||
|
}
|
||||||
|
if(instance.vertexBufferSize < requiredMemory) {
|
||||||
|
int newSize = (requiredMemory & 0xFFFFF000) + 0x2000;
|
||||||
|
_wglBindBuffer(_wGL_ARRAY_BUFFER, instance.vertexBuffer);
|
||||||
|
_wglBufferData00(_wGL_ARRAY_BUFFER, newSize, _wGL_STREAM_DRAW);
|
||||||
|
instance.vertexBufferSize = newSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected StreamBufferInstance[] buffers;
|
protected StreamBufferInstance[] buffers;
|
||||||
|
|
||||||
protected int currentBufferId = 0;
|
protected int currentBufferId = 0;
|
||||||
|
@ -17,9 +55,8 @@ public class StreamBuffer {
|
||||||
|
|
||||||
public static class StreamBufferInstance {
|
public static class StreamBufferInstance {
|
||||||
|
|
||||||
|
protected PoolInstance poolInstance = null;
|
||||||
protected BufferArrayGL vertexArray = null;
|
protected BufferArrayGL vertexArray = null;
|
||||||
protected BufferGL vertexBuffer = null;
|
|
||||||
protected int vertexBufferSize = 0;
|
|
||||||
|
|
||||||
public boolean bindQuad16 = false;
|
public boolean bindQuad16 = false;
|
||||||
public boolean bindQuad32 = false;
|
public boolean bindQuad32 = false;
|
||||||
|
@ -29,7 +66,7 @@ public class StreamBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public BufferGL getVertexBuffer() {
|
public BufferGL getVertexBuffer() {
|
||||||
return vertexBuffer;
|
return poolInstance.vertexBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,9 +76,14 @@ public class StreamBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamBuffer(int initialSize, int initialCount, int maxCount, IStreamBufferInitializer initializer) {
|
public StreamBuffer(int initialSize, int initialCount, int maxCount, IStreamBufferInitializer initializer) {
|
||||||
|
if(maxCount > poolSize) {
|
||||||
|
maxCount = poolSize;
|
||||||
|
}
|
||||||
this.buffers = new StreamBufferInstance[initialCount];
|
this.buffers = new StreamBufferInstance[initialCount];
|
||||||
for(int i = 0; i < this.buffers.length; ++i) {
|
for(int i = 0; i < this.buffers.length; ++i) {
|
||||||
this.buffers[i] = new StreamBufferInstance();
|
StreamBufferInstance j = new StreamBufferInstance();
|
||||||
|
j.poolInstance = fillPoolInstance();
|
||||||
|
this.buffers[i] = j;
|
||||||
}
|
}
|
||||||
this.initialSize = initialSize;
|
this.initialSize = initialSize;
|
||||||
this.initialCount = initialCount;
|
this.initialCount = initialCount;
|
||||||
|
@ -51,18 +93,10 @@ public class StreamBuffer {
|
||||||
|
|
||||||
public StreamBufferInstance getBuffer(int requiredMemory) {
|
public StreamBufferInstance getBuffer(int requiredMemory) {
|
||||||
StreamBufferInstance next = buffers[(currentBufferId++) % buffers.length];
|
StreamBufferInstance next = buffers[(currentBufferId++) % buffers.length];
|
||||||
if(next.vertexBuffer == null) {
|
resizeInstance(next.poolInstance, requiredMemory);
|
||||||
next.vertexBuffer = _wglCreateBuffer();
|
|
||||||
}
|
|
||||||
if(next.vertexArray == null) {
|
if(next.vertexArray == null) {
|
||||||
next.vertexArray = _wglCreateVertexArray();
|
next.vertexArray = _wglCreateVertexArray();
|
||||||
initializer.initialize(next.vertexArray, next.vertexBuffer);
|
initializer.initialize(next.vertexArray, next.poolInstance.vertexBuffer);
|
||||||
}
|
|
||||||
if(next.vertexBufferSize < requiredMemory) {
|
|
||||||
int newSize = (requiredMemory & 0xFFFFF000) + 0x2000;
|
|
||||||
_wglBindBuffer(_wGL_ARRAY_BUFFER, next.vertexBuffer);
|
|
||||||
_wglBufferData00(_wGL_ARRAY_BUFFER, newSize, _wGL_STREAM_DRAW);
|
|
||||||
next.vertexBufferSize = newSize;
|
|
||||||
}
|
}
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
@ -83,12 +117,10 @@ public class StreamBuffer {
|
||||||
if(buffers[i].vertexArray != null) {
|
if(buffers[i].vertexArray != null) {
|
||||||
_wglDeleteVertexArray(buffers[i].vertexArray);
|
_wglDeleteVertexArray(buffers[i].vertexArray);
|
||||||
}
|
}
|
||||||
if(buffers[i].vertexBuffer != null) {
|
|
||||||
_wglDeleteBuffer(buffers[i].vertexBuffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffers = newArray;
|
buffers = newArray;
|
||||||
|
refill();
|
||||||
}
|
}
|
||||||
overflowCounter = 0;
|
overflowCounter = 0;
|
||||||
}else if(overflowCounter > 15) {
|
}else if(overflowCounter > 15) {
|
||||||
|
@ -106,25 +138,52 @@ public class StreamBuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffers = newArray;
|
buffers = newArray;
|
||||||
|
refill();
|
||||||
}
|
}
|
||||||
overflowCounter = 0;
|
overflowCounter = 0;
|
||||||
}
|
}
|
||||||
currentBufferId = 0;
|
currentBufferId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refill() {
|
||||||
|
for(int i = 0; i < buffers.length; ++i) {
|
||||||
|
PoolInstance j = fillPoolInstance();
|
||||||
|
StreamBufferInstance k = buffers[i];
|
||||||
|
if(j != k.poolInstance) {
|
||||||
|
PoolInstance l = k.poolInstance;
|
||||||
|
k.poolInstance = j;
|
||||||
|
if(k.vertexArray != null) {
|
||||||
|
if(j.vertexBuffer == null) {
|
||||||
|
resizeInstance(j, l.vertexBufferSize);
|
||||||
|
}
|
||||||
|
initializer.initialize(k.vertexArray, j.vertexBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
for(int i = 0; i < buffers.length; ++i) {
|
for(int i = 0; i < buffers.length; ++i) {
|
||||||
StreamBufferInstance next = buffers[i];
|
StreamBufferInstance next = buffers[i];
|
||||||
if(next.vertexArray != null) {
|
if(next.vertexArray != null) {
|
||||||
_wglDeleteVertexArray(next.vertexArray);
|
_wglDeleteVertexArray(next.vertexArray);
|
||||||
}
|
}
|
||||||
if(next.vertexBuffer != null) {
|
|
||||||
_wglDeleteBuffer(next.vertexBuffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
buffers = new StreamBufferInstance[initialCount];
|
buffers = new StreamBufferInstance[initialCount];
|
||||||
for(int i = 0; i < buffers.length; ++i) {
|
for(int i = 0; i < initialCount; ++i) {
|
||||||
buffers[i] = new StreamBufferInstance();
|
StreamBufferInstance j = new StreamBufferInstance();
|
||||||
|
j.poolInstance = fillPoolInstance();
|
||||||
|
buffers[i] = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void destroyPool() {
|
||||||
|
for(int i = 0; i < pool.length; ++i) {
|
||||||
|
if(pool[i].vertexBuffer != null) {
|
||||||
|
_wglDeleteBuffer(pool[i].vertexBuffer);
|
||||||
|
pool[i].vertexBuffer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1774,6 +1774,9 @@ public class EaglerAdapterImpl2 {
|
||||||
sleep(0);
|
sleep(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static final boolean immediateContinueSupported() {
|
||||||
|
return immediateContinueChannel != null;
|
||||||
|
}
|
||||||
private static final JSString emptyJSString = JSString.valueOf("");
|
private static final JSString emptyJSString = JSString.valueOf("");
|
||||||
@Async
|
@Async
|
||||||
private static native void immediateContinueTeaVM0();
|
private static native void immediateContinueTeaVM0();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user