diff options
Diffstat (limited to 'libs/rs/rsElement.cpp')
-rw-r--r-- | libs/rs/rsElement.cpp | 307 |
1 files changed, 225 insertions, 82 deletions
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp index 6288bc4..6ae8bb8 100644 --- a/libs/rs/rsElement.cpp +++ b/libs/rs/rsElement.cpp @@ -14,26 +14,27 @@ * limitations under the License. */ -#include "rsContext.h" +#ifndef ANDROID_RS_BUILD_FOR_HOST +#include "rsContext.h" #include <GLES/gl.h> +#else +#include "rsContextHostStub.h" +#include <OpenGL/gl.h> +#endif using namespace android; using namespace android::renderscript; -Element::Element(Context *rsc) : ObjectBase(rsc) -{ +Element::Element(Context *rsc) : ObjectBase(rsc) { mBits = 0; - mAllocFile = __FILE__; - mAllocLine = __LINE__; mFields = NULL; mFieldCount = 0; + mHasReference = false; } - -Element::~Element() -{ +Element::~Element() { for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) { if (mRSC->mStateElement.mElements[ct] == this) { mRSC->mStateElement.mElements.removeAt(ct); @@ -43,50 +44,142 @@ Element::~Element() clear(); } -void Element::clear() -{ +void Element::clear() { delete [] mFields; mFields = NULL; mFieldCount = 0; + mHasReference = false; } -size_t Element::getSizeBits() const -{ +size_t Element::getSizeBits() const { if (!mFieldCount) { return mBits; } size_t total = 0; for (size_t ct=0; ct < mFieldCount; ct++) { - total += mFields[ct].e->mBits; + total += mFields[ct].e->mBits * mFields[ct].arraySize; } return total; } -size_t Element::getFieldOffsetBits(uint32_t componentNumber) const -{ - size_t offset = 0; - for (uint32_t ct = 0; ct < componentNumber; ct++) { - offset += mFields[ct].e->mBits; +void Element::dumpLOGV(const char *prefix) const { + ObjectBase::dumpLOGV(prefix); + LOGV("%s Element: fieldCount: %i, size bytes: %i", prefix, mFieldCount, getSizeBytes()); + for (uint32_t ct = 0; ct < mFieldCount; ct++) { + LOGV("%s Element field index: %u ------------------", prefix, ct); + LOGV("%s name: %s, offsetBits: %u, arraySize: %u", + prefix, mFields[ct].name.string(), mFields[ct].offsetBits, mFields[ct].arraySize); + mFields[ct].e->dumpLOGV(prefix); } - return offset; } -void Element::dumpLOGV(const char *prefix) const -{ - ObjectBase::dumpLOGV(prefix); - LOGV("%s Element: components %i, size %i", prefix, mFieldCount, mBits); +void Element::serialize(OStream *stream) const { + // Need to identify ourselves + stream->addU32((uint32_t)getClassId()); + + String8 name(getName()); + stream->addString(&name); + + mComponent.serialize(stream); + + // Now serialize all the fields + stream->addU32(mFieldCount); for (uint32_t ct = 0; ct < mFieldCount; ct++) { - char buf[1024]; - sprintf(buf, "%s component %i: ", prefix, ct); - //mComponents[ct]->dumpLOGV(buf); + stream->addString(&mFields[ct].name); + stream->addU32(mFields[ct].arraySize); + mFields[ct].e->serialize(stream); + } +} + +Element *Element::createFromStream(Context *rsc, IStream *stream) { + // First make sure we are reading the correct object + RsA3DClassID classID = (RsA3DClassID)stream->loadU32(); + if (classID != RS_A3D_CLASS_ID_ELEMENT) { + LOGE("element loading skipped due to invalid class id\n"); + return NULL; + } + + String8 name; + stream->loadString(&name); + + Element *elem = new Element(rsc); + elem->mComponent.loadFromStream(stream); + + elem->mFieldCount = stream->loadU32(); + if (elem->mFieldCount) { + elem->mFields = new ElementField_t [elem->mFieldCount]; + for (uint32_t ct = 0; ct < elem->mFieldCount; ct ++) { + stream->loadString(&elem->mFields[ct].name); + elem->mFields[ct].arraySize = stream->loadU32(); + Element *fieldElem = Element::createFromStream(rsc, stream); + elem->mFields[ct].e.set(fieldElem); + } + } + + // We need to check if this already exists + for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) { + Element *ee = rsc->mStateElement.mElements[ct]; + if (ee->isEqual(elem)) { + ObjectBase::checkDelete(elem); + ee->incUserRef(); + return ee; + } } + + elem->compute(); + rsc->mStateElement.mElements.push(elem); + return elem; } +bool Element::isEqual(const Element *other) const { + if (other == NULL) { + return false; + } + if (!other->getFieldCount() && !mFieldCount) { + if ((other->getType() == getType()) && + (other->getKind() == getKind()) && + (other->getComponent().getIsNormalized() == getComponent().getIsNormalized()) && + (other->getComponent().getVectorSize() == getComponent().getVectorSize())) { + return true; + } + return false; + } + if (other->getFieldCount() == mFieldCount) { + for (uint32_t i=0; i < mFieldCount; i++) { + if ((!other->mFields[i].e->isEqual(mFields[i].e.get())) || + (other->mFields[i].name.length() != mFields[i].name.length()) || + (other->mFields[i].name != mFields[i].name) || + (other->mFields[i].arraySize != mFields[i].arraySize)) { + return false; + } + } + return true; + } + return false; +} + +void Element::compute() { + if (mFieldCount == 0) { + mBits = mComponent.getBits(); + mHasReference = mComponent.isReference(); + return; + } + + size_t bits = 0; + for (size_t ct=0; ct < mFieldCount; ct++) { + mFields[ct].offsetBits = bits; + bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize; + + if (mFields[ct].e->mHasReference) { + mHasReference = true; + } + } + +} const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk, - bool isNorm, uint32_t vecSize) -{ + bool isNorm, uint32_t vecSize) { // Look for an existing match. for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) { const Element *ee = rsc->mStateElement.mElements[ct]; @@ -103,14 +196,13 @@ const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk, Element *e = new Element(rsc); e->mComponent.set(dt, dk, isNorm, vecSize); - e->mBits = e->mComponent.getBits(); + e->compute(); rsc->mStateElement.mElements.push(e); return e; } const Element * Element::create(Context *rsc, size_t count, const Element **ein, - const char **nin, const size_t * lengths) -{ + const char **nin, const size_t * lengths, const uint32_t *asin) { // Look for an existing match. for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) { const Element *ee = rsc->mStateElement.mElements[ct]; @@ -119,7 +211,8 @@ const Element * Element::create(Context *rsc, size_t count, const Element **ein, for (uint32_t i=0; i < count; i++) { if ((ee->mFields[i].e.get() != ein[i]) || (ee->mFields[i].name.length() != lengths[i]) || - (ee->mFields[i].name != nin[i])) { + (ee->mFields[i].name != nin[i]) || + (ee->mFields[i].arraySize != asin[i])) { match = false; break; } @@ -137,35 +230,15 @@ const Element * Element::create(Context *rsc, size_t count, const Element **ein, for (size_t ct=0; ct < count; ct++) { e->mFields[ct].e.set(ein[ct]); e->mFields[ct].name.setTo(nin[ct], lengths[ct]); + e->mFields[ct].arraySize = asin[ct]; } + e->compute(); rsc->mStateElement.mElements.push(e); return e; } -String8 Element::getCStructBody(uint32_t indent) const -{ - String8 si; - for (uint32_t ct=0; ct < indent; ct++) { - si.append(" "); - } - - String8 s(si); - s.append("{\n"); - for (uint32_t ct = 0; ct < mFieldCount; ct++) { - s.append(si); - s.append(mFields[ct].e->getCType(indent+4)); - s.append(" "); - s.append(mFields[ct].name); - s.append(";\n"); - } - s.append(si); - s.append("}"); - return s; -} - -String8 Element::getCType(uint32_t indent) const -{ +String8 Element::getGLSLType(uint32_t indent) const { String8 s; for (uint32_t ct=0; ct < indent; ct++) { s.append(" "); @@ -173,45 +246,96 @@ String8 Element::getCType(uint32_t indent) const if (!mFieldCount) { // Basic component. - s.append(mComponent.getCType()); + s.append(mComponent.getGLSLType()); } else { - s.append("struct "); - s.append(getCStructBody(indent)); + rsAssert(0); + //s.append("struct "); + //s.append(getCStructBody(indent)); } return s; } -String8 Element::getGLSLType(uint32_t indent) const -{ - String8 s; - for (uint32_t ct=0; ct < indent; ct++) { - s.append(" "); +void Element::incRefs(const void *ptr) const { + if (!mFieldCount) { + if (mComponent.isReference()) { + ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr); + ObjectBase *ob = obp[0]; + if (ob) ob->incSysRef(); + } + return; } + const uint8_t *p = static_cast<const uint8_t *>(ptr); + for (uint32_t i=0; i < mFieldCount; i++) { + if (mFields[i].e->mHasReference) { + p = &p[mFields[i].offsetBits >> 3]; + for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) { + mFields[i].e->incRefs(p); + p += mFields[i].e->getSizeBytes(); + } + } + } +} + +void Element::decRefs(const void *ptr) const { if (!mFieldCount) { - // Basic component. - s.append(mComponent.getGLSLType()); - } else { - rsAssert(0); - //s.append("struct "); - //s.append(getCStructBody(indent)); + if (mComponent.isReference()) { + ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr); + ObjectBase *ob = obp[0]; + if (ob) ob->decSysRef(); + } + return; } - return s; + const uint8_t *p = static_cast<const uint8_t *>(ptr); + for (uint32_t i=0; i < mFieldCount; i++) { + if (mFields[i].e->mHasReference) { + p = &p[mFields[i].offsetBits >> 3]; + for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) { + mFields[i].e->decRefs(p); + p += mFields[i].e->getSizeBytes(); + } + } + } } - -ElementState::ElementState() -{ +ElementState::ElementState() { + const uint32_t initialCapacity = 32; + mBuilderElements.setCapacity(initialCapacity); + mBuilderNameStrings.setCapacity(initialCapacity); + mBuilderNameLengths.setCapacity(initialCapacity); + mBuilderArrays.setCapacity(initialCapacity); } -ElementState::~ElementState() -{ +ElementState::~ElementState() { rsAssert(!mElements.size()); } +void ElementState::elementBuilderBegin() { + mBuilderElements.clear(); + mBuilderNameStrings.clear(); + mBuilderNameLengths.clear(); + mBuilderArrays.clear(); +} + +void ElementState::elementBuilderAdd(const Element *e, const char *nameStr, uint32_t arraySize) { + mBuilderElements.push(e); + mBuilderNameStrings.push(nameStr); + mBuilderNameLengths.push(strlen(nameStr)); + mBuilderArrays.push(arraySize); + +} + +const Element *ElementState::elementBuilderCreate(Context *rsc) { + return Element::create(rsc, mBuilderElements.size(), + &(mBuilderElements.editArray()[0]), + &(mBuilderNameStrings.editArray()[0]), + mBuilderNameLengths.editArray(), + mBuilderArrays.editArray()); +} + ///////////////////////////////////////// // @@ -223,9 +347,7 @@ RsElement rsi_ElementCreate(Context *rsc, RsDataType dt, RsDataKind dk, bool norm, - uint32_t vecSize) -{ - //LOGE("rsi_ElementCreate %i %i %i %i", dt, dk, norm, vecSize); + uint32_t vecSize) { const Element *e = Element::create(rsc, dt, dk, norm, vecSize); e->incUserRef(); return (RsElement)e; @@ -235,14 +357,35 @@ RsElement rsi_ElementCreate2(Context *rsc, size_t count, const RsElement * ein, const char ** names, - const size_t * nameLengths) -{ - //LOGE("rsi_ElementCreate2 %i", count); - const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths); + const size_t * nameLengths, + const uint32_t * arraySizes) { + const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths, arraySizes); e->incUserRef(); return (RsElement)e; } +} +} + +void rsaElementGetNativeData(RsContext con, RsElement elem, uint32_t *elemData, uint32_t elemDataSize) { + rsAssert(elemDataSize == 5); + // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements + Element *e = static_cast<Element *>(elem); + (*elemData++) = (uint32_t)e->getType(); + (*elemData++) = (uint32_t)e->getKind(); + (*elemData++) = e->getComponent().getIsNormalized() ? 1 : 0; + (*elemData++) = e->getComponent().getVectorSize(); + (*elemData++) = e->getFieldCount(); } + +void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids, const char **names, uint32_t dataSize) { + Element *e = static_cast<Element *>(elem); + rsAssert(e->getFieldCount() == dataSize); + + for (uint32_t i = 0; i < dataSize; i ++) { + e->getField(i)->incUserRef(); + ids[i] = (uint32_t)e->getField(i); + names[i] = e->getFieldName(i); + } } |