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