| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package sun.java2d.pipe;  | 
 | 
 | 
 | 
import sun.misc.Unsafe;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
public class RenderBuffer { | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    protected static final long SIZEOF_BYTE   = 1L;  | 
 | 
    protected static final long SIZEOF_SHORT  = 2L;  | 
 | 
    protected static final long SIZEOF_INT    = 4L;  | 
 | 
    protected static final long SIZEOF_FLOAT  = 4L;  | 
 | 
    protected static final long SIZEOF_LONG   = 8L;  | 
 | 
    protected static final long SIZEOF_DOUBLE = 8L;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private static final int COPY_FROM_ARRAY_THRESHOLD = 6;  | 
 | 
 | 
 | 
    protected final Unsafe unsafe;  | 
 | 
    protected final long baseAddress;  | 
 | 
    protected final long endAddress;  | 
 | 
    protected long curAddress;  | 
 | 
    protected final int capacity;  | 
 | 
 | 
 | 
    protected RenderBuffer(int numBytes) { | 
 | 
        unsafe = Unsafe.getUnsafe();  | 
 | 
        curAddress = baseAddress = unsafe.allocateMemory(numBytes);  | 
 | 
        endAddress = baseAddress + numBytes;  | 
 | 
        capacity = numBytes;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public static RenderBuffer allocate(int numBytes) { | 
 | 
        return new RenderBuffer(numBytes);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public final long getAddress() { | 
 | 
        return baseAddress;  | 
 | 
    }  | 
 | 
 | 
 | 
    /**  | 
 | 
     * The behavior (and names) of the following methods are nearly  | 
 | 
     * identical to their counterparts in the various NIO Buffer classes.  | 
 | 
     */  | 
 | 
 | 
 | 
    public final int capacity() { | 
 | 
        return capacity;  | 
 | 
    }  | 
 | 
 | 
 | 
    public final int remaining() { | 
 | 
        return (int)(endAddress - curAddress);  | 
 | 
    }  | 
 | 
 | 
 | 
    public final int position() { | 
 | 
        return (int)(curAddress - baseAddress);  | 
 | 
    }  | 
 | 
 | 
 | 
    public final void position(long numBytes) { | 
 | 
        curAddress = baseAddress + numBytes;  | 
 | 
    }  | 
 | 
 | 
 | 
    public final void clear() { | 
 | 
        curAddress = baseAddress;  | 
 | 
    }  | 
 | 
 | 
 | 
    public final RenderBuffer skip(long numBytes) { | 
 | 
        curAddress += numBytes;  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    /**  | 
 | 
     * putByte() methods...  | 
 | 
     */  | 
 | 
 | 
 | 
    public final RenderBuffer putByte(byte x) { | 
 | 
        unsafe.putByte(curAddress, x);  | 
 | 
        curAddress += SIZEOF_BYTE;  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    public RenderBuffer put(byte[] x) { | 
 | 
        return put(x, 0, x.length);  | 
 | 
    }  | 
 | 
 | 
 | 
    public RenderBuffer put(byte[] x, int offset, int length) { | 
 | 
        if (length > COPY_FROM_ARRAY_THRESHOLD) { | 
 | 
            long offsetInBytes = offset * SIZEOF_BYTE + Unsafe.ARRAY_BYTE_BASE_OFFSET;  | 
 | 
            long lengthInBytes = length * SIZEOF_BYTE;  | 
 | 
            unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);  | 
 | 
            position(position() + lengthInBytes);  | 
 | 
        } else { | 
 | 
            int end = offset + length;  | 
 | 
            for (int i = offset; i < end; i++) { | 
 | 
                putByte(x[i]);  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    /**  | 
 | 
     * putShort() methods...  | 
 | 
     */  | 
 | 
 | 
 | 
    public final RenderBuffer putShort(short x) { | 
 | 
          | 
 | 
        unsafe.putShort(curAddress, x);  | 
 | 
        curAddress += SIZEOF_SHORT;  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    public RenderBuffer put(short[] x) { | 
 | 
        return put(x, 0, x.length);  | 
 | 
    }  | 
 | 
 | 
 | 
    public RenderBuffer put(short[] x, int offset, int length) { | 
 | 
          | 
 | 
        if (length > COPY_FROM_ARRAY_THRESHOLD) { | 
 | 
            long offsetInBytes = offset * SIZEOF_SHORT + Unsafe.ARRAY_SHORT_BASE_OFFSET;  | 
 | 
            long lengthInBytes = length * SIZEOF_SHORT;  | 
 | 
            unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);  | 
 | 
            position(position() + lengthInBytes);  | 
 | 
        } else { | 
 | 
            int end = offset + length;  | 
 | 
            for (int i = offset; i < end; i++) { | 
 | 
                putShort(x[i]);  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    /**  | 
 | 
     * putInt() methods...  | 
 | 
     */  | 
 | 
 | 
 | 
    public final RenderBuffer putInt(int pos, int x) { | 
 | 
          | 
 | 
        unsafe.putInt(baseAddress + pos, x);  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    public final RenderBuffer putInt(int x) { | 
 | 
          | 
 | 
        unsafe.putInt(curAddress, x);  | 
 | 
        curAddress += SIZEOF_INT;  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    public RenderBuffer put(int[] x) { | 
 | 
        return put(x, 0, x.length);  | 
 | 
    }  | 
 | 
 | 
 | 
    public RenderBuffer put(int[] x, int offset, int length) { | 
 | 
          | 
 | 
        if (length > COPY_FROM_ARRAY_THRESHOLD) { | 
 | 
            long offsetInBytes = offset * SIZEOF_INT + Unsafe.ARRAY_INT_BASE_OFFSET;  | 
 | 
            long lengthInBytes = length * SIZEOF_INT;  | 
 | 
            unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);  | 
 | 
            position(position() + lengthInBytes);  | 
 | 
        } else { | 
 | 
            int end = offset + length;  | 
 | 
            for (int i = offset; i < end; i++) { | 
 | 
                putInt(x[i]);  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    /**  | 
 | 
     * putFloat() methods...  | 
 | 
     */  | 
 | 
 | 
 | 
    public final RenderBuffer putFloat(float x) { | 
 | 
          | 
 | 
        unsafe.putFloat(curAddress, x);  | 
 | 
        curAddress += SIZEOF_FLOAT;  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    public RenderBuffer put(float[] x) { | 
 | 
        return put(x, 0, x.length);  | 
 | 
    }  | 
 | 
 | 
 | 
    public RenderBuffer put(float[] x, int offset, int length) { | 
 | 
          | 
 | 
        if (length > COPY_FROM_ARRAY_THRESHOLD) { | 
 | 
            long offsetInBytes = offset * SIZEOF_FLOAT + Unsafe.ARRAY_FLOAT_BASE_OFFSET;  | 
 | 
            long lengthInBytes = length * SIZEOF_FLOAT;  | 
 | 
            unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);  | 
 | 
            position(position() + lengthInBytes);  | 
 | 
        } else { | 
 | 
            int end = offset + length;  | 
 | 
            for (int i = offset; i < end; i++) { | 
 | 
                putFloat(x[i]);  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    /**  | 
 | 
     * putLong() methods...  | 
 | 
     */  | 
 | 
 | 
 | 
    public final RenderBuffer putLong(long x) { | 
 | 
          | 
 | 
        unsafe.putLong(curAddress, x);  | 
 | 
        curAddress += SIZEOF_LONG;  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    public RenderBuffer put(long[] x) { | 
 | 
        return put(x, 0, x.length);  | 
 | 
    }  | 
 | 
 | 
 | 
    public RenderBuffer put(long[] x, int offset, int length) { | 
 | 
          | 
 | 
        if (length > COPY_FROM_ARRAY_THRESHOLD) { | 
 | 
            long offsetInBytes = offset * SIZEOF_LONG + Unsafe.ARRAY_LONG_BASE_OFFSET;  | 
 | 
            long lengthInBytes = length * SIZEOF_LONG;  | 
 | 
            unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes);  | 
 | 
            position(position() + lengthInBytes);  | 
 | 
        } else { | 
 | 
            int end = offset + length;  | 
 | 
            for (int i = offset; i < end; i++) { | 
 | 
                putLong(x[i]);  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
 | 
 | 
    /**  | 
 | 
     * putDouble() method(s)...  | 
 | 
     */  | 
 | 
 | 
 | 
    public final RenderBuffer putDouble(double x) { | 
 | 
          | 
 | 
        unsafe.putDouble(curAddress, x);  | 
 | 
        curAddress += SIZEOF_DOUBLE;  | 
 | 
        return this;  | 
 | 
    }  | 
 | 
}  |