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