Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-144307

VBO delete/create world switching lag + System.gc()

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • Minecraft 1.13.2, Minecraft 19w05a, Minecraft 19w06a, Minecraft 19w07a, Minecraft 19w08b, Minecraft 1.14 Pre-Release 2, Minecraft 1.14 Pre-Release 3, Minecraft 1.14 Pre-Release 4, Minecraft 1.14 Pre-Release 5, Minecraft 1.14, 1.15.2, 20w06a
    • None
    • Community Consensus
    • (Unassigned)

      Switching worlds can cause NO LAG! Just remove System.gc() from the code and don't delete all VBOs when changing dimensions. For example, on Hypixel dimension switch is sent 2 times which causes the screen to darken 2 times (especially with render distance 32). This lag can take up to 5 seconds on Windows and 30+ seconds on linux leading to disconnection with the server.

      How to reproduce:
      Set render distance to 32 and go through the nether portal in singleplayer
      or switch subserver in multiplayer.

      Solution:
      Remove System.gc() Reuse buffers. Sample code below

      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;
      	}
      }
      

            Unassigned Unassigned
            7ERr0r 7ERr0r
            Votes:
            8 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              CHK: