summaryrefslogtreecommitdiffstats
path: root/libs/rs/rsElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/rs/rsElement.cpp')
-rw-r--r--libs/rs/rsElement.cpp307
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);
+ }
}