EDIT:
You just have to not delete VBOs when switching worlds. This bug exists even on Windows 10 on Hypixel. On every platform. Render distance 32 makes the lag longer.
Detailed info:
Create an unordered stack with objects that have indexes inside. Addictional stack index points to the top of used elements stack. When deleting VBO just remove it from the used stack and "transfer to ununsed" stack. Java code as a proof of concept in comments
Minor improvement: please remove System.gc() when switching worlds
(end of edit)
When I switch the world (1.9.3-pre1) or teleport between servers on a proxy server (1.9.2) the game freezes in dirt screen (no text showing).
When switching nether<->overworld it takes about 8 seconds every time. On my proxy it takes sometimes 100s.
Here's a snapshot of CPU time when joining my server. Which sends 4 respawn packets. On Windows 10 both switching world and server work perfectly.
I have no resource packs, just freshly installed system.
On calltree it looks like it's something with glGenLists()
Attachments
Comments 7
Detailed info:
Create an unordered stack with objects that have indexes inside. Addictional stack index points to the top of used elements stack. When deleting VBO just remove it from the used stack and "transfer to ununsed" stack. Below working java code as a proof of concept
public class GlBuffer
{
public static GlBuffersStack glBuffers = new GlBuffersStack(1024*64);
private static int glBuffersIndex = 0;
public static int vmem = 0;
private int index;
public static GlBuffer genBuffer(){
GlBuffer result = null;
if(glBuffersIndex < glBuffers.size()){
result = glBuffers.get(glBuffersIndex);
}else{
result = new GlBuffer();
glBuffers.push(result);
}
result.index = glBuffersIndex;
glBuffersIndex++;
return result;
}
public static void trimUnused(){
while(glBuffers.size() > 0){
GlBuffer gb = glBuffers.get(glBuffers.size()-1);
if(gb.released()){
gb.deleteGlBuffers();
glBuffers.popSilently();
}else{
break;
}
}
}
private int glBufferId;
private int size;
private static int globalCount = 0;
public GlBuffer()
{
this.glBufferId = OpenGlHelper.glGenBuffers();
globalCount++;
}
public void bindBuffer()
{
OpenGlHelper.glBindBuffer(OpenGlHelper.GL_ARRAY_BUFFER, this.glBufferId);
}
public void setBufferData(ByteBuffer data)
{
vmem -= this.size;
this.bindBuffer();
OpenGlHelper.glBufferData(OpenGlHelper.GL_ARRAY_BUFFER, data, 35044);
this.unbindBuffer();
this.size = data.limit();
vmem += this.size;
}
public void drawArrays(int mode, int count)
{
GL11.glDrawArrays(mode, 0, count);
}
public void unbindBuffer()
{
OpenGlHelper.glBindBuffer(OpenGlHelper.GL_ARRAY_BUFFER, 0);
}
public void deleteGlBuffers()
{
if (this.glBufferId >= 0)
{
OpenGlHelper.glDeleteBuffers(this.glBufferId);
this.glBufferId = -1;
globalCount--;
}
}
public void releaseGenBuffer(){
if(this.index == -1){
return;
}
GlBuffer self = glBuffers.get(this.index);
if(this != self){
throw new RuntimeException("wrong order in releaseGenBuffer");
}
glBuffersIndex--;
GlBuffer last = glBuffers.get(glBuffersIndex);
glBuffers.set(this.index, last);
glBuffers.set(glBuffersIndex, self);
last.index = this.index;
this.index = -1;
}
public boolean released(){
return this.index == -1;
}
public static int getGlobalCount(){
return globalCount;
}
public int getSize(){
return this.size;
}
}
public final class GlBuffersStack {
public GlBuffer[] stack;
public int size;
public GlBuffersStack(int initialCapacity) {
stack = new GlBuffer[initialCapacity];
}
public GlBuffer push(GlBuffer value) {
if (size + 1 >= stack.length) {
resizeStack(stack.length * 2);
}
stack[size++] = value;
return value;
}
public void popSilently() {
stack[--size] = null;
}
public GlBuffer pop() {
final GlBuffer result = stack[--size];
stack[size] = null;
return result;
}
public GlBuffer peek() {
return size == 0 ? null : stack[size - 1];
}
public int size() {
return size;
}
public boolean hasStuff() {
return size > 0;
}
public GlBuffer get(int i) {
return stack[i];
}
private void resizeStack(int newCapacity) {
GlBuffer[] newStack = new GlBuffer[newCapacity];
System.arraycopy(stack, 0, newStack, 0, Math.min(size, newCapacity));
stack = newStack;
}
public String toString() {
StringBuffer result = new StringBuffer("[");
for (int i = 0; i < size; i++) {
if (i > 0) {
result.append(", ");
}
result.append(stack[i]);
}
result.append(']');
return result.toString();
}
public void set(int i, GlBuffer value) {
stack[i] = value;
}
}
I'm running Fedora 24 and I get this same thing. Oddly enough, it doesn't occur for the first respawn packet that's received in the client's lifetime, but does for every other one, often leading to a connection timeout. Has there been any progress on this?