Create FieldPacker.getPos() to get the actual amount of data used for FP.

We need larger buffers to handle 64-bit RS object types, but 32-bit code
will never fill all of the getData().length bytes. This allows us to retain
our verification code.

We have to modify an existing use of FieldPacker that was doing partial
updates of the underlying buffer. This was really relying on the old data
to be implicitly selected and written back, but that is not guaranteed by
the original API. This also required a fix to the FieldPacker.reset() API,
which was not allowing the FieldPacker to ever point to the final entry in
its buffer.

Change-Id: Idcd52790ac2b0ab1eff3f043e7eec2832953f04b
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index c2bab91..20b7ee7 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -776,10 +776,11 @@
         mRS.validate();
         int eSize = mType.mElement.getBytesSize();
         final byte[] data = fp.getData();
+        int data_length = fp.getPos();
 
-        int count = data.length / eSize;
-        if ((eSize * count) != data.length) {
-            throw new RSIllegalArgumentException("Field packer length " + data.length +
+        int count = data_length / eSize;
+        if ((eSize * count) != data_length) {
+            throw new RSIllegalArgumentException("Field packer length " + data_length +
                                                " not divisible by element size " + eSize + ".");
         }
         copy1DRangeFromUnchecked(xoff, count, data);
@@ -803,16 +804,17 @@
         }
 
         final byte[] data = fp.getData();
+        int data_length = fp.getPos();
         int eSize = mType.mElement.mElements[component_number].getBytesSize();
         eSize *= mType.mElement.mArraySizes[component_number];
 
-        if (data.length != eSize) {
-            throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
+        if (data_length != eSize) {
+            throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
                                                " does not match component size " + eSize + ".");
         }
 
         mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
-                                     component_number, data, data.length);
+                                     component_number, data, data_length);
     }
 
     private void data1DChecks(int off, int count, int len, int dataSize) {
diff --git a/rs/java/android/renderscript/FieldPacker.java b/rs/java/android/renderscript/FieldPacker.java
index 576a84d..dccc1ac 100644
--- a/rs/java/android/renderscript/FieldPacker.java
+++ b/rs/java/android/renderscript/FieldPacker.java
@@ -76,7 +76,7 @@
         mPos = 0;
     }
     public void reset(int i) {
-        if ((i < 0) || (i >= mLen)) {
+        if ((i < 0) || (i > mLen)) {
             throw new RSIllegalArgumentException("out of range argument: " + i);
         }
         mPos = i;
@@ -606,6 +606,15 @@
         return mData;
     }
 
+    /**
+     * Get the actual length used for the FieldPacker.
+     *
+     * @hide
+     */
+    public int getPos() {
+        return mPos;
+    }
+
     private final byte mData[];
     private int mPos;
     private int mLen;
diff --git a/rs/java/android/renderscript/ProgramVertexFixedFunction.java b/rs/java/android/renderscript/ProgramVertexFixedFunction.java
index a350154..7026597 100644
--- a/rs/java/android/renderscript/ProgramVertexFixedFunction.java
+++ b/rs/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -249,6 +249,9 @@
             for(int i = 0; i < 16; i ++) {
                 mIOBuffer.addF32(m.mMat[i]);
             }
+            // Reset the buffer back to the end, since we want to flush all of
+            // the contents back (and not just what we wrote now).
+            mIOBuffer.reset(mIOBuffer.getData().length);
             mAlloc.setFromFieldPacker(0, mIOBuffer);
         }