Package org.lwjgl

Class BufferUtils

java.lang.Object
org.lwjgl.BufferUtils

public final class BufferUtils extends Object

This class makes it easy and safe to work with direct buffers. It is the recommended way to allocate memory to use with LWJGL.

Direct buffers

LWJGL requires that all NIO buffers passed to it are direct buffers. Direct buffers essentially wrap an address that points to off-heap memory, i.e. a native pointer. This is the only way LWJGL can safely pass data from Java code to native code, and vice-versa, without a performance penalty. It does not support on-heap Java arrays (or plain NIO buffers, which wrap them) because arrays may be moved around in memory by the JVM's garbage collector while native code is accessing them. In addition, Java arrays have an unspecified layout, i.e. they are not necessarily contiguous in memory.

Usage

When a direct buffer is passed as an argument to an LWJGL method, no data is copied. Instead, the current buffer position is added to the buffer's memory address and the resulting value is passed to native code. The native code interprets that value as a pointer and reads or copies from it as necessary. LWJGL will often also use the current buffer limit (via Buffer.remaining()) to automatically pass length/maxlength arguments. This means that, just like other APIs that use NIO buffers, the current Buffer.position() and Buffer.limit() at the time of the call is very important. Contrary to other APIs, LWJGL never modifies the current position, it will be the same value before and after the call.

Arrays of pointers

In addition to the standard NIO buffer classes, LWJGL provides a PointerBuffer class for storing pointer data in an architecture independent way. It is used in bindings for pointer-to-pointers arguments, usually to provide arrays of data (input parameter) or to store returned pointer values (output parameter). Also, there's the CLongBuffer class which is similar to PointerBuffer, but for C long data.

Memory management

Using NIO buffers for off-heap memory has some drawbacks:

  • Memory blocks bigger than Integer.MAX_VALUE bytes cannot be allocated.
  • Memory blocks are zeroed-out on allocation, for safety. This has (sometimes unwanted) performance implications.
  • There is no way to free a buffer explicitly (without JVM specific reflection). Buffer objects are subject to GC and it usually takes two GC cycles to free the off-heap memory after the buffer object becomes unreachable.

An alternative API for allocating off-heap memory can be found in the MemoryUtil class. This has none of the above drawbacks, but requires allocated memory to be explictly freed when not used anymore.

Memory alignment

Allocations done via this class have a guaranteed alignment of 8 bytes. If higher alignment values are required, use the explicit memory management API or pad the requested memory with extra bytes and align manually.

Structs and arrays of structs

Java does not support struct value types, so LWJGL requires struct values that are backed by off-heap memory. Each struct type defined in a binding has a corresponding class in LWJGL that can be used to access its members. Each struct class also has a Buffer inner class that can be used to access (packed) arrays of struct values. Both struct and struct buffer classes may be backed by direct ByteBuffers allocated from this class, but it is highly recommended to use explicit memory management for performance.

  • Method Summary

    Modifier and Type
    Method
    Description
    static ByteBuffer
    createByteBuffer(int capacity)
    Allocates a direct native-ordered ByteBuffer with the specified capacity.
    static CharBuffer
    createCharBuffer(int capacity)
    Allocates a direct native-order CharBuffer with the specified number of elements.
    createCLongBuffer(int capacity)
    Allocates a CLongBuffer with the specified number of elements.
    createDoubleBuffer(int capacity)
    Allocates a direct native-order DoubleBuffer with the specified number of elements.
    createFloatBuffer(int capacity)
    Allocates a direct native-order FloatBuffer with the specified number of elements.
    static IntBuffer
    createIntBuffer(int capacity)
    Allocates a direct native-order IntBuffer with the specified number of elements.
    static LongBuffer
    createLongBuffer(int capacity)
    Allocates a direct native-order LongBuffer with the specified number of elements.
    createPointerBuffer(int capacity)
    Allocates a PointerBuffer with the specified number of elements.
    createShortBuffer(int capacity)
    Allocates a direct native-order ShortBuffer with the specified number of elements.
    static void
    Fills the specified buffer with zeros from the current position to the current limit.
    static void
    Fills the specified buffer with zeros from the current position to the current limit.
    static void
    Fills the specified buffer with zeros from the current position to the current limit.
    static void
    Fills the specified buffer with zeros from the current position to the current limit.
    static void
    Fills the specified buffer with zeros from the current position to the current limit.
    static void
    Fills the specified buffer with zeros from the current position to the current limit.
    static void
    Fills the specified buffer with zeros from the current position to the current limit.
    static <T extends CustomBuffer<T>>
    void
    zeroBuffer(T buffer)
    Fills the specified buffer with zeros from the current position to the current limit.

    Methods inherited from class java.lang.Object

    equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • createByteBuffer

      public static ByteBuffer createByteBuffer(int capacity)
      Allocates a direct native-ordered ByteBuffer with the specified capacity.
      Parameters:
      capacity - the capacity, in bytes
      Returns:
      a ByteBuffer
    • createShortBuffer

      public static ShortBuffer createShortBuffer(int capacity)
      Allocates a direct native-order ShortBuffer with the specified number of elements.
      Parameters:
      capacity - the capacity, in shorts
      Returns:
      a ShortBuffer
    • createCharBuffer

      public static CharBuffer createCharBuffer(int capacity)
      Allocates a direct native-order CharBuffer with the specified number of elements.
      Parameters:
      capacity - the capacity, in chars
      Returns:
      a CharBuffer
    • createIntBuffer

      public static IntBuffer createIntBuffer(int capacity)
      Allocates a direct native-order IntBuffer with the specified number of elements.
      Parameters:
      capacity - the capacity, in ints
      Returns:
      an IntBuffer
    • createLongBuffer

      public static LongBuffer createLongBuffer(int capacity)
      Allocates a direct native-order LongBuffer with the specified number of elements.
      Parameters:
      capacity - the capacity, in longs
      Returns:
      a LongBuffer
    • createCLongBuffer

      public static CLongBuffer createCLongBuffer(int capacity)
      Allocates a CLongBuffer with the specified number of elements.
      Parameters:
      capacity - the capacity, in memory addresses
      Returns:
      a CLongBuffer
    • createFloatBuffer

      public static FloatBuffer createFloatBuffer(int capacity)
      Allocates a direct native-order FloatBuffer with the specified number of elements.
      Parameters:
      capacity - the capacity, in floats
      Returns:
      a FloatBuffer
    • createDoubleBuffer

      public static DoubleBuffer createDoubleBuffer(int capacity)
      Allocates a direct native-order DoubleBuffer with the specified number of elements.
      Parameters:
      capacity - the capacity, in doubles
      Returns:
      a DoubleBuffer
    • createPointerBuffer

      public static PointerBuffer createPointerBuffer(int capacity)
      Allocates a PointerBuffer with the specified number of elements.
      Parameters:
      capacity - the capacity, in memory addresses
      Returns:
      a PointerBuffer
    • zeroBuffer

      public static void zeroBuffer(ByteBuffer buffer)
      Fills the specified buffer with zeros from the current position to the current limit.
      Parameters:
      buffer - the buffer to fill with zeros
    • zeroBuffer

      public static void zeroBuffer(ShortBuffer buffer)
      Fills the specified buffer with zeros from the current position to the current limit.
      Parameters:
      buffer - the buffer to fill with zeros
    • zeroBuffer

      public static void zeroBuffer(CharBuffer buffer)
      Fills the specified buffer with zeros from the current position to the current limit.
      Parameters:
      buffer - the buffer to fill with zeros
    • zeroBuffer

      public static void zeroBuffer(IntBuffer buffer)
      Fills the specified buffer with zeros from the current position to the current limit.
      Parameters:
      buffer - the buffer to fill with zeros
    • zeroBuffer

      public static void zeroBuffer(FloatBuffer buffer)
      Fills the specified buffer with zeros from the current position to the current limit.
      Parameters:
      buffer - the buffer to fill with zeros
    • zeroBuffer

      public static void zeroBuffer(LongBuffer buffer)
      Fills the specified buffer with zeros from the current position to the current limit.
      Parameters:
      buffer - the buffer to fill with zeros
    • zeroBuffer

      public static void zeroBuffer(DoubleBuffer buffer)
      Fills the specified buffer with zeros from the current position to the current limit.
      Parameters:
      buffer - the buffer to fill with zeros
    • zeroBuffer

      public static <T extends CustomBuffer<T>> void zeroBuffer(T buffer)
      Fills the specified buffer with zeros from the current position to the current limit.
      Parameters:
      buffer - the buffer to fill with zeros