/gdx/src/com/badlogic/gdx/utils/BufferUtils.java
Java | 284 lines | 127 code | 23 blank | 134 comment | 45 complexity | dc0dd332cc141f899f1a340a0e97aa7f MD5 | raw file
- /*******************************************************************************
- * Copyright 2011 See AUTHORS file.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
- package com.badlogic.gdx.utils;
-
- import java.nio.Buffer;
- import java.nio.ByteBuffer;
- import java.nio.ByteOrder;
- import java.nio.CharBuffer;
- import java.nio.DoubleBuffer;
- import java.nio.FloatBuffer;
- import java.nio.IntBuffer;
- import java.nio.LongBuffer;
- import java.nio.ShortBuffer;
-
- /**
- * Class with static helper methods to increase the speed of array/direct buffer and direct buffer/direct buffer transfers
- *
- * @author mzechner
- *
- */
- public class BufferUtils {
- /**
- * Frees the memory allocated for the ByteBuffer. DO NOT USE THIS ON BYTEBUFFERS ALLOCATEd
- * VIA METHODS IN THIS CLASS OR ByteBuffer.allocateDirect()! IT WILL EXPLODE!
- */
- public static native void freeMemory(ByteBuffer buffer) /*-{ }-*/;
-
- /**
- * Copies numFloats floats from src starting at offset to dst. Dst is assumed to be a direct {@link Buffer}. The method will
- * crash if that is not the case. The position and limit of the buffer are ignored, the copy is placed at position 0 in the
- * buffer. After the copying process the position of the buffer is set to 0 and its limit is set to numFloats * 4 if it is a
- * ByteBuffer and numFloats if it is a FloatBuffer. In case the Buffer is neither a ByteBuffer nor a FloatBuffer the limit is
- * not set. This is an expert method, use at your own risk.
- *
- * @param src the source array
- * @param dst the destination buffer, has to be a direct Buffer
- * @param numFloats the number of floats to copy
- * @param offset the offset in src to start copying from
- */
- public static void copy (float[] src, Buffer dst, int numFloats, int offset) {
- copyJni(src, dst, numFloats, offset);
- dst.position(0);
-
- if (dst instanceof ByteBuffer)
- dst.limit(numFloats << 2);
- else if (dst instanceof FloatBuffer) dst.limit(numFloats);
- }
-
- /**
- * Copies the contents of src to dst, starting from src[srcOffset], copying numElements
- * elements. The {@link Buffer} instance's {@link Buffer#position()} is used to define
- * the offset into the Buffer itself. The position will stay the same, the limit will be
- * set to position + numElements. <b>The Buffer must be a direct Buffer with native byte order.
- * No error checking is performed</b>.
- *
- * @param src the source array.
- * @param srcOffset the offset into the source array.
- * @param dst the destination Buffer, its position is used as an offset.
- * @param numElements the number of elements to copy.
- */
- public static void copy (byte[] src, int srcOffset, Buffer dst, int numElements) {
- copyJni(src, srcOffset, dst, positionInBytes(dst), numElements);
- dst.limit(dst.position() + bytesToElements(dst, numElements));
- }
-
- /**
- * Copies the contents of src to dst, starting from src[srcOffset], copying numElements
- * elements. The {@link Buffer} instance's {@link Buffer#position()} is used to define
- * the offset into the Buffer itself. The position will stay the same, the limit will be
- * set to position + numElements. <b>The Buffer must be a direct Buffer with native byte order.
- * No error checking is performed</b>.
- *
- * @param src the source array.
- * @param srcOffset the offset into the source array.
- * @param dst the destination Buffer, its position is used as an offset.
- * @param numElements the number of elements to copy.
- */
- public static void copy (short[] src, int srcOffset, Buffer dst, int numElements) {
- copyJni(src, srcOffset << 1, dst, positionInBytes(dst), numElements << 1);
- dst.limit(dst.position() + bytesToElements(dst, numElements << 1));
- }
-
- /**
- * Copies the contents of src to dst, starting from src[srcOffset], copying numElements
- * elements. The {@link Buffer} instance's {@link Buffer#position()} is used to define
- * the offset into the Buffer itself. The position will stay the same, the limit will be
- * set to position + numElements. <b>The Buffer must be a direct Buffer with native byte order.
- * No error checking is performed</b>.
- *
- * @param src the source array.
- * @param srcOffset the offset into the source array.
- * @param dst the destination Buffer, its position is used as an offset.
- * @param numElements the number of elements to copy.
- */
- public static void copy (char[] src, int srcOffset, Buffer dst, int numElements) {
- copyJni(src, srcOffset << 1, dst, positionInBytes(dst), numElements << 1);
- dst.limit(dst.position() + bytesToElements(dst, numElements << 1));
- }
-
- /**
- * Copies the contents of src to dst, starting from src[srcOffset], copying numElements
- * elements. The {@link Buffer} instance's {@link Buffer#position()} is used to define
- * the offset into the Buffer itself. The position will stay the same, the limit will be
- * set to position + numElements. <b>The Buffer must be a direct Buffer with native byte order.
- * No error checking is performed</b>.
- *
- * @param src the source array.
- * @param srcOffset the offset into the source array.
- * @param dst the destination Buffer, its position is used as an offset.
- * @param numElements the number of elements to copy.
- */
- public static void copy (int[] src, int srcOffset, Buffer dst, int numElements) {
- copyJni(src, srcOffset << 2, dst, positionInBytes(dst), numElements << 2);
- dst.limit(dst.position() + bytesToElements(dst, numElements << 2));
- }
-
- /**
- * Copies the contents of src to dst, starting from src[srcOffset], copying numElements
- * elements. The {@link Buffer} instance's {@link Buffer#position()} is used to define
- * the offset into the Buffer itself. The position will stay the same, the limit will be
- * set to position + numElements. <b>The Buffer must be a direct Buffer with native byte order.
- * No error checking is performed</b>.
- *
- * @param src the source array.
- * @param srcOffset the offset into the source array.
- * @param dst the destination Buffer, its position is used as an offset.
- * @param numElements the number of elements to copy.
- */
- public static void copy (long[] src, int srcOffset, Buffer dst, int numElements) {
- copyJni(src, srcOffset << 3, dst, positionInBytes(dst), numElements << 3);
- dst.limit(dst.position() + bytesToElements(dst, numElements << 3));
- }
-
- /**
- * Copies the contents of src to dst, starting from src[srcOffset], copying numElements
- * elements. The {@link Buffer} instance's {@link Buffer#position()} is used to define
- * the offset into the Buffer itself. The position will stay the same, the limit will be
- * set to position + numElements. <b>The Buffer must be a direct Buffer with native byte order.
- * No error checking is performed</b>.
- *
- * @param src the source array.
- * @param srcOffset the offset into the source array.
- * @param dst the destination Buffer, its position is used as an offset.
- * @param numElements the number of elements to copy.
- */
- public static void copy (float[] src, int srcOffset, Buffer dst, int numElements) {
- copyJni(src, srcOffset << 2, dst, positionInBytes(dst), numElements << 2);
- dst.limit(dst.position() + bytesToElements(dst, numElements << 2));
- }
-
- /**
- * Copies the contents of src to dst, starting from src[srcOffset], copying numElements
- * elements. The {@link Buffer} instance's {@link Buffer#position()} is used to define
- * the offset into the Buffer itself. The position will stay the same, the limit will be
- * set to position + numElements. <b>The Buffer must be a direct Buffer with native byte order.
- * No error checking is performed</b>.
- *
- * @param src the source array.
- * @param srcOffset the offset into the source array.
- * @param dst the destination Buffer, its position is used as an offset.
- * @param numElements the number of elements to copy.
- */
- public static void copy (double[] src, int srcOffset, Buffer dst, int numElements) {
- copyJni(src, srcOffset << 3, dst, positionInBytes(dst), numElements << 3);
- dst.limit(dst.position() + bytesToElements(dst, numElements << 3));
- }
-
- /**
- * Copies the contents of src to dst, starting from the current position of src, copying
- * numElements elements (using the data type of src, no matter the datatype of dst). The
- * dst {@link Buffer#position()} is used as the writing offset. The position of both Buffers
- * will stay the same. The limit of the src Buffer will stay the same. The limit of the dst Buffer
- * will be set to dst.position() + numElements, where numElements are translated to the number of
- * elements appropriate for the dst Buffer data type. <b>The Buffers must be direct Buffers with native byte order.
- * No error checking is performed</b>.
- *
- * @param src the source Buffer.
- * @param dst the destination Buffer.
- * @param numElements the number of elements to copy.
- */
- public static void copy(Buffer src, Buffer dst, int numElements) {
- int numBytes = elementsToBytes(src, numElements);
- copyJni(src, positionInBytes(src), dst, positionInBytes(dst), numBytes);
- dst.limit(dst.position() + bytesToElements(dst, numBytes));
- }
-
- private static int positionInBytes(Buffer dst) {
- if(dst instanceof ByteBuffer) return dst.position();
- else if(dst instanceof ShortBuffer) return dst.position() << 1;
- else if(dst instanceof CharBuffer) return dst.position() << 1;
- else if(dst instanceof IntBuffer) return dst.position() << 2;
- else if(dst instanceof LongBuffer) return dst.position() << 3;
- else if(dst instanceof FloatBuffer) return dst.position() << 2;
- else if(dst instanceof DoubleBuffer) return dst.position() << 3;
- else throw new GdxRuntimeException("Can't copy to a " + dst.getClass().getName() + " instance");
- }
-
- private static int bytesToElements(Buffer dst, int bytes) {
- if(dst instanceof ByteBuffer) return bytes;
- else if(dst instanceof ShortBuffer) return bytes >>> 1;
- else if(dst instanceof CharBuffer) return bytes >>> 1;
- else if(dst instanceof IntBuffer) return bytes >>> 2;
- else if(dst instanceof LongBuffer) return bytes >>> 3;
- else if(dst instanceof FloatBuffer) return bytes >>> 2;
- else if(dst instanceof DoubleBuffer) return bytes >>> 3;
- else throw new GdxRuntimeException("Can't copy to a " + dst.getClass().getName() + " instance");
- }
-
- private static int elementsToBytes(Buffer dst, int elements) {
- if(dst instanceof ByteBuffer) return elements;
- else if(dst instanceof ShortBuffer) return elements << 1;
- else if(dst instanceof CharBuffer) return elements << 1;
- else if(dst instanceof IntBuffer) return elements << 2;
- else if(dst instanceof LongBuffer) return elements << 3;
- else if(dst instanceof FloatBuffer) return elements << 2;
- else if(dst instanceof DoubleBuffer) return elements << 3;
- else throw new GdxRuntimeException("Can't copy to a " + dst.getClass().getName() + " instance");
- }
-
- private native static void copyJni (float[] src, Buffer dst, int numFloats, int offset) /*-{ }-*/;
- private native static void copyJni (byte[] src, int srcOffset, Buffer dst, int dstOffset, int numBytes) /*-{ }-*/;
- private native static void copyJni (char[] src, int srcOffset, Buffer dst, int dstOffset, int numBytes) /*-{ }-*/;
- private native static void copyJni (short[] src, int srcOffset, Buffer dst, int dstOffset, int numBytes) /*-{ }-*/;
- private native static void copyJni (int[] src, int srcOffset, Buffer dst, int dstOffset, int numBytes) /*-{ }-*/;
- private native static void copyJni (long[] src, int srcOffset, Buffer dst, int dstOffset, int numBytes) /*-{ }-*/;
- private native static void copyJni (float[] src, int srcOffset, Buffer dst, int dstOffset, int numBytes) /*-{ }-*/;
- private native static void copyJni (double[] src, int srcOffset, Buffer dst, int dstOffset, int numBytes) /*-{ }-*/;
- private native static void copyJni (Buffer src, int srcOffset, Buffer dst, int dstOffset, int numBytes) /*-{ }-*/;
-
- public static FloatBuffer newFloatBuffer (int numFloats) {
- ByteBuffer buffer = ByteBuffer.allocateDirect(numFloats * 4);
- buffer.order(ByteOrder.nativeOrder());
- return buffer.asFloatBuffer();
- }
-
- public static DoubleBuffer newDoubleBuffer (int numDoubles) {
- ByteBuffer buffer = ByteBuffer.allocateDirect(numDoubles * 8);
- buffer.order(ByteOrder.nativeOrder());
- return buffer.asDoubleBuffer();
- }
-
- public static ByteBuffer newByteBuffer (int numBytes) {
- ByteBuffer buffer = ByteBuffer.allocateDirect(numBytes);
- buffer.order(ByteOrder.nativeOrder());
- return buffer;
- }
-
- public static ShortBuffer newShortBuffer (int numShorts) {
- ByteBuffer buffer = ByteBuffer.allocateDirect(numShorts * 2);
- buffer.order(ByteOrder.nativeOrder());
- return buffer.asShortBuffer();
- }
-
- public static CharBuffer newCharBuffer(int numChars) {
- ByteBuffer buffer = ByteBuffer.allocateDirect(numChars * 2);
- buffer.order(ByteOrder.nativeOrder());
- return buffer.asCharBuffer();
- }
-
- public static IntBuffer newIntBuffer (int numInts) {
- ByteBuffer buffer = ByteBuffer.allocateDirect(numInts * 4);
- buffer.order(ByteOrder.nativeOrder());
- return buffer.asIntBuffer();
- }
-
- public static LongBuffer newLongBuffer (int numLongs) {
- ByteBuffer buffer = ByteBuffer.allocateDirect(numLongs * 8);
- buffer.order(ByteOrder.nativeOrder());
- return buffer.asLongBuffer();
- }
- }