rsElement.cpp revision 10e5e570bab66a6cd543c857b26c576795eb240f
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; 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 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 elem->mBits = elem->mComponent.getBits(); 117 elem->mHasReference = elem->mComponent.isReference(); 118 119 elem->mFieldCount = stream->loadU32(); 120 if(elem->mFieldCount) { 121 uint32_t offset = 0; 122 elem->mFields = new ElementField_t [elem->mFieldCount]; 123 for(uint32_t ct = 0; ct < elem->mFieldCount; ct ++) { 124 stream->loadString(&elem->mFields[ct].name); 125 Element *fieldElem = Element::createFromStream(rsc, stream); 126 elem->mFields[ct].e.set(fieldElem); 127 elem->mFields[ct].offsetBits = offset; 128 offset += fieldElem->getSizeBits(); 129 // Check if our sub-elements have references 130 if(fieldElem->mHasReference) { 131 elem->mHasReference = true; 132 } 133 } 134 } 135 136 // We need to check if this already exists 137 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) { 138 Element *ee = rsc->mStateElement.mElements[ct]; 139 140 if (!ee->getFieldCount() ) { 141 142 if((ee->getComponent().getType() == elem->getComponent().getType()) && 143 (ee->getComponent().getKind() == elem->getComponent().getKind()) && 144 (ee->getComponent().getIsNormalized() == elem->getComponent().getIsNormalized()) && 145 (ee->getComponent().getVectorSize() == elem->getComponent().getVectorSize())) { 146 // Match 147 delete elem; 148 ee->incUserRef(); 149 return ee; 150 } 151 152 } else if (ee->getFieldCount() == elem->mFieldCount) { 153 154 bool match = true; 155 for (uint32_t i=0; i < elem->mFieldCount; i++) { 156 if ((ee->mFields[i].e.get() != elem->mFields[i].e.get()) || 157 (ee->mFields[i].name.length() != elem->mFields[i].name.length()) || 158 (ee->mFields[i].name != elem->mFields[i].name)) { 159 match = false; 160 break; 161 } 162 } 163 if (match) { 164 delete elem; 165 ee->incUserRef(); 166 return ee; 167 } 168 169 } 170 } 171 172 rsc->mStateElement.mElements.push(elem); 173 return elem; 174} 175 176 177const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk, 178 bool isNorm, uint32_t vecSize) 179{ 180 // Look for an existing match. 181 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) { 182 const Element *ee = rsc->mStateElement.mElements[ct]; 183 if (!ee->getFieldCount() && 184 (ee->getComponent().getType() == dt) && 185 (ee->getComponent().getKind() == dk) && 186 (ee->getComponent().getIsNormalized() == isNorm) && 187 (ee->getComponent().getVectorSize() == vecSize)) { 188 // Match 189 ee->incUserRef(); 190 return ee; 191 } 192 } 193 194 Element *e = new Element(rsc); 195 e->mComponent.set(dt, dk, isNorm, vecSize); 196 e->mBits = e->mComponent.getBits(); 197 e->mHasReference = e->mComponent.isReference(); 198 rsc->mStateElement.mElements.push(e); 199 return e; 200} 201 202const Element * Element::create(Context *rsc, size_t count, const Element **ein, 203 const char **nin, const size_t * lengths) 204{ 205 // Look for an existing match. 206 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) { 207 const Element *ee = rsc->mStateElement.mElements[ct]; 208 if (ee->getFieldCount() == count) { 209 bool match = true; 210 for (uint32_t i=0; i < count; i++) { 211 if ((ee->mFields[i].e.get() != ein[i]) || 212 (ee->mFields[i].name.length() != lengths[i]) || 213 (ee->mFields[i].name != nin[i])) { 214 match = false; 215 break; 216 } 217 } 218 if (match) { 219 ee->incUserRef(); 220 return ee; 221 } 222 } 223 } 224 225 Element *e = new Element(rsc); 226 e->mFields = new ElementField_t [count]; 227 e->mFieldCount = count; 228 size_t bits = 0; 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].offsetBits = bits; 233 bits += ein[ct]->getSizeBits(); 234 235 if (ein[ct]->mHasReference) { 236 e->mHasReference = true; 237 } 238 } 239 240 rsc->mStateElement.mElements.push(e); 241 return e; 242} 243 244String8 Element::getGLSLType(uint32_t indent) const 245{ 246 String8 s; 247 for (uint32_t ct=0; ct < indent; ct++) { 248 s.append(" "); 249 } 250 251 if (!mFieldCount) { 252 // Basic component. 253 s.append(mComponent.getGLSLType()); 254 } else { 255 rsAssert(0); 256 //s.append("struct "); 257 //s.append(getCStructBody(indent)); 258 } 259 260 return s; 261} 262 263void Element::incRefs(const void *ptr) const 264{ 265 if (!mFieldCount) { 266 if (mComponent.isReference()) { 267 ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr); 268 ObjectBase *ob = obp[0]; 269 if (ob) ob->incSysRef(); 270 } 271 return; 272 } 273 274 const uint8_t *p = static_cast<const uint8_t *>(ptr); 275 for (uint32_t i=0; i < mFieldCount; i++) { 276 if (mFields[i].e->mHasReference) { 277 mFields[i].e->incRefs(&p[mFields[i].offsetBits >> 3]); 278 } 279 } 280} 281 282void Element::decRefs(const void *ptr) const 283{ 284 if (!mFieldCount) { 285 if (mComponent.isReference()) { 286 ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr); 287 ObjectBase *ob = obp[0]; 288 if (ob) ob->decSysRef(); 289 } 290 return; 291 } 292 293 const uint8_t *p = static_cast<const uint8_t *>(ptr); 294 for (uint32_t i=0; i < mFieldCount; i++) { 295 if (mFields[i].e->mHasReference) { 296 mFields[i].e->decRefs(&p[mFields[i].offsetBits >> 3]); 297 } 298 } 299} 300 301 302ElementState::ElementState() 303{ 304} 305 306ElementState::~ElementState() 307{ 308 rsAssert(!mElements.size()); 309} 310 311 312///////////////////////////////////////// 313// 314 315namespace android { 316namespace renderscript { 317 318RsElement rsi_ElementCreate(Context *rsc, 319 RsDataType dt, 320 RsDataKind dk, 321 bool norm, 322 uint32_t vecSize) 323{ 324 //LOGE("rsi_ElementCreate %i %i %i %i", dt, dk, norm, vecSize); 325 const Element *e = Element::create(rsc, dt, dk, norm, vecSize); 326 e->incUserRef(); 327 return (RsElement)e; 328} 329 330RsElement rsi_ElementCreate2(Context *rsc, 331 size_t count, 332 const RsElement * ein, 333 const char ** names, 334 const size_t * nameLengths) 335{ 336 //LOGE("rsi_ElementCreate2 %i", count); 337 const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths); 338 e->incUserRef(); 339 return (RsElement)e; 340} 341 342void rsi_ElementGetNativeData(Context *rsc, RsElement elem, uint32_t *elemData, uint32_t elemDataSize) 343{ 344 rsAssert(elemDataSize == 5); 345 // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements 346 Element *e = static_cast<Element *>(elem); 347 348 (*elemData++) = (uint32_t)e->getType(); 349 (*elemData++) = (uint32_t)e->getKind(); 350 (*elemData++) = e->getComponent().getIsNormalized() ? 1 : 0; 351 (*elemData++) = e->getComponent().getVectorSize(); 352 (*elemData++) = e->getFieldCount(); 353 354} 355 356void rsi_ElementGetSubElements(Context *rsc, RsElement elem, uint32_t *ids, const char **names, uint32_t dataSize) 357{ 358 Element *e = static_cast<Element *>(elem); 359 rsAssert(e->getFieldCount() == dataSize); 360 361 for(uint32_t i = 0; i < dataSize; i ++) { 362 ids[i] = (uint32_t)e->getField(i); 363 names[i] = e->getFieldName(i); 364 } 365 366} 367 368 369} 370} 371