package com.mojang.blaze3d.opengl; import com.mojang.blaze3d.buffers.BufferType; import com.mojang.blaze3d.buffers.BufferUsage; import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.jtracy.MemoryPool; import com.mojang.jtracy.TracyClient; import java.nio.ByteBuffer; import java.util.function.Supplier; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import org.jetbrains.annotations.Nullable; @Environment(EnvType.CLIENT) public class GlBuffer extends GpuBuffer { protected static final MemoryPool MEMORY_POOl = TracyClient.createMemoryPool("GPU Buffers"); protected boolean closed; protected boolean initialized = false; @Nullable protected final Supplier label; protected final int handle; protected GlBuffer(GlDebugLabel debugLabel, @Nullable Supplier label, BufferType type, BufferUsage usage, int size, int handle) { super(type, usage, size); this.label = label; this.handle = handle; if (usage.isReadable()) { GlStateManager._glBindBuffer(GlConst.toGl(type), handle); GlStateManager._glBufferData(GlConst.toGl(type), size, GlConst.toGl(usage)); MEMORY_POOl.malloc(handle, size); this.initialized = true; debugLabel.applyLabel(this); } } protected void ensureBufferExists() { if (!this.initialized) { GlStateManager._glBindBuffer(GlConst.toGl(this.type()), this.handle); GlStateManager._glBindBuffer(GlConst.toGl(this.type()), 0); } } @Override public boolean isClosed() { return this.closed; } @Override public void close() { if (!this.closed) { this.closed = true; GlStateManager._glDeleteBuffers(this.handle); if (this.initialized) { MEMORY_POOl.free(this.handle); } } } @Environment(EnvType.CLIENT) public static class ReadView implements GpuBuffer.ReadView { private final int target; private final ByteBuffer data; protected ReadView(int target, ByteBuffer data) { this.target = target; this.data = data; } @Override public ByteBuffer data() { return this.data; } @Override public void close() { GlStateManager._glUnmapBuffer(this.target); } } }