Implement more type checks on Allocations.

Add tracking for allocations created using the "sized" helper.
Add more param validation for data upload calls.
This commit is contained in:
Jason Sams
2009-09-21 19:41:04 -07:00
parent 88a83d3f10
commit 768bc02d81
6 changed files with 197 additions and 113 deletions

View File

@ -48,50 +48,49 @@ public class Allocation extends BaseObj {
}
public void data(int[] d) {
int size;
if(mType != null && mType.mElement != null) {
size = mType.mElement.mSize;
for(int ct=0; ct < mType.mValues.length; ct++) {
if(mType.mValues[ct] != 0) {
size *= mType.mValues[ct];
}
}
if((d.length * 4) < size) {
throw new IllegalArgumentException("Array too small for allocation type.");
}
Log.e("rs", "Alloc data size=" + size);
mRS.nAllocationData(mID, d, size);
return;
}
mRS.nAllocationData(mID, d, d.length * 4);
subData1D(0, mType.getElementCount(), d);
}
public void data(short[] d) {
subData1D(0, mType.getElementCount(), d);
}
public void data(byte[] d) {
subData1D(0, mType.getElementCount(), d);
}
public void data(float[] d) {
subData1D(0, mType.getElementCount(), d);
}
public void data(float[] d) {
int size;
if(mType != null && mType.mElement != null) {
size = mType.mElement.mSize;
for(int ct=0; ct < mType.mValues.length; ct++) {
if(mType.mValues[ct] != 0) {
size *= mType.mValues[ct];
}
}
if((d.length * 4) < size) {
throw new IllegalArgumentException("Array too small for allocation type.");
}
Log.e("rs", "Alloc data size=" + size);
mRS.nAllocationData(mID, d, size);
return;
private void data1DChecks(int off, int count, int len, int dataSize) {
if((off < 0) || (count < 1) || ((off + count) > mType.getElementCount())) {
throw new IllegalArgumentException("Offset or Count out of bounds.");
}
if((len) < dataSize) {
throw new IllegalArgumentException("Array too small for allocation type.");
}
mRS.nAllocationData(mID, d, d.length * 4);
}
public void subData1D(int off, int count, int[] d) {
mRS.nAllocationSubData1D(mID, off, count, d, count * 4);
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 4, dataSize);
mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
}
public void subData1D(int off, int count, short[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 2, dataSize);
mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
}
public void subData1D(int off, int count, byte[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length, dataSize);
mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
}
public void subData1D(int off, int count, float[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 4, dataSize);
mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
}
public void subData1D(int off, int count, float[] d) {
mRS.nAllocationSubData1D(mID, off, count, d, d.length * 4);
}
public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
@ -213,11 +212,15 @@ public class Allocation extends BaseObj {
static public Allocation createSized(RenderScript rs, Element e, int count)
throws IllegalArgumentException {
int id = rs.nAllocationCreateSized(e.mID, count);
Type.Builder b = new Type.Builder(rs, e);
b.add(Dimension.X, count);
Type t = b.create();
int id = rs.nAllocationCreateTyped(t.mID);
if(id == 0) {
throw new IllegalStateException("Bad element.");
}
return new Allocation(id, rs, null);
return new Allocation(id, rs, t);
}
static public Allocation createFromBitmap(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips)

View File

@ -26,18 +26,40 @@ public class Element extends BaseObj {
int mSize;
Entry[] mEntries;
int getSizeBytes() {
return mSize;
}
int getComponentCount() {
return mEntries.length;
}
Element.DataType getComponentDataType(int num) {
return mEntries[num].mType;
}
Element.DataKind getComponentDataKind(int num) {
return mEntries[num].mKind;
}
boolean getComponentIsNormalized(int num) {
return mEntries[num].mIsNormalized;
}
int getComponentBits(int num) {
return mEntries[num].mBits;
}
String getComponentName(int num) {
return mEntries[num].mName;
}
static class Entry {
Element mElement;
//Element mElement;
Element.DataType mType;
Element.DataKind mKind;
boolean mIsNormalized;
int mBits;
String mName;
Entry(Element e, int bits) {
mElement = e;
int mBits = bits;
}
//Entry(Element e, int bits) {
//mElement = e;
//int mBits = bits;
//}
Entry(DataType dt, DataKind dk, boolean isNorm, int bits, String name) {
mType = dt;
@ -266,14 +288,11 @@ public class Element extends BaseObj {
int bits = 0;
for (int ct=0; ct < e.mEntries.length; ct++) {
Entry en = e.mEntries[ct];
if(en.mElement != null) {
//if(en.mElement != null) {
//rs.nElementAdd(en.mElement.mID);
} else {
int norm = 0;
if (en.mIsNormalized) {
norm = 1;
}
rs.nElementAdd(en.mKind.mID, en.mType.mID, norm, en.mBits, en.mName);
//} else
{
rs.nElementAdd(en.mKind.mID, en.mType.mID, en.mIsNormalized, en.mBits, en.mName);
bits += en.mBits;
}
}
@ -308,11 +327,11 @@ public class Element extends BaseObj {
mEntryCount++;
}
public Builder add(Element e) throws IllegalArgumentException {
Entry en = new Entry(e, e.mSize * 8);
addEntry(en);
return this;
}
//public Builder add(Element e) throws IllegalArgumentException {
//Entry en = new Entry(e, e.mSize * 8);
//addEntry(en);
//return this;
//}
public Builder add(Element.DataType dt, Element.DataKind dk, boolean isNormalized, int bits, String name) {
Entry en = new Entry(dt, dk, isNormalized, bits, name);

View File

@ -80,7 +80,7 @@ public class RenderScript {
native int nFileOpen(byte[] name);
native void nElementBegin();
native void nElementAdd(int kind, int type, int norm, int bits, String s);
native void nElementAdd(int kind, int type, boolean norm, int bits, String s);
native int nElementCreate();
native void nTypeBegin(int elementID);
@ -90,17 +90,19 @@ public class RenderScript {
native void nTypeSetupFields(Type t, int[] types, int[] bits, Field[] IDs);
native int nAllocationCreateTyped(int type);
native int nAllocationCreateSized(int elem, int count);
//native int nAllocationCreateSized(int elem, int count);
native int nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp);
native int nAllocationCreateFromBitmapBoxed(int dstFmt, boolean genMips, Bitmap bmp);
native int nAllocationCreateFromAssetStream(int dstFmt, boolean genMips, int assetStream);
native void nAllocationUploadToTexture(int alloc, int baseMioLevel);
native void nAllocationUploadToBufferObject(int alloc);
native void nAllocationData(int id, int[] d, int sizeBytes);
native void nAllocationData(int id, float[] d, int sizeBytes);
native void nAllocationSubData1D(int id, int off, int count, int[] d, int sizeBytes);
native void nAllocationSubData1D(int id, int off, int count, short[] d, int sizeBytes);
native void nAllocationSubData1D(int id, int off, int count, byte[] d, int sizeBytes);
native void nAllocationSubData1D(int id, int off, int count, float[] d, int sizeBytes);
native void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, int[] d, int sizeBytes);
native void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, float[] d, int sizeBytes);
native void nAllocationRead(int id, int[] d);

View File

@ -162,7 +162,6 @@ public class SimpleMesh extends BaseObj {
}
public SimpleMesh create() {
Log.e("rs", "SimpleMesh create");
SimpleMesh sm = internalCreate(mRS, this);
sm.mVertexTypes = new Type[mVertexTypeCount];
for(int ct=0; ct < mVertexTypeCount; ct++) {
@ -177,7 +176,7 @@ public class SimpleMesh extends BaseObj {
public static class TriangleMeshBuilder {
float mVtxData[];
int mVtxCount;
int mIndexData[];
short mIndexData[];
int mIndexCount;
RenderScript mRS;
Element mElement;
@ -191,7 +190,7 @@ public class SimpleMesh extends BaseObj {
mVtxCount = 0;
mIndexCount = 0;
mVtxData = new float[128];
mIndexData = new int[128];
mIndexData = new short[128];
mVtxSize = vtxSize;
mNorm = norm;
mTex = tex;
@ -268,13 +267,13 @@ public class SimpleMesh extends BaseObj {
public void addTriangle(int idx1, int idx2, int idx3) {
if((mIndexCount + 3) >= mIndexData.length) {
int t[] = new int[mIndexData.length * 2];
short t[] = new short[mIndexData.length * 2];
System.arraycopy(mIndexData, 0, t, 0, mIndexData.length);
mIndexData = t;
}
mIndexData[mIndexCount++] = idx1;
mIndexData[mIndexCount++] = idx2;
mIndexData[mIndexCount++] = idx3;
mIndexData[mIndexCount++] = (short)idx1;
mIndexData[mIndexCount++] = (short)idx2;
mIndexData[mIndexCount++] = (short)idx3;
}
public SimpleMesh create() {
@ -309,10 +308,6 @@ public class SimpleMesh extends BaseObj {
vertexAlloc.data(mVtxData);
vertexAlloc.uploadToBufferObject();
// This is safe because length is a pow2
for(int ct=0; ct < (mIndexCount+1); ct += 2) {
mIndexData[ct >> 1] = mIndexData[ct] | (mIndexData[ct+1] << 16);
}
indexAlloc.data(mIndexData);
indexAlloc.uploadToBufferObject();

View File

@ -23,13 +23,74 @@ import java.lang.reflect.Field;
*
**/
public class Type extends BaseObj {
Dimension[] mDimensions;
int[] mValues;
int mDimX;
int mDimY;
int mDimZ;
boolean mDimLOD;
boolean mDimFaces;
int mElementCount;
Element mElement;
private int mNativeCache;
Class mJavaClass;
public int getX() {
return mDimX;
}
public int getY() {
return mDimY;
}
public int getZ() {
return mDimZ;
}
public boolean getLOD() {
return mDimLOD;
}
public boolean getFaces() {
return mDimFaces;
}
public int getElementCount() {
return mElementCount;
}
void calcElementCount() {
boolean hasLod = getLOD();
int x = getX();
int y = getY();
int z = getZ();
int faces = 1;
if(getFaces()) {
faces = 6;
}
if(x == 0) {
x = 1;
}
if(y == 0) {
y = 1;
}
if(z == 0) {
z = 1;
}
int count = x * y * z * faces;
if(hasLod && (x > 1) && (y > 1) && (z > 1)) {
if(x > 1) {
x >>= 1;
}
if(y > 1) {
y >>= 1;
}
if(z > 1) {
z >>= 1;
}
count += x * y * z * faces;
}
mElementCount = count;
}
Type(int id, RenderScript rs) {
super(rs);
mID = id;
@ -131,12 +192,25 @@ public class Type extends BaseObj {
public Type create() {
Type t = internalCreate(mRS, this);
t.mElement = mElement;
t.mDimensions = new Dimension[mEntryCount];
t.mValues = new int[mEntryCount];
for(int ct=0; ct < mEntryCount; ct++) {
t.mDimensions[ct] = mEntries[ct].mDim;
t.mValues[ct] = mEntries[ct].mValue;
if(mEntries[ct].mDim == Dimension.X) {
t.mDimX = mEntries[ct].mValue;
}
if(mEntries[ct].mDim == Dimension.Y) {
t.mDimY = mEntries[ct].mValue;
}
if(mEntries[ct].mDim == Dimension.Z) {
t.mDimZ = mEntries[ct].mValue;
}
if(mEntries[ct].mDim == Dimension.LOD) {
t.mDimLOD = mEntries[ct].mValue != 0;
}
if(mEntries[ct].mDim == Dimension.FACE) {
t.mDimFaces = mEntries[ct].mValue != 0;
}
}
t.calcElementCount();
return t;
}
}