diff options
-rw-r--r-- | graphics/java/android/renderscript/Element.java | 22 | ||||
-rw-r--r-- | graphics/java/android/renderscript/Mesh.java | 23 | ||||
-rw-r--r-- | libs/rs/rsAllocation.cpp | 110 | ||||
-rw-r--r-- | libs/rs/rsAllocation.h | 5 | ||||
-rw-r--r-- | libs/rs/rsComponent.cpp | 3 | ||||
-rw-r--r-- | libs/rs/rsComponent.h | 2 | ||||
-rw-r--r-- | libs/rs/rsElement.cpp | 17 | ||||
-rw-r--r-- | libs/rs/rsElement.h | 12 | ||||
-rw-r--r-- | libs/rs/rsFont.cpp | 6 |
9 files changed, 176 insertions, 24 deletions
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java index 8a9ca8550992..29306e4b52f5 100644 --- a/graphics/java/android/renderscript/Element.java +++ b/graphics/java/android/renderscript/Element.java @@ -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]; diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java index 7b3b73f505c6..b6ca58c3760b 100644 --- a/graphics/java/android/renderscript/Mesh.java +++ b/graphics/java/android/renderscript/Mesh.java @@ -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); diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index 35d812d40f25..c1192fefff7a 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -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; diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h index 714798aa1e0c..4ce863ab927f 100644 --- a/libs/rs/rsAllocation.h +++ b/libs/rs/rsAllocation.h @@ -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; }; } diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp index 7d9cf0ba954c..21b98f6193a2 100644 --- a/libs/rs/rsComponent.cpp +++ b/libs/rs/rsComponent.cpp @@ -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 { diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h index 6ddc990b2486..8629d0d9d6b9 100644 --- a/libs/rs/rsComponent.h +++ b/libs/rs/rsComponent.h @@ -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; diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp index df90ce499e85..56c31b66405d 100644 --- a/libs/rs/rsElement.cpp +++ b/libs/rs/rsElement.cpp @@ -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; diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h index bfdec53b9982..04010faafac8 100644 --- a/libs/rs/rsElement.h +++ b/libs/rs/rsElement.h @@ -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(); diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp index 7efed9d9f948..d1b7324f741d 100644 --- a/libs/rs/rsFont.cpp +++ b/libs/rs/rsFont.cpp @@ -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; |