Home | History | Annotate | Download | only in rs
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 
     18 #include "rsContext.h"
     19 
     20 using namespace android;
     21 using namespace android::renderscript;
     22 
     23 
     24 Element::Element(Context *rsc) : ObjectBase(rsc) {
     25     mBits = 0;
     26     mBitsUnpadded = 0;
     27     mFields = NULL;
     28     mFieldCount = 0;
     29     mHasReference = false;
     30     memset(&mHal, 0, sizeof(mHal));
     31 }
     32 
     33 Element::~Element() {
     34     clear();
     35 }
     36 
     37 void Element::preDestroy() const {
     38     for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) {
     39         if (mRSC->mStateElement.mElements[ct] == this) {
     40             mRSC->mStateElement.mElements.removeAt(ct);
     41             break;
     42         }
     43     }
     44 }
     45 
     46 void Element::clear() {
     47     if (mFields) {
     48         for (size_t i = 0; i < mFieldCount; i++) {
     49             delete[] mFields[i].name;
     50         }
     51         delete [] mFields;
     52     }
     53     mFields = NULL;
     54     mFieldCount = 0;
     55     mHasReference = false;
     56 
     57     delete [] mHal.state.fields;
     58     delete [] mHal.state.fieldArraySizes;
     59     delete [] mHal.state.fieldNames;
     60     delete [] mHal.state.fieldNameLengths;
     61     delete [] mHal.state.fieldOffsetBytes;
     62 }
     63 
     64 size_t Element::getSizeBits() const {
     65     if (!mFieldCount) {
     66         return mBits;
     67     }
     68 
     69     size_t total = 0;
     70     for (size_t ct=0; ct < mFieldCount; ct++) {
     71         total += mFields[ct].e->mBits * mFields[ct].arraySize;
     72     }
     73     return total;
     74 }
     75 
     76 size_t Element::getSizeBitsUnpadded() const {
     77     if (!mFieldCount) {
     78         return mBitsUnpadded;
     79     }
     80 
     81     size_t total = 0;
     82     for (size_t ct=0; ct < mFieldCount; ct++) {
     83         total += mFields[ct].e->mBitsUnpadded * mFields[ct].arraySize;
     84     }
     85     return total;
     86 }
     87 
     88 void Element::dumpLOGV(const char *prefix) const {
     89     ObjectBase::dumpLOGV(prefix);
     90     ALOGV("%s Element: fieldCount: %zu,  size bytes: %zu", prefix, mFieldCount, getSizeBytes());
     91     mComponent.dumpLOGV(prefix);
     92     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
     93         ALOGV("%s Element field index: %u ------------------", prefix, ct);
     94         ALOGV("%s name: %s, offsetBits: %u, arraySize: %u",
     95              prefix, mFields[ct].name, mFields[ct].offsetBits, mFields[ct].arraySize);
     96         mFields[ct].e->dumpLOGV(prefix);
     97     }
     98 }
     99 
    100 void Element::serialize(Context *rsc, OStream *stream) const {
    101     // Need to identify ourselves
    102     stream->addU32((uint32_t)getClassId());
    103     stream->addString(getName());
    104 
    105     mComponent.serialize(stream);
    106 
    107     // Now serialize all the fields
    108     stream->addU32(mFieldCount);
    109     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
    110         stream->addString(mFields[ct].name);
    111         stream->addU32(mFields[ct].arraySize);
    112         mFields[ct].e->serialize(rsc, stream);
    113     }
    114 }
    115 
    116 Element *Element::createFromStream(Context *rsc, IStream *stream) {
    117     // First make sure we are reading the correct object
    118     RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
    119     if (classID != RS_A3D_CLASS_ID_ELEMENT) {
    120         ALOGE("element loading skipped due to invalid class id\n");
    121         return NULL;
    122     }
    123 
    124     const char *name = stream->loadString();
    125 
    126     Component component;
    127     component.loadFromStream(stream);
    128 
    129     uint32_t fieldCount = stream->loadU32();
    130     if (!fieldCount) {
    131         return (Element *)Element::create(rsc,
    132                                           component.getType(),
    133                                           component.getKind(),
    134                                           component.getIsNormalized(),
    135                                           component.getVectorSize());
    136     }
    137 
    138     const Element **subElems = new const Element *[fieldCount];
    139     const char **subElemNames = new const char *[fieldCount];
    140     size_t *subElemNamesLengths = new size_t[fieldCount];
    141     uint32_t *arraySizes = new uint32_t[fieldCount];
    142 
    143     for (uint32_t ct = 0; ct < fieldCount; ct ++) {
    144         subElemNames[ct] = stream->loadString();
    145         subElemNamesLengths[ct] = strlen(subElemNames[ct]);
    146         arraySizes[ct] = stream->loadU32();
    147         subElems[ct] = Element::createFromStream(rsc, stream);
    148     }
    149 
    150     const Element *elem = Element::create(rsc, fieldCount, subElems, subElemNames,
    151                                           subElemNamesLengths, arraySizes);
    152     for (uint32_t ct = 0; ct < fieldCount; ct ++) {
    153         delete [] subElemNames[ct];
    154         subElems[ct]->decUserRef();
    155     }
    156     delete[] name;
    157     delete[] subElems;
    158     delete[] subElemNames;
    159     delete[] subElemNamesLengths;
    160     delete[] arraySizes;
    161 
    162     return (Element *)elem;
    163 }
    164 
    165 void Element::compute() {
    166     mHal.state.dataType = mComponent.getType();
    167     mHal.state.dataKind = mComponent.getKind();
    168     mHal.state.vectorSize = mComponent.getVectorSize();
    169 
    170     if (mFieldCount == 0) {
    171         mBits = mComponent.getBits();
    172         mBitsUnpadded = mComponent.getBitsUnpadded();
    173         mHasReference = mComponent.isReference();
    174 
    175         mHal.state.elementSizeBytes = getSizeBytes();
    176         return;
    177     }
    178 
    179     uint32_t noPaddingFieldCount = 0;
    180     for (uint32_t ct = 0; ct < mFieldCount; ct ++) {
    181         if (mFields[ct].name[0] != '#') {
    182             noPaddingFieldCount ++;
    183         }
    184     }
    185 
    186     mHal.state.fields = new const Element*[noPaddingFieldCount];
    187     mHal.state.fieldArraySizes = new uint32_t[noPaddingFieldCount];
    188     mHal.state.fieldNames = new const char*[noPaddingFieldCount];
    189     mHal.state.fieldNameLengths = new uint32_t[noPaddingFieldCount];
    190     mHal.state.fieldOffsetBytes = new uint32_t[noPaddingFieldCount];
    191     mHal.state.fieldsCount = noPaddingFieldCount;
    192 
    193     size_t bits = 0;
    194     size_t bitsUnpadded = 0;
    195     for (size_t ct = 0, ctNoPadding = 0; ct < mFieldCount; ct++) {
    196         mFields[ct].offsetBits = bits;
    197         mFields[ct].offsetBitsUnpadded = bitsUnpadded;
    198         bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize;
    199         bitsUnpadded += mFields[ct].e->getSizeBitsUnpadded() * mFields[ct].arraySize;
    200 
    201         if (mFields[ct].e->mHasReference) {
    202             mHasReference = true;
    203         }
    204 
    205         if (mFields[ct].name[0] == '#') {
    206             continue;
    207         }
    208 
    209         mHal.state.fields[ctNoPadding] = mFields[ct].e.get();
    210         mHal.state.fieldArraySizes[ctNoPadding] = mFields[ct].arraySize;
    211         mHal.state.fieldNames[ctNoPadding] = mFields[ct].name;
    212         mHal.state.fieldNameLengths[ctNoPadding] = strlen(mFields[ct].name) + 1; // to include 0
    213         mHal.state.fieldOffsetBytes[ctNoPadding] = mFields[ct].offsetBits >> 3;
    214 
    215         ctNoPadding ++;
    216     }
    217 
    218     mHal.state.elementSizeBytes = getSizeBytes();
    219 }
    220 
    221 ObjectBaseRef<const Element> Element::createRef(Context *rsc, RsDataType dt, RsDataKind dk,
    222                                 bool isNorm, uint32_t vecSize) {
    223     ObjectBaseRef<const Element> returnRef;
    224     // Look for an existing match.
    225     ObjectBase::asyncLock();
    226     for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
    227         const Element *ee = rsc->mStateElement.mElements[ct];
    228         if (!ee->getFieldCount() &&
    229             (ee->getComponent().getType() == dt) &&
    230             (ee->getComponent().getKind() == dk) &&
    231             (ee->getComponent().getIsNormalized() == isNorm) &&
    232             (ee->getComponent().getVectorSize() == vecSize)) {
    233             // Match
    234             returnRef.set(ee);
    235             ObjectBase::asyncUnlock();
    236             return ee;
    237         }
    238     }
    239     ObjectBase::asyncUnlock();
    240 
    241     Element *e = new Element(rsc);
    242     returnRef.set(e);
    243     e->mComponent.set(dt, dk, isNorm, vecSize);
    244     e->compute();
    245 
    246     ObjectBase::asyncLock();
    247     rsc->mStateElement.mElements.push(e);
    248     ObjectBase::asyncUnlock();
    249 
    250     return returnRef;
    251 }
    252 
    253 ObjectBaseRef<const Element> Element::createRef(Context *rsc, size_t count, const Element **ein,
    254                             const char **nin, const size_t * lengths, const uint32_t *asin) {
    255 
    256     ObjectBaseRef<const Element> returnRef;
    257     // Look for an existing match.
    258     ObjectBase::asyncLock();
    259     for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
    260         const Element *ee = rsc->mStateElement.mElements[ct];
    261         if (ee->getFieldCount() == count) {
    262             bool match = true;
    263             for (uint32_t i=0; i < count; i++) {
    264                 size_t len;
    265                 uint32_t asize = 1;
    266                 if (lengths) {
    267                     len = lengths[i];
    268                 } else {
    269                     len = strlen(nin[i]);
    270                 }
    271                 if (asin) {
    272                     asize = asin[i];
    273                 }
    274 
    275                 if ((ee->mFields[i].e.get() != ein[i]) ||
    276                     (strlen(ee->mFields[i].name) != len) ||
    277                     strcmp(ee->mFields[i].name, nin[i]) ||
    278                     (ee->mFields[i].arraySize != asize)) {
    279                     match = false;
    280                     break;
    281                 }
    282             }
    283             if (match) {
    284                 returnRef.set(ee);
    285                 ObjectBase::asyncUnlock();
    286                 return returnRef;
    287             }
    288         }
    289     }
    290     ObjectBase::asyncUnlock();
    291 
    292     Element *e = new Element(rsc);
    293     returnRef.set(e);
    294     e->mFields = new ElementField_t [count];
    295     e->mFieldCount = count;
    296     for (size_t ct=0; ct < count; ct++) {
    297         size_t len;
    298         uint32_t asize = 1;
    299         if (lengths) {
    300             len = lengths[ct];
    301         } else {
    302             len = strlen(nin[ct]);
    303         }
    304         if (asin) {
    305             asize = asin[ct];
    306         }
    307 
    308         e->mFields[ct].e.set(ein[ct]);
    309         e->mFields[ct].name = rsuCopyString(nin[ct], len);
    310         e->mFields[ct].arraySize = asize;
    311     }
    312     e->compute();
    313 
    314     ObjectBase::asyncLock();
    315     rsc->mStateElement.mElements.push(e);
    316     ObjectBase::asyncUnlock();
    317 
    318     return returnRef;
    319 }
    320 
    321 void Element::incRefs(const void *ptr) const {
    322     if (!mFieldCount) {
    323         if (mComponent.isReference()) {
    324             ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
    325             ObjectBase *ob = obp[0];
    326             if (ob) ob->incSysRef();
    327         }
    328         return;
    329     }
    330 
    331     const uint8_t *p = static_cast<const uint8_t *>(ptr);
    332     for (uint32_t i=0; i < mFieldCount; i++) {
    333         if (mFields[i].e->mHasReference) {
    334             const uint8_t *p2 = &p[mFields[i].offsetBits >> 3];
    335             for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
    336                 mFields[i].e->incRefs(p2);
    337                 p2 += mFields[i].e->getSizeBytes();
    338             }
    339         }
    340     }
    341 }
    342 
    343 void Element::decRefs(const void *ptr) const {
    344     if (!mFieldCount) {
    345         if (mComponent.isReference()) {
    346             ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
    347             ObjectBase *ob = obp[0];
    348             if (ob) ob->decSysRef();
    349         }
    350         return;
    351     }
    352 
    353     const uint8_t *p = static_cast<const uint8_t *>(ptr);
    354     for (uint32_t i=0; i < mFieldCount; i++) {
    355         if (mFields[i].e->mHasReference) {
    356             const uint8_t *p2 = &p[mFields[i].offsetBits >> 3];
    357             for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
    358                 mFields[i].e->decRefs(p2);
    359                 p2 += mFields[i].e->getSizeBytes();
    360             }
    361         }
    362     }
    363 }
    364 
    365 ElementState::ElementState() {
    366 }
    367 
    368 ElementState::~ElementState() {
    369     rsAssert(!mElements.size());
    370 }
    371 
    372 /////////////////////////////////////////
    373 //
    374 
    375 namespace android {
    376 namespace renderscript {
    377 
    378 RsElement rsi_ElementCreate(Context *rsc,
    379                             RsDataType dt,
    380                             RsDataKind dk,
    381                             bool norm,
    382                             uint32_t vecSize) {
    383     return (RsElement)Element::create(rsc, dt, dk, norm, vecSize);
    384 }
    385 
    386 
    387 RsElement rsi_ElementCreate2(Context *rsc,
    388                              const RsElement * ein,
    389                              size_t ein_length,
    390 
    391                              const char ** names,
    392                              size_t nameLengths_length,
    393                              const size_t * nameLengths,
    394 
    395                              const uint32_t * arraySizes,
    396                              size_t arraySizes_length) {
    397     return (RsElement)Element::create(rsc, ein_length, (const Element **)ein,
    398                                       names, nameLengths, arraySizes);
    399 }
    400 
    401 }
    402 }
    403 
    404 extern "C" void rsaElementGetNativeData(RsContext con, RsElement elem,
    405                              uint32_t *elemData, uint32_t elemDataSize) {
    406     rsAssert(elemDataSize == 5);
    407     // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
    408     Element *e = static_cast<Element *>(elem);
    409 
    410     (*elemData++) = (uint32_t)e->getType();
    411     (*elemData++) = (uint32_t)e->getKind();
    412     (*elemData++) = e->getComponent().getIsNormalized() ? 1 : 0;
    413     (*elemData++) = e->getComponent().getVectorSize();
    414     (*elemData++) = e->getFieldCount();
    415 }
    416 
    417 extern "C" void rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids,
    418                               const char **names, size_t *arraySizes, uint32_t dataSize) {
    419     Element *e = static_cast<Element *>(elem);
    420     rsAssert(e->getFieldCount() == dataSize);
    421 
    422     for (uint32_t i = 0; i < dataSize; i ++) {
    423         e->getField(i)->incUserRef();
    424         ids[i] = (uintptr_t)e->getField(i);
    425         names[i] = e->getFieldName(i);
    426         arraySizes[i] = e->getFieldArraySize(i);
    427     }
    428 }
    429