mojira.dev

7ERr0r

Assigned

No issues.

Reported

MC-144307 VBO delete/create world switching lag + System.gc() Community Consensus MC-103897 Make player vs. player battles possible Invalid MC-101266 Freeze when switching dimension [VBO delete buffer lag] Invalid MC-84240 Enchanted books in Minecarts (mineshafts) are corrupted Duplicate

Comments

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

 

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

Isn't the fix so simple as setting player's lastPosX = teleportX etc. to prevent animation when packet arrives?
This change shouldn't break any entity trackers, I hope.