Description
ReflectionAllocator uses java.nio.ByteByffer.allocateDirect()
which always initializes new buffers to all zeros.
LWJGLBufferAllocator uses org.lwjgl.system.MemoryUtil.nmemAlloc()
which does not make the same guarantee. (nmemAlloc doesn't have much documentation, just redirects to this memAlloc description)
Strangely, it seems that this discrepancy only starts manifesting after buffers have been destroyed, so it isn't immediately obvious. Since the uninitialized data is overwritten immediately 99% of the time, it's not a big deal, but my understanding is that LWJGLBufferAllocator is intended to be a drop-in replacement for ReflectionAllocator.
Here's an MRE:
public static void main(String[] args)
{
//comment this line out to use ReflectionAllocator
System.setProperty(BufferAllocatorFactory.PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION, LWJGLBufferAllocator.class.getName());
FloatBuffer buff = BufferUtils.createFloatBuffer(1_000_000);
//strangely, this one is always(?) zero'd
for(int i = 0; i < buff.capacity(); i++)
assert buff.get(i) == 0f;
//put some random garbage into it and destroy it
for(int i = 0; i < buff.capacity(); i++)
buff.put(i, FastMath.rand.nextFloat());
BufferUtils.destroyDirectBuffer(buff);
//create another buffer, should contain all zeros like the first one
FloatBuffer buff2 = BufferUtils.createFloatBuffer(1_000_000);
//using ReflectionAllocator == A-OK
//using LWJGLBufferAllocator == crash
for(int i = 0; i < buff2.capacity(); i++)
assert buff2.get(i) == 0f;
}
Possible fix could be to add a MemoryUtil.memSet() call after nmemAlloc(). I can test it out and make a PR later if y'all want.