rsElement.cpp revision a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12
1589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian/* 2589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * Copyright (C) 2009 The Android Open Source Project 3589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * 4589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * you may not use this file except in compliance with the License. 6589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * You may obtain a copy of the License at 7589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * 8589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * 10589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * Unless required by applicable law or agreed to in writing, software 11589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * See the License for the specific language governing permissions and 14589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * limitations under the License. 15589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian */ 16589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 17801ea093b0e923a61b832f2adba698a273479880Mathias Agopian 18801ea093b0e923a61b832f2adba698a273479880Mathias Agopian#include "rsContext.h" 19589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 207b5be95cb3903087742f1079fe89cddd8abe3696Mathias Agopianusing namespace android; 2127c8115510cebda13cbe24fd4caa946ea9c5003cDan Stozausing namespace android::renderscript; 22589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 23589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 2499fe3c6d3dcb6fb26bf283343f946d031b052dffMathias AgopianElement::Element(Context *rsc) : ObjectBase(rsc) { 25589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mBits = 0; 26589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mBitsUnpadded = 0; 27589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mFields = NULL; 28589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mFieldCount = 0; 29589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mHasReference = false; 30589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian memset(&mHal, 0, sizeof(mHal)); 3127c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza} 32589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 3327c8115510cebda13cbe24fd4caa946ea9c5003cDan StozaElement::~Element() { 3427c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza clear(); 3590ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian} 367b5be95cb3903087742f1079fe89cddd8abe3696Mathias Agopian 377d290174b08a56ae6bc6719bec58805ca38b348bDan Stozavoid Element::preDestroy() const { 3890ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) { 39589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (mRSC->mStateElement.mElements[ct] == this) { 40589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mRSC->mStateElement.mElements.removeAt(ct); 417d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza break; 42589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 437d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza } 447d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza} 45589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 46589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopianvoid Element::clear() { 4790ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian if (mFields) { 4890ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian for (size_t i = 0; i < mFieldCount; i++) { 4990ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian delete[] mFields[i].name; 5090ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian } 5190ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian delete [] mFields; 5290ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian } 5327c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza mFields = NULL; 5490ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian mFieldCount = 0; 5590ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian mHasReference = false; 5690ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian 5790ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian delete [] mHal.state.fields; 587d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza delete [] mHal.state.fieldArraySizes; 597d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza delete [] mHal.state.fieldNames; 6090ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian delete [] mHal.state.fieldNameLengths; 617d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza delete [] mHal.state.fieldOffsetBytes; 627d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza} 6390ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian 6490ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopiansize_t Element::getSizeBits() const { 6590ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian if (!mFieldCount) { 6627c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza return mBits; 675cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian } 685cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian 695cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian size_t total = 0; 705cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian for (size_t ct=0; ct < mFieldCount; ct++) { 715cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian total += mFields[ct].e->mBits * mFields[ct].arraySize; 725cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian } 7327c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza return total; 74589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 75589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 76589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopiansize_t Element::getSizeBitsUnpadded() const { 7727c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza if (!mFieldCount) { 7856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return mBitsUnpadded; 7956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 8056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 816b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza size_t total = 0; 826b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza for (size_t ct=0; ct < mFieldCount; ct++) { 836b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza total += mFields[ct].e->mBitsUnpadded * mFields[ct].arraySize; 846b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza } 856b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza return total; 866b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza} 876b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza 886b698e4fe4ff50dcef818452283637f9870ae770Dan Stozavoid Element::dumpLOGV(const char *prefix) const { 8927c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza ObjectBase::dumpLOGV(prefix); 905cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian ALOGV("%s Element: fieldCount: %zu, size bytes: %zu", prefix, mFieldCount, getSizeBytes()); 915cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian mComponent.dumpLOGV(prefix); 927b5be95cb3903087742f1079fe89cddd8abe3696Mathias Agopian for (uint32_t ct = 0; ct < mFieldCount; ct++) { 9390ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian ALOGV("%s Element field index: %u ------------------", prefix, ct); 945cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian ALOGV("%s name: %s, offsetBits: %u, arraySize: %u", 955cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian prefix, mFields[ct].name, mFields[ct].offsetBits, mFields[ct].arraySize); 965cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian mFields[ct].e->dumpLOGV(prefix); 97589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 98589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 9927c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza 1005cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopianvoid Element::serialize(Context *rsc, OStream *stream) const { 1015cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian // Need to identify ourselves 1027b5be95cb3903087742f1079fe89cddd8abe3696Mathias Agopian stream->addU32((uint32_t)getClassId()); 1035cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian stream->addString(getName()); 1045cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian 1053ad3807a5c4039618175c042a1121c926c2c62e9Mathias Agopian mComponent.serialize(stream); 10627c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza 10727c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza // Now serialize all the fields 1083ad3807a5c4039618175c042a1121c926c2c62e9Mathias Agopian stream->addU32(mFieldCount); 1093ad3807a5c4039618175c042a1121c926c2c62e9Mathias Agopian for (uint32_t ct = 0; ct < mFieldCount; ct++) { 1105cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian stream->addString(mFields[ct].name); 111589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian stream->addU32(mFields[ct].arraySize); 112589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mFields[ct].e->serialize(rsc, stream); 11327c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza } 11427c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza} 115589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 116589ce85ee4174829cfedce91b6b2509d2a4002ebMathias AgopianElement *Element::createFromStream(Context *rsc, IStream *stream) { 1177d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza // First make sure we are reading the correct object 118589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian RsA3DClassID classID = (RsA3DClassID)stream->loadU32(); 119589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (classID != RS_A3D_CLASS_ID_ELEMENT) { 120589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian ALOGE("element loading skipped due to invalid class id\n"); 1217d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza return NULL; 1227d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza } 1237d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza 1247d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza const char *name = stream->loadString(); 1257d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza 1267d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza Component component; 1277d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza component.loadFromStream(stream); 1287d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza 1297d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza uint32_t fieldCount = stream->loadU32(); 1307d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza if (!fieldCount) { 1317d290174b08a56ae6bc6719bec58805ca38b348bDan Stoza return (Element *)Element::create(rsc, 1326b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza component.getType(), 13390ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian component.getKind(), 13427c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza component.getIsNormalized(), 13590ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian component.getVectorSize()); 13690ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian } 137d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza 13827c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza const Element **subElems = new const Element *[fieldCount]; 13927c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza const char **subElemNames = new const char *[fieldCount]; 14027c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza size_t *subElemNamesLengths = new size_t[fieldCount]; 14190ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian uint32_t *arraySizes = new uint32_t[fieldCount]; 14227c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza 143d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza for (uint32_t ct = 0; ct < fieldCount; ct ++) { 1447b5be95cb3903087742f1079fe89cddd8abe3696Mathias Agopian subElemNames[ct] = stream->loadString(); 1457b5be95cb3903087742f1079fe89cddd8abe3696Mathias Agopian subElemNamesLengths[ct] = strlen(subElemNames[ct]); 1466b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza arraySizes[ct] = stream->loadU32(); 14790ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian subElems[ct] = Element::createFromStream(rsc, stream); 14827c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza } 14990ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian 15090ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian const Element *elem = Element::create(rsc, fieldCount, subElems, subElemNames, 151d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza subElemNamesLengths, arraySizes); 15227c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza for (uint32_t ct = 0; ct < fieldCount; ct ++) { 15327c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza delete [] subElemNames[ct]; 15427c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza subElems[ct]->decUserRef(); 15590ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian } 15627c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza delete[] name; 157d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza delete[] subElems; 1587b5be95cb3903087742f1079fe89cddd8abe3696Mathias Agopian delete[] subElemNames; 1597b5be95cb3903087742f1079fe89cddd8abe3696Mathias Agopian delete[] subElemNamesLengths; 16027c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza delete[] arraySizes; 16127c8115510cebda13cbe24fd4caa946ea9c5003cDan Stoza 162 return (Element *)elem; 163} 164 165void Element::compute() { 166 mHal.state.dataType = mComponent.getType(); 167 mHal.state.dataKind = mComponent.getKind(); 168 mHal.state.vectorSize = mComponent.getVectorSize(); 169 170 if (mFieldCount == 0) { 171 mBits = mComponent.getBits(); 172 mBitsUnpadded = mComponent.getBitsUnpadded(); 173 mHasReference = mComponent.isReference(); 174 175 mHal.state.elementSizeBytes = getSizeBytes(); 176 return; 177 } 178 179 uint32_t noPaddingFieldCount = 0; 180 for (uint32_t ct = 0; ct < mFieldCount; ct ++) { 181 if (mFields[ct].name[0] != '#') { 182 noPaddingFieldCount ++; 183 } 184 } 185 186 mHal.state.fields = new const Element*[noPaddingFieldCount]; 187 mHal.state.fieldArraySizes = new uint32_t[noPaddingFieldCount]; 188 mHal.state.fieldNames = new const char*[noPaddingFieldCount]; 189 mHal.state.fieldNameLengths = new uint32_t[noPaddingFieldCount]; 190 mHal.state.fieldOffsetBytes = new uint32_t[noPaddingFieldCount]; 191 mHal.state.fieldsCount = noPaddingFieldCount; 192 193 size_t bits = 0; 194 size_t bitsUnpadded = 0; 195 for (size_t ct = 0, ctNoPadding = 0; ct < mFieldCount; ct++) { 196 mFields[ct].offsetBits = bits; 197 mFields[ct].offsetBitsUnpadded = bitsUnpadded; 198 bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize; 199 bitsUnpadded += mFields[ct].e->getSizeBitsUnpadded() * mFields[ct].arraySize; 200 201 if (mFields[ct].e->mHasReference) { 202 mHasReference = true; 203 } 204 205 if (mFields[ct].name[0] == '#') { 206 continue; 207 } 208 209 mHal.state.fields[ctNoPadding] = mFields[ct].e.get(); 210 mHal.state.fieldArraySizes[ctNoPadding] = mFields[ct].arraySize; 211 mHal.state.fieldNames[ctNoPadding] = mFields[ct].name; 212 mHal.state.fieldNameLengths[ctNoPadding] = strlen(mFields[ct].name) + 1; // to include 0 213 mHal.state.fieldOffsetBytes[ctNoPadding] = mFields[ct].offsetBits >> 3; 214 215 ctNoPadding ++; 216 } 217 218 mHal.state.elementSizeBytes = getSizeBytes(); 219} 220 221ObjectBaseRef<const Element> Element::createRef(Context *rsc, RsDataType dt, RsDataKind dk, 222 bool isNorm, uint32_t vecSize) { 223 ObjectBaseRef<const Element> returnRef; 224 // Look for an existing match. 225 ObjectBase::asyncLock(); 226 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) { 227 const Element *ee = rsc->mStateElement.mElements[ct]; 228 if (!ee->getFieldCount() && 229 (ee->getComponent().getType() == dt) && 230 (ee->getComponent().getKind() == dk) && 231 (ee->getComponent().getIsNormalized() == isNorm) && 232 (ee->getComponent().getVectorSize() == vecSize)) { 233 // Match 234 returnRef.set(ee); 235 ObjectBase::asyncUnlock(); 236 return ee; 237 } 238 } 239 ObjectBase::asyncUnlock(); 240 241 // Element objects must use allocator specified by the driver 242 void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Element), 0); 243 if (!allocMem) { 244 rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Element"); 245 return NULL; 246 } 247 248 Element *e = new (allocMem) Element(rsc); 249 returnRef.set(e); 250 e->mComponent.set(dt, dk, isNorm, vecSize); 251 e->compute(); 252 253#ifdef RS_FIND_OFFSETS 254 ALOGE("pointer for element: %p", e); 255 ALOGE("pointer for element.drv: %p", &e->mHal.drv); 256#endif 257 258 259 ObjectBase::asyncLock(); 260 rsc->mStateElement.mElements.push(e); 261 ObjectBase::asyncUnlock(); 262 263 return returnRef; 264} 265 266ObjectBaseRef<const Element> Element::createRef(Context *rsc, size_t count, const Element **ein, 267 const char **nin, const size_t * lengths, const uint32_t *asin) { 268 269 ObjectBaseRef<const Element> returnRef; 270 // Look for an existing match. 271 ObjectBase::asyncLock(); 272 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) { 273 const Element *ee = rsc->mStateElement.mElements[ct]; 274 if (ee->getFieldCount() == count) { 275 bool match = true; 276 for (uint32_t i=0; i < count; i++) { 277 size_t len; 278 uint32_t asize = 1; 279 if (lengths) { 280 len = lengths[i]; 281 } else { 282 len = strlen(nin[i]); 283 } 284 if (asin) { 285 asize = asin[i]; 286 } 287 288 if ((ee->mFields[i].e.get() != ein[i]) || 289 (strlen(ee->mFields[i].name) != len) || 290 strcmp(ee->mFields[i].name, nin[i]) || 291 (ee->mFields[i].arraySize != asize)) { 292 match = false; 293 break; 294 } 295 } 296 if (match) { 297 returnRef.set(ee); 298 ObjectBase::asyncUnlock(); 299 return returnRef; 300 } 301 } 302 } 303 ObjectBase::asyncUnlock(); 304 305 // Element objects must use allocator specified by the driver 306 void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Element), 0); 307 if (!allocMem) { 308 rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Element"); 309 return NULL; 310 } 311 312 Element *e = new (allocMem) Element(rsc); 313 returnRef.set(e); 314 e->mFields = new ElementField_t [count]; 315 e->mFieldCount = count; 316 for (size_t ct=0; ct < count; ct++) { 317 size_t len; 318 uint32_t asize = 1; 319 if (lengths) { 320 len = lengths[ct]; 321 } else { 322 len = strlen(nin[ct]); 323 } 324 if (asin) { 325 asize = asin[ct]; 326 } 327 328 e->mFields[ct].e.set(ein[ct]); 329 e->mFields[ct].name = rsuCopyString(nin[ct], len); 330 e->mFields[ct].arraySize = asize; 331 } 332 e->compute(); 333 334 ObjectBase::asyncLock(); 335 rsc->mStateElement.mElements.push(e); 336 ObjectBase::asyncUnlock(); 337 338 return returnRef; 339} 340 341void Element::incRefs(const void *ptr) const { 342 if (!mFieldCount) { 343 if (mComponent.isReference()) { 344 ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr); 345 ObjectBase *ob = obp[0]; 346 if (ob) ob->incSysRef(); 347 } 348 return; 349 } 350 351 const uint8_t *p = static_cast<const uint8_t *>(ptr); 352 for (uint32_t i=0; i < mFieldCount; i++) { 353 if (mFields[i].e->mHasReference) { 354 const uint8_t *p2 = &p[mFields[i].offsetBits >> 3]; 355 for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) { 356 mFields[i].e->incRefs(p2); 357 p2 += mFields[i].e->getSizeBytes(); 358 } 359 } 360 } 361} 362 363void Element::decRefs(const void *ptr) const { 364 if (!mFieldCount) { 365 if (mComponent.isReference()) { 366 ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr); 367 ObjectBase *ob = obp[0]; 368 if (ob) ob->decSysRef(); 369 } 370 return; 371 } 372 373 const uint8_t *p = static_cast<const uint8_t *>(ptr); 374 for (uint32_t i=0; i < mFieldCount; i++) { 375 if (mFields[i].e->mHasReference) { 376 const uint8_t *p2 = &p[mFields[i].offsetBits >> 3]; 377 for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) { 378 mFields[i].e->decRefs(p2); 379 p2 += mFields[i].e->getSizeBytes(); 380 } 381 } 382 } 383} 384 385void Element::callUpdateCacheObject(const Context *rsc, void *dstObj) const { 386 if (rsc->mHal.funcs.element.updateCachedObject != NULL) { 387 rsc->mHal.funcs.element.updateCachedObject(rsc, this, (rs_element *)dstObj); 388 } else { 389 *((const void **)dstObj) = this; 390 } 391} 392 393ElementState::ElementState() { 394} 395 396ElementState::~ElementState() { 397 rsAssert(!mElements.size()); 398} 399 400///////////////////////////////////////// 401// 402 403namespace android { 404namespace renderscript { 405 406RsElement rsi_ElementCreate(Context *rsc, 407 RsDataType dt, 408 RsDataKind dk, 409 bool norm, 410 uint32_t vecSize) { 411 return (RsElement)Element::create(rsc, dt, dk, norm, vecSize); 412} 413 414 415RsElement rsi_ElementCreate2(Context *rsc, 416 const RsElement * ein, 417 size_t ein_length, 418 419 const char ** names, 420 size_t nameLengths_length, 421 const size_t * nameLengths, 422 423 const uint32_t * arraySizes, 424 size_t arraySizes_length) { 425 return (RsElement)Element::create(rsc, ein_length, (const Element **)ein, 426 names, nameLengths, arraySizes); 427} 428 429} 430} 431 432extern "C" void rsaElementGetNativeData(RsContext con, RsElement elem, 433 uint32_t *elemData, uint32_t elemDataSize) { 434 rsAssert(elemDataSize == 5); 435 // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements 436 Element *e = static_cast<Element *>(elem); 437 438 (*elemData++) = (uint32_t)e->getType(); 439 (*elemData++) = (uint32_t)e->getKind(); 440 (*elemData++) = e->getComponent().getIsNormalized() ? 1 : 0; 441 (*elemData++) = e->getComponent().getVectorSize(); 442 (*elemData++) = e->getFieldCount(); 443} 444 445extern "C" void rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids, 446 const char **names, size_t *arraySizes, uint32_t dataSize) { 447 Element *e = static_cast<Element *>(elem); 448 rsAssert(e->getFieldCount() == dataSize); 449 450 for (uint32_t i = 0; i < dataSize; i ++) { 451 e->getField(i)->incUserRef(); 452 ids[i] = (uintptr_t)e->getField(i); 453 names[i] = e->getFieldName(i); 454 arraySizes[i] = e->getFieldArraySize(i); 455 } 456} 457