Rewrote FieldPack::createFieldPack for alignment

b/20032217

Some data types requires data alignment. This has an impact on the
total data size for the FieldPack. Fixed createFiledPack()
implementation to handle this correctly.

Change-Id: I241da19df69bf51cfdaf3b3a1381b446eaacb7fb
diff --git a/rs/java/android/renderscript/FieldPacker.java b/rs/java/android/renderscript/FieldPacker.java
index 0f967fc..de1c497 100644
--- a/rs/java/android/renderscript/FieldPacker.java
+++ b/rs/java/android/renderscript/FieldPacker.java
@@ -47,6 +47,15 @@
         // subAlign() can never work correctly for copied FieldPacker objects.
     }
 
+    static FieldPacker createFromArray(Object[] args) {
+        FieldPacker fp = new FieldPacker(RenderScript.sPointerSize * 8);
+        for (Object arg : args) {
+            fp.addSafely(arg);
+        }
+        fp.resize(fp.mPos);
+        return fp;
+    }
+
     public void align(int v) {
         if ((v <= 0) || ((v & (v - 1)) != 0)) {
             throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
@@ -618,294 +627,182 @@
         return mPos;
     }
 
-    private static void addToPack(FieldPacker fp, Object obj) {
+    private void add(Object obj) {
         if (obj instanceof Boolean) {
-            fp.addBoolean(((Boolean)obj).booleanValue());
+            addBoolean((Boolean)obj);
             return;
         }
 
         if (obj instanceof Byte) {
-            fp.addI8(((Byte)obj).byteValue());
+            addI8((Byte)obj);
             return;
         }
 
         if (obj instanceof Short) {
-            fp.addI16(((Short)obj).shortValue());
+            addI16((Short)obj);
             return;
         }
 
         if (obj instanceof Integer) {
-            fp.addI32(((Integer)obj).intValue());
+            addI32((Integer)obj);
             return;
         }
 
         if (obj instanceof Long) {
-            fp.addI64(((Long)obj).longValue());
+            addI64((Long)obj);
             return;
         }
 
         if (obj instanceof Float) {
-            fp.addF32(((Float)obj).floatValue());
+            addF32((Float)obj);
             return;
         }
 
         if (obj instanceof Double) {
-            fp.addF64(((Double)obj).doubleValue());
+            addF64((Double)obj);
             return;
         }
 
         if (obj instanceof Byte2) {
-            fp.addI8((Byte2)obj);
+            addI8((Byte2)obj);
             return;
         }
 
         if (obj instanceof Byte3) {
-            fp.addI8((Byte3)obj);
+            addI8((Byte3)obj);
             return;
         }
 
         if (obj instanceof Byte4) {
-            fp.addI8((Byte4)obj);
+            addI8((Byte4)obj);
             return;
         }
 
         if (obj instanceof Short2) {
-            fp.addI16((Short2)obj);
+            addI16((Short2)obj);
             return;
         }
 
         if (obj instanceof Short3) {
-            fp.addI16((Short3)obj);
+            addI16((Short3)obj);
             return;
         }
 
         if (obj instanceof Short4) {
-            fp.addI16((Short4)obj);
+            addI16((Short4)obj);
             return;
         }
 
         if (obj instanceof Int2) {
-            fp.addI32((Int2)obj);
+            addI32((Int2)obj);
             return;
         }
 
         if (obj instanceof Int3) {
-            fp.addI32((Int3)obj);
+            addI32((Int3)obj);
             return;
         }
 
         if (obj instanceof Int4) {
-            fp.addI32((Int4)obj);
+            addI32((Int4)obj);
             return;
         }
 
         if (obj instanceof Long2) {
-            fp.addI64((Long2)obj);
+            addI64((Long2)obj);
             return;
         }
 
         if (obj instanceof Long3) {
-            fp.addI64((Long3)obj);
+            addI64((Long3)obj);
             return;
         }
 
         if (obj instanceof Long4) {
-            fp.addI64((Long4)obj);
+            addI64((Long4)obj);
             return;
         }
 
         if (obj instanceof Float2) {
-            fp.addF32((Float2)obj);
+            addF32((Float2)obj);
             return;
         }
 
         if (obj instanceof Float3) {
-            fp.addF32((Float3)obj);
+            addF32((Float3)obj);
             return;
         }
 
         if (obj instanceof Float4) {
-            fp.addF32((Float4)obj);
+            addF32((Float4)obj);
             return;
         }
 
         if (obj instanceof Double2) {
-            fp.addF64((Double2)obj);
+            addF64((Double2)obj);
             return;
         }
 
         if (obj instanceof Double3) {
-            fp.addF64((Double3)obj);
+            addF64((Double3)obj);
             return;
         }
 
         if (obj instanceof Double4) {
-            fp.addF64((Double4)obj);
+            addF64((Double4)obj);
             return;
         }
 
         if (obj instanceof Matrix2f) {
-            fp.addMatrix((Matrix2f)obj);
+            addMatrix((Matrix2f)obj);
             return;
         }
 
         if (obj instanceof Matrix3f) {
-            fp.addMatrix((Matrix3f)obj);
+            addMatrix((Matrix3f)obj);
             return;
         }
 
         if (obj instanceof Matrix4f) {
-            fp.addMatrix((Matrix4f)obj);
+            addMatrix((Matrix4f)obj);
             return;
         }
 
         if (obj instanceof BaseObj) {
-            fp.addObj((BaseObj)obj);
+            addObj((BaseObj)obj);
             return;
         }
     }
 
-    private static int getPackedSize(Object obj) {
-        if (obj instanceof Boolean) {
-            return 1;
+    private boolean resize(int newSize) {
+        if (newSize == mLen) {
+            return false;
         }
 
-        if (obj instanceof Byte) {
-            return 1;
-        }
+        byte[] newData = new byte[newSize];
+        System.arraycopy(mData, 0, newData, 0, mPos);
+        mData = newData;
+        mLen = newSize;
+        return true;
+    }
 
-        if (obj instanceof Short) {
-            return 2;
-        }
-
-        if (obj instanceof Integer) {
-            return 4;
-        }
-
-        if (obj instanceof Long) {
-            return 8;
-        }
-
-        if (obj instanceof Float) {
-            return 4;
-        }
-
-        if (obj instanceof Double) {
-            return 8;
-        }
-
-        if (obj instanceof Byte2) {
-            return 2;
-        }
-
-        if (obj instanceof Byte3) {
-            return 3;
-        }
-
-        if (obj instanceof Byte4) {
-            return 4;
-        }
-
-        if (obj instanceof Short2) {
-            return 4;
-        }
-
-        if (obj instanceof Short3) {
-            return 6;
-        }
-
-        if (obj instanceof Short4) {
-            return 8;
-        }
-
-        if (obj instanceof Int2) {
-            return 8;
-        }
-
-        if (obj instanceof Int3) {
-            return 12;
-        }
-
-        if (obj instanceof Int4) {
-            return 16;
-        }
-
-        if (obj instanceof Long2) {
-            return 16;
-        }
-
-        if (obj instanceof Long3) {
-            return 24;
-        }
-
-        if (obj instanceof Long4) {
-            return 32;
-        }
-
-        if (obj instanceof Float2) {
-            return 8;
-        }
-
-        if (obj instanceof Float3) {
-            return 12;
-        }
-
-        if (obj instanceof Float4) {
-            return 16;
-        }
-
-        if (obj instanceof Double2) {
-            return 16;
-        }
-
-        if (obj instanceof Double3) {
-            return 24;
-        }
-
-        if (obj instanceof Double4) {
-            return 32;
-        }
-
-        if (obj instanceof Matrix2f) {
-            return 16;
-        }
-
-        if (obj instanceof Matrix3f) {
-            return 36;
-        }
-
-        if (obj instanceof Matrix4f) {
-            return 64;
-        }
-
-        if (obj instanceof BaseObj) {
-            if (RenderScript.sPointerSize == 8) {
-                return 32;
-            } else {
-                return 4;
+    private void addSafely(Object obj) {
+        boolean retry;
+        final int oldPos = mPos;
+        do {
+            retry = false;
+            try {
+                add(obj);
+            } catch (ArrayIndexOutOfBoundsException e) {
+                mPos = oldPos;
+                resize(mLen * 2);
+                retry = true;
             }
-        }
-
-        return 0;
+        } while (retry);
     }
 
-    static FieldPacker createFieldPack(Object[] args) {
-        int len = 0;
-        for (Object arg : args) {
-            len += getPackedSize(arg);
-        }
-        FieldPacker fp = new FieldPacker(len);
-        for (Object arg : args) {
-            addToPack(fp, arg);
-        }
-        return fp;
-    }
-
-    private final byte mData[];
+    private byte mData[];
     private int mPos;
     private int mLen;
     private BitSet mAlignment;
-
 }
-
-