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