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