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