Fast Float Buffer : Buffer « File « Android






Fast Float Buffer

    
//package com.ryanm.droid.rugl.util;

import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

/**
 * Convenient work-around for poor {@link FloatBuffer#put(float[])} performance.
 * This should become unnecessary in gingerbread, @see <a href
 * ="http://code.google.com/p/android/issues/detail?id=11078">Issue 11078</a>
 * 
 * @author ryanm
 */
public class FastFloatBuffer {
  /**
   * Underlying data - give this to OpenGL
   */
  public ByteBuffer bytes;

  private FloatBuffer floats;

  private IntBuffer ints;

  /**
   * Use a {@link SoftReference} so that the array can be collected if
   * necessary
   */
  private static SoftReference<int[]> intArray = new SoftReference<int[]>(
      new int[0]);

  /**
   * Constructs a new direct native-ordered buffer
   * 
   * @param capacity
   *            the number of floats
   */
  public FastFloatBuffer(int capacity) {
    bytes = ByteBuffer.allocateDirect((capacity * 4)).order(
        ByteOrder.nativeOrder());
    floats = bytes.asFloatBuffer();
    ints = bytes.asIntBuffer();
  }

  /**
   * See {@link FloatBuffer#flip()}
   */
  public void flip() {
    bytes.flip();
    floats.flip();
    ints.flip();
  }

  /**
   * See {@link FloatBuffer#put(float)}
   * 
   * @param f
   */
  public void put(float f) {
    bytes.position(bytes.position() + 4);
    floats.put(f);
    ints.position(ints.position() + 1);
  }

  /**
   * It's like {@link FloatBuffer#put(float[])}, but about 10 times faster
   * 
   * @param data
   */
  public void put(float[] data) {
    int[] ia = intArray.get();
    if (ia == null || ia.length < data.length) {
      ia = new int[data.length];
      intArray = new SoftReference<int[]>(ia);
    }

    for (int i = 0; i < data.length; i++) {
      ia[i] = Float.floatToRawIntBits(data[i]);
    }

    bytes.position(bytes.position() + 4 * data.length);
    floats.position(floats.position() + data.length);
    ints.put(ia, 0, data.length);
  }

  /**
   * For use with pre-converted data. This is 50x faster than
   * {@link #put(float[])}, and 500x faster than
   * {@link FloatBuffer#put(float[])}, so if you've got float[] data that
   * won't change, {@link #convert(float...)} it to an int[] once and use this
   * method to put it in the buffer
   * 
   * @param data
   *            floats that have been converted with
   *            {@link Float#floatToIntBits(float)}
   */
  public void put(int[] data) {
    bytes.position(bytes.position() + 4 * data.length);
    floats.position(floats.position() + data.length);
    ints.put(data, 0, data.length);
  }

  /**
   * Converts float data to a format that can be quickly added to the buffer
   * with {@link #put(int[])}
   * 
   * @param data
   * @return the int-formatted data
   */
  public static int[] convert(float... data) {
    int[] id = new int[data.length];
    for (int i = 0; i < data.length; i++) {
      id[i] = Float.floatToRawIntBits(data[i]);
    }

    return id;
  }

  /**
   * See {@link FloatBuffer#put(FloatBuffer)}
   * 
   * @param b
   */
  public void put(FastFloatBuffer b) {
    bytes.put(b.bytes);
    floats.position(bytes.position() >> 2);
    ints.position(bytes.position() >> 2);
  }

  /**
   * @return See {@link FloatBuffer#capacity()}
   */
  public int capacity() {
    return floats.capacity();
  }

  /**
   * @return See {@link FloatBuffer#position()}
   */
  public int position() {
    return floats.position();
  }

  /**
   * See {@link FloatBuffer#position(int)}
   * 
   * @param p
   */
  public void position(int p) {
    bytes.position(4 * p);
    floats.position(p);
    ints.position(p);
  }

  /**
   * @return See {@link FloatBuffer#slice()}
   */
  public FloatBuffer slice() {
    return floats.slice();
  }

  /**
   * @return See {@link FloatBuffer#remaining()}
   */
  public int remaining() {
    return floats.remaining();
  }

  /**
   * @return See {@link FloatBuffer#limit()}
   */
  public int limit() {
    return floats.limit();
  }

  /**
   * See {@link FloatBuffer#clear()}
   */
  public void clear() {
    bytes.clear();
    floats.clear();
    ints.clear();
  }
}

   
    
    
    
  








Related examples in the same category

1.Demonstrate the Frame Buffer Object OpenGL ES extension.
2.Loads a file to a ByteBuffer.
3.Make a direct NIO FloatBuffer from an array of floats
4.Make a direct NIO ByteBuffer from an array of bytes
5.Make Float Buffer From Array
6.Creates a floatbuffer of the given size.
7.Make Float Buffer with ByteBuffer.allocateDirect
8.allocate Float Buffer
9.to Short Buffer
10.to Float Buffer Position Zero
11.allocate Short Buffer
12.allocate Int Buffer
13.Read InputStream with BufferedReader
14.To convert the InputStream to String we use the BufferedReader.readLine() method.
15.make Float Buffer
16.get Buffer From Array
17.Your own float buffer
18.Direct Buffer
19.create Buffer
20.Write String to File with BufferWriter
21.Byte Buffer Stack
22.Compute the SHA-1 hash of the bytes in the given buffer
23.An utility class for java.nio.Buffers