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