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