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