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