package com.mojang.blaze3d.opengl; import com.mojang.blaze3d.buffers.GpuBuffer; import java.nio.ByteBuffer; import java.util.Set; import java.util.function.Supplier; import org.jspecify.annotations.Nullable; import org.lwjgl.opengl.GLCapabilities; public abstract class BufferStorage { public static BufferStorage create(final GLCapabilities capabilities, final Set enabledExtensions) { if (capabilities.GL_ARB_buffer_storage && GlDevice.USE_GL_ARB_buffer_storage) { enabledExtensions.add("GL_ARB_buffer_storage"); return new BufferStorage.Immutable(); } else { return new BufferStorage.Mutable(); } } public abstract GlBuffer createBuffer(DirectStateAccess dsa, @Nullable Supplier label, @GpuBuffer.Usage int usage, long size); public abstract GlBuffer createBuffer(DirectStateAccess dsa, @Nullable Supplier label, @GpuBuffer.Usage int usage, ByteBuffer data); private static class Immutable extends BufferStorage { @Override public GlBuffer createBuffer(final DirectStateAccess dsa, @Nullable final Supplier label, @GpuBuffer.Usage final int usage, final long size) { int buffer = dsa.createBuffer(); dsa.bufferStorage(buffer, size, usage); return new GlBuffer(label, dsa, usage, size, buffer, true); } @Override public GlBuffer createBuffer(final DirectStateAccess dsa, @Nullable final Supplier label, @GpuBuffer.Usage final int usage, final ByteBuffer data) { int buffer = dsa.createBuffer(); int size = data.remaining(); dsa.bufferStorage(buffer, data, usage); return new GlBuffer(label, dsa, usage, size, buffer, true); } } private static class Mutable extends BufferStorage { @Override public GlBuffer createBuffer(final DirectStateAccess dsa, @Nullable final Supplier label, @GpuBuffer.Usage final int usage, final long size) { int buffer = dsa.createBuffer(); dsa.bufferData(buffer, size, usage); return new GlBuffer(label, dsa, usage, size, buffer, false); } @Override public GlBuffer createBuffer(final DirectStateAccess dsa, @Nullable final Supplier label, @GpuBuffer.Usage final int usage, final ByteBuffer data) { int buffer = dsa.createBuffer(); int size = data.remaining(); dsa.bufferData(buffer, data, usage); return new GlBuffer(label, dsa, usage, size, buffer, false); } } }