Merge "Expand RS vector3 types to vector4."
This commit is contained in:
committed by
Android (Google) Code Review
commit
5a47181833
@@ -690,7 +690,11 @@ public class Element extends BaseObj {
|
||||
if ((dt != DataType.UNSIGNED_5_6_5) &&
|
||||
(dt != DataType.UNSIGNED_4_4_4_4) &&
|
||||
(dt != DataType.UNSIGNED_5_5_5_1)) {
|
||||
mSize = dt.mSize * size;
|
||||
if (size == 3) {
|
||||
mSize = dt.mSize * 4;
|
||||
} else {
|
||||
mSize = dt.mSize * size;
|
||||
}
|
||||
} else {
|
||||
mSize = dt.mSize;
|
||||
}
|
||||
@@ -885,6 +889,7 @@ public class Element extends BaseObj {
|
||||
String[] mElementNames;
|
||||
int[] mArraySizes;
|
||||
int mCount;
|
||||
int mSkipPadding;
|
||||
|
||||
/**
|
||||
* Create a builder object.
|
||||
@@ -910,6 +915,21 @@ public class Element extends BaseObj {
|
||||
if (arraySize < 1) {
|
||||
throw new RSIllegalArgumentException("Array size cannot be less than 1.");
|
||||
}
|
||||
|
||||
// Skip padding fields after a vector 3 type.
|
||||
if (mSkipPadding != 0) {
|
||||
if (name.startsWith("#padding_")) {
|
||||
mSkipPadding = 0;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
if (element.mVectorSize == 3) {
|
||||
mSkipPadding = 1;
|
||||
} else {
|
||||
mSkipPadding = 0;
|
||||
}
|
||||
|
||||
if(mCount == mElements.length) {
|
||||
Element[] e = new Element[mCount + 8];
|
||||
String[] s = new String[mCount + 8];
|
||||
|
||||
@@ -514,6 +514,7 @@ public class Mesh extends BaseObj {
|
||||
public static class TriangleMeshBuilder {
|
||||
float mVtxData[];
|
||||
int mVtxCount;
|
||||
int mMaxIndex;
|
||||
short mIndexData[];
|
||||
int mIndexCount;
|
||||
RenderScript mRS;
|
||||
@@ -548,6 +549,7 @@ public class Mesh extends BaseObj {
|
||||
public TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags) {
|
||||
mRS = rs;
|
||||
mVtxCount = 0;
|
||||
mMaxIndex = 0;
|
||||
mIndexCount = 0;
|
||||
mVtxData = new float[128];
|
||||
mIndexData = new short[128];
|
||||
@@ -581,11 +583,13 @@ public class Mesh extends BaseObj {
|
||||
mVtxData[mVtxCount++] = mT0;
|
||||
}
|
||||
if ((mFlags & NORMAL) != 0) {
|
||||
makeSpace(3);
|
||||
makeSpace(4);
|
||||
mVtxData[mVtxCount++] = mNX;
|
||||
mVtxData[mVtxCount++] = mNY;
|
||||
mVtxData[mVtxCount++] = mNZ;
|
||||
mVtxData[mVtxCount++] = 0.0f;
|
||||
}
|
||||
mMaxIndex ++;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -622,10 +626,11 @@ public class Mesh extends BaseObj {
|
||||
if (mVtxSize != 3) {
|
||||
throw new IllegalStateException("add mistmatch with declared components.");
|
||||
}
|
||||
makeSpace(3);
|
||||
makeSpace(4);
|
||||
mVtxData[mVtxCount++] = x;
|
||||
mVtxData[mVtxCount++] = y;
|
||||
mVtxData[mVtxCount++] = z;
|
||||
mVtxData[mVtxCount++] = 1.0f;
|
||||
latch();
|
||||
return this;
|
||||
}
|
||||
@@ -697,9 +702,9 @@ public class Mesh extends BaseObj {
|
||||
* @return this
|
||||
**/
|
||||
public TriangleMeshBuilder addTriangle(int idx1, int idx2, int idx3) {
|
||||
if((idx1 >= mVtxCount) || (idx1 < 0) ||
|
||||
(idx2 >= mVtxCount) || (idx2 < 0) ||
|
||||
(idx3 >= mVtxCount) || (idx3 < 0)) {
|
||||
if((idx1 >= mMaxIndex) || (idx1 < 0) ||
|
||||
(idx2 >= mMaxIndex) || (idx2 < 0) ||
|
||||
(idx3 >= mMaxIndex) || (idx3 < 0)) {
|
||||
throw new IllegalStateException("Index provided greater than vertex count.");
|
||||
}
|
||||
if ((mIndexCount + 3) >= mIndexData.length) {
|
||||
@@ -729,20 +734,16 @@ public class Mesh extends BaseObj {
|
||||
**/
|
||||
public Mesh create(boolean uploadToBufferObject) {
|
||||
Element.Builder b = new Element.Builder(mRS);
|
||||
int floatCount = mVtxSize;
|
||||
b.add(Element.createVector(mRS,
|
||||
Element.DataType.FLOAT_32,
|
||||
mVtxSize), "position");
|
||||
if ((mFlags & COLOR) != 0) {
|
||||
floatCount += 4;
|
||||
b.add(Element.F32_4(mRS), "color");
|
||||
}
|
||||
if ((mFlags & TEXTURE_0) != 0) {
|
||||
floatCount += 2;
|
||||
b.add(Element.F32_2(mRS), "texture0");
|
||||
}
|
||||
if ((mFlags & NORMAL) != 0) {
|
||||
floatCount += 3;
|
||||
b.add(Element.F32_3(mRS), "normal");
|
||||
}
|
||||
mElement = b.create();
|
||||
@@ -753,12 +754,12 @@ public class Mesh extends BaseObj {
|
||||
}
|
||||
|
||||
Builder smb = new Builder(mRS, usage);
|
||||
smb.addVertexType(mElement, mVtxCount / floatCount);
|
||||
smb.addVertexType(mElement, mMaxIndex);
|
||||
smb.addIndexSetType(Element.U16(mRS), mIndexCount, Primitive.TRIANGLE);
|
||||
|
||||
Mesh sm = smb.create();
|
||||
|
||||
sm.getVertexAllocation(0).copy1DRangeFromUnchecked(0, mVtxCount / floatCount, mVtxData);
|
||||
sm.getVertexAllocation(0).copy1DRangeFromUnchecked(0, mMaxIndex, mVtxData);
|
||||
if(uploadToBufferObject) {
|
||||
if (uploadToBufferObject) {
|
||||
sm.getVertexAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
|
||||
|
||||
@@ -195,6 +195,81 @@ void Allocation::dumpLOGV(const char *prefix) const {
|
||||
prefix, getPtr(), mHal.state.usageFlags, mHal.state.mipmapControl);
|
||||
}
|
||||
|
||||
uint32_t Allocation::getPackedSize() const {
|
||||
uint32_t numItems = mHal.state.type->getSizeBytes() / mHal.state.type->getElementSizeBytes();
|
||||
return numItems * mHal.state.type->getElement()->getSizeBytesUnpadded();
|
||||
}
|
||||
|
||||
void Allocation::writePackedData(const Type *type,
|
||||
uint8_t *dst, const uint8_t *src, bool dstPadded) {
|
||||
const Element *elem = type->getElement();
|
||||
uint32_t unpaddedBytes = elem->getSizeBytesUnpadded();
|
||||
uint32_t paddedBytes = elem->getSizeBytes();
|
||||
uint32_t numItems = type->getSizeBytes() / paddedBytes;
|
||||
|
||||
uint32_t srcInc = !dstPadded ? paddedBytes : unpaddedBytes;
|
||||
uint32_t dstInc = dstPadded ? paddedBytes : unpaddedBytes;
|
||||
|
||||
// no sub-elements
|
||||
uint32_t fieldCount = elem->getFieldCount();
|
||||
if (fieldCount == 0) {
|
||||
for (uint32_t i = 0; i < numItems; i ++) {
|
||||
memcpy(dst, src, unpaddedBytes);
|
||||
src += srcInc;
|
||||
dst += dstInc;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache offsets
|
||||
uint32_t *offsetsPadded = new uint32_t[fieldCount];
|
||||
uint32_t *offsetsUnpadded = new uint32_t[fieldCount];
|
||||
uint32_t *sizeUnpadded = new uint32_t[fieldCount];
|
||||
|
||||
for (uint32_t i = 0; i < fieldCount; i++) {
|
||||
offsetsPadded[i] = elem->getFieldOffsetBytes(i);
|
||||
offsetsUnpadded[i] = elem->getFieldOffsetBytesUnpadded(i);
|
||||
sizeUnpadded[i] = elem->getField(i)->getSizeBytesUnpadded();
|
||||
}
|
||||
|
||||
uint32_t *srcOffsets = !dstPadded ? offsetsPadded : offsetsUnpadded;
|
||||
uint32_t *dstOffsets = dstPadded ? offsetsPadded : offsetsUnpadded;
|
||||
|
||||
// complex elements, need to copy subelem after subelem
|
||||
for (uint32_t i = 0; i < numItems; i ++) {
|
||||
for (uint32_t fI = 0; fI < fieldCount; fI++) {
|
||||
memcpy(dst + dstOffsets[fI], src + srcOffsets[fI], sizeUnpadded[fI]);
|
||||
}
|
||||
src += srcInc;
|
||||
dst += dstInc;
|
||||
}
|
||||
|
||||
delete[] offsetsPadded;
|
||||
delete[] offsetsUnpadded;
|
||||
delete[] sizeUnpadded;
|
||||
}
|
||||
|
||||
void Allocation::unpackVec3Allocation(const void *data, uint32_t dataSize) {
|
||||
const uint8_t *src = (const uint8_t*)data;
|
||||
uint8_t *dst = (uint8_t*)getPtr();
|
||||
|
||||
writePackedData(getType(), dst, src, true);
|
||||
}
|
||||
|
||||
void Allocation::packVec3Allocation(OStream *stream) const {
|
||||
uint32_t paddedBytes = getType()->getElement()->getSizeBytes();
|
||||
uint32_t unpaddedBytes = getType()->getElement()->getSizeBytesUnpadded();
|
||||
uint32_t numItems = mHal.state.type->getSizeBytes() / paddedBytes;
|
||||
|
||||
const uint8_t *src = (const uint8_t*)getPtr();
|
||||
uint8_t *dst = new uint8_t[numItems * unpaddedBytes];
|
||||
|
||||
writePackedData(getType(), dst, src, false);
|
||||
stream->addByteArray(dst, getPackedSize());
|
||||
|
||||
delete[] dst;
|
||||
}
|
||||
|
||||
void Allocation::serialize(OStream *stream) const {
|
||||
// Need to identify ourselves
|
||||
stream->addU32((uint32_t)getClassId());
|
||||
@@ -207,10 +282,17 @@ void Allocation::serialize(OStream *stream) const {
|
||||
mHal.state.type->serialize(stream);
|
||||
|
||||
uint32_t dataSize = mHal.state.type->getSizeBytes();
|
||||
// 3 element vectors are padded to 4 in memory, but padding isn't serialized
|
||||
uint32_t packedSize = getPackedSize();
|
||||
// Write how much data we are storing
|
||||
stream->addU32(dataSize);
|
||||
// Now write the data
|
||||
stream->addByteArray(getPtr(), dataSize);
|
||||
stream->addU32(packedSize);
|
||||
if (dataSize == packedSize) {
|
||||
// Now write the data
|
||||
stream->addByteArray(getPtr(), dataSize);
|
||||
} else {
|
||||
// Now write the data
|
||||
packVec3Allocation(stream);
|
||||
}
|
||||
}
|
||||
|
||||
Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
|
||||
@@ -230,22 +312,30 @@ Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
|
||||
}
|
||||
type->compute();
|
||||
|
||||
Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
|
||||
type->decUserRef();
|
||||
|
||||
// Number of bytes we wrote out for this allocation
|
||||
uint32_t dataSize = stream->loadU32();
|
||||
if (dataSize != type->getSizeBytes()) {
|
||||
// 3 element vectors are padded to 4 in memory, but padding isn't serialized
|
||||
uint32_t packedSize = alloc->getPackedSize();
|
||||
if (dataSize != type->getSizeBytes() &&
|
||||
dataSize != packedSize) {
|
||||
LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
|
||||
ObjectBase::checkDelete(alloc);
|
||||
ObjectBase::checkDelete(type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
|
||||
alloc->setName(name.string(), name.size());
|
||||
type->decUserRef();
|
||||
|
||||
uint32_t count = dataSize / type->getElementSizeBytes();
|
||||
|
||||
// Read in all of our allocation data
|
||||
alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
|
||||
if (dataSize == type->getSizeBytes()) {
|
||||
uint32_t count = dataSize / type->getElementSizeBytes();
|
||||
// Read in all of our allocation data
|
||||
alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
|
||||
} else {
|
||||
alloc->unpackVec3Allocation(stream->getPtr() + stream->getPos(), dataSize);
|
||||
}
|
||||
stream->reset(stream->getPos() + dataSize);
|
||||
|
||||
return alloc;
|
||||
|
||||
@@ -135,6 +135,11 @@ protected:
|
||||
private:
|
||||
void freeChildrenUnlocked();
|
||||
Allocation(Context *rsc, const Type *, uint32_t usages, RsAllocationMipmapControl mc);
|
||||
|
||||
uint32_t getPackedSize() const;
|
||||
static void writePackedData(const Type *type, uint8_t *dst, const uint8_t *src, bool dstPadded);
|
||||
void unpackVec3Allocation(const void *data, uint32_t dataSize);
|
||||
void packVec3Allocation(OStream *stream) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -169,7 +169,8 @@ void Component::set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
mBits = mTypeBits * mVectorSize;
|
||||
mBitsUnpadded = mTypeBits * mVectorSize;
|
||||
mBits = mTypeBits * rsHigherPow2(mVectorSize);
|
||||
}
|
||||
|
||||
bool Component::isReference() const {
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
bool getIsFloat() const {return mIsFloat;}
|
||||
bool getIsSigned() const {return mIsSigned;}
|
||||
uint32_t getBits() const {return mBits;}
|
||||
uint32_t getBitsUnpadded() const {return mBitsUnpadded;}
|
||||
|
||||
// Helpers for reading / writing this class out
|
||||
void serialize(OStream *stream) const;
|
||||
@@ -56,6 +57,7 @@ protected:
|
||||
|
||||
// derived
|
||||
uint32_t mBits;
|
||||
uint32_t mBitsUnpadded;
|
||||
uint32_t mTypeBits;
|
||||
bool mIsFloat;
|
||||
bool mIsSigned;
|
||||
|
||||
@@ -23,6 +23,7 @@ using namespace android::renderscript;
|
||||
|
||||
Element::Element(Context *rsc) : ObjectBase(rsc) {
|
||||
mBits = 0;
|
||||
mBitsUnpadded = 0;
|
||||
mFields = NULL;
|
||||
mFieldCount = 0;
|
||||
mHasReference = false;
|
||||
@@ -60,6 +61,18 @@ size_t Element::getSizeBits() const {
|
||||
return total;
|
||||
}
|
||||
|
||||
size_t Element::getSizeBitsUnpadded() const {
|
||||
if (!mFieldCount) {
|
||||
return mBitsUnpadded;
|
||||
}
|
||||
|
||||
size_t total = 0;
|
||||
for (size_t ct=0; ct < mFieldCount; ct++) {
|
||||
total += mFields[ct].e->mBitsUnpadded * mFields[ct].arraySize;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void Element::dumpLOGV(const char *prefix) const {
|
||||
ObjectBase::dumpLOGV(prefix);
|
||||
ALOGV("%s Element: fieldCount: %zu, size bytes: %zu", prefix, mFieldCount, getSizeBytes());
|
||||
@@ -146,14 +159,18 @@ Element *Element::createFromStream(Context *rsc, IStream *stream) {
|
||||
void Element::compute() {
|
||||
if (mFieldCount == 0) {
|
||||
mBits = mComponent.getBits();
|
||||
mBitsUnpadded = mComponent.getBitsUnpadded();
|
||||
mHasReference = mComponent.isReference();
|
||||
return;
|
||||
}
|
||||
|
||||
size_t bits = 0;
|
||||
size_t bitsUnpadded = 0;
|
||||
for (size_t ct=0; ct < mFieldCount; ct++) {
|
||||
mFields[ct].offsetBits = bits;
|
||||
mFields[ct].offsetBitsUnpadded = bitsUnpadded;
|
||||
bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize;
|
||||
bitsUnpadded += mFields[ct].e->getSizeBitsUnpadded() * mFields[ct].arraySize;
|
||||
|
||||
if (mFields[ct].e->mHasReference) {
|
||||
mHasReference = true;
|
||||
|
||||
@@ -43,6 +43,11 @@ public:
|
||||
uint32_t getGLType() const;
|
||||
uint32_t getGLFormat() const;
|
||||
|
||||
size_t getSizeBitsUnpadded() const;
|
||||
size_t getSizeBytesUnpadded() const {
|
||||
return (getSizeBitsUnpadded() + 7) >> 3;
|
||||
}
|
||||
|
||||
size_t getSizeBits() const;
|
||||
size_t getSizeBytes() const {
|
||||
return (getSizeBits() + 7) >> 3;
|
||||
@@ -55,6 +60,10 @@ public:
|
||||
return mFields[componentNumber].offsetBits >> 3;
|
||||
}
|
||||
|
||||
size_t getFieldOffsetBytesUnpadded(uint32_t componentNumber) const {
|
||||
return mFields[componentNumber].offsetBitsUnpadded >> 3;
|
||||
}
|
||||
|
||||
uint32_t getFieldCount() const {return mFieldCount;}
|
||||
const Element * getField(uint32_t idx) const {return mFields[idx].e.get();}
|
||||
const char * getFieldName(uint32_t idx) const {return mFields[idx].name.string();}
|
||||
@@ -64,6 +73,7 @@ public:
|
||||
RsDataType getType() const {return mComponent.getType();}
|
||||
RsDataKind getKind() const {return mComponent.getKind();}
|
||||
uint32_t getBits() const {return mBits;}
|
||||
uint32_t getBitsUnpadded() const {return mBitsUnpadded;}
|
||||
|
||||
void dumpLOGV(const char *prefix) const;
|
||||
virtual void serialize(OStream *stream) const;
|
||||
@@ -112,6 +122,7 @@ protected:
|
||||
String8 name;
|
||||
ObjectBaseRef<const Element> e;
|
||||
uint32_t offsetBits;
|
||||
uint32_t offsetBitsUnpadded;
|
||||
uint32_t arraySize;
|
||||
} ElementField_t;
|
||||
ElementField_t *mFields;
|
||||
@@ -123,6 +134,7 @@ protected:
|
||||
Element(Context *);
|
||||
|
||||
Component mComponent;
|
||||
uint32_t mBitsUnpadded;
|
||||
uint32_t mBits;
|
||||
|
||||
void compute();
|
||||
|
||||
@@ -651,7 +651,7 @@ void FontState::appendMeshQuad(float x1, float y1, float z1,
|
||||
float x4, float y4, float z4,
|
||||
float u4, float v4) {
|
||||
const uint32_t vertsPerQuad = 4;
|
||||
const uint32_t floatsPerVert = 5;
|
||||
const uint32_t floatsPerVert = 6;
|
||||
float *currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert;
|
||||
|
||||
// Cull things that are off the screen
|
||||
@@ -670,24 +670,28 @@ void FontState::appendMeshQuad(float x1, float y1, float z1,
|
||||
(*currentPos++) = x1;
|
||||
(*currentPos++) = y1;
|
||||
(*currentPos++) = z1;
|
||||
(*currentPos++) = 0;
|
||||
(*currentPos++) = u1;
|
||||
(*currentPos++) = v1;
|
||||
|
||||
(*currentPos++) = x2;
|
||||
(*currentPos++) = y2;
|
||||
(*currentPos++) = z2;
|
||||
(*currentPos++) = 0;
|
||||
(*currentPos++) = u2;
|
||||
(*currentPos++) = v2;
|
||||
|
||||
(*currentPos++) = x3;
|
||||
(*currentPos++) = y3;
|
||||
(*currentPos++) = z3;
|
||||
(*currentPos++) = 0;
|
||||
(*currentPos++) = u3;
|
||||
(*currentPos++) = v3;
|
||||
|
||||
(*currentPos++) = x4;
|
||||
(*currentPos++) = y4;
|
||||
(*currentPos++) = z4;
|
||||
(*currentPos++) = 0;
|
||||
(*currentPos++) = u4;
|
||||
(*currentPos++) = v4;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user