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