• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "rsContext.h"
19 
20 using namespace android;
21 using namespace android::renderscript;
22 
23 
Element(Context * rsc)24 Element::Element(Context *rsc) : ObjectBase(rsc) {
25     mBits = 0;
26     mBitsUnpadded = 0;
27     mFields = NULL;
28     mFieldCount = 0;
29     mHasReference = false;
30     memset(&mHal, 0, sizeof(mHal));
31 }
32 
~Element()33 Element::~Element() {
34     clear();
35 }
36 
preDestroy() const37 void Element::preDestroy() const {
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 }
45 
clear()46 void Element::clear() {
47     delete [] mFields;
48     mFields = NULL;
49     mFieldCount = 0;
50     mHasReference = false;
51 
52     delete [] mHal.state.fields;
53     delete [] mHal.state.fieldArraySizes;
54     delete [] mHal.state.fieldNames;
55     delete [] mHal.state.fieldNameLengths;
56     delete [] mHal.state.fieldOffsetBytes;
57 }
58 
getSizeBits() const59 size_t Element::getSizeBits() const {
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 
getSizeBitsUnpadded() const71 size_t Element::getSizeBitsUnpadded() const {
72     if (!mFieldCount) {
73         return mBitsUnpadded;
74     }
75 
76     size_t total = 0;
77     for (size_t ct=0; ct < mFieldCount; ct++) {
78         total += mFields[ct].e->mBitsUnpadded * mFields[ct].arraySize;
79     }
80     return total;
81 }
82 
dumpLOGV(const char * prefix) const83 void Element::dumpLOGV(const char *prefix) const {
84     ObjectBase::dumpLOGV(prefix);
85     ALOGV("%s Element: fieldCount: %zu,  size bytes: %zu", prefix, mFieldCount, getSizeBytes());
86     mComponent.dumpLOGV(prefix);
87     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
88         ALOGV("%s Element field index: %u ------------------", prefix, ct);
89         ALOGV("%s name: %s, offsetBits: %u, arraySize: %u",
90              prefix, mFields[ct].name.string(), mFields[ct].offsetBits, mFields[ct].arraySize);
91         mFields[ct].e->dumpLOGV(prefix);
92     }
93 }
94 
serialize(Context * rsc,OStream * stream) const95 void Element::serialize(Context *rsc, OStream *stream) const {
96     // Need to identify ourselves
97     stream->addU32((uint32_t)getClassId());
98 
99     String8 name(getName());
100     stream->addString(&name);
101 
102     mComponent.serialize(stream);
103 
104     // Now serialize all the fields
105     stream->addU32(mFieldCount);
106     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
107         stream->addString(&mFields[ct].name);
108         stream->addU32(mFields[ct].arraySize);
109         mFields[ct].e->serialize(rsc, stream);
110     }
111 }
112 
createFromStream(Context * rsc,IStream * stream)113 Element *Element::createFromStream(Context *rsc, IStream *stream) {
114     // First make sure we are reading the correct object
115     RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
116     if (classID != RS_A3D_CLASS_ID_ELEMENT) {
117         ALOGE("element loading skipped due to invalid class id\n");
118         return NULL;
119     }
120 
121     String8 name;
122     stream->loadString(&name);
123 
124     Component component;
125     component.loadFromStream(stream);
126 
127     uint32_t fieldCount = stream->loadU32();
128     if (!fieldCount) {
129         return (Element *)Element::create(rsc,
130                                           component.getType(),
131                                           component.getKind(),
132                                           component.getIsNormalized(),
133                                           component.getVectorSize());
134     }
135 
136     const Element **subElems = new const Element *[fieldCount];
137     const char **subElemNames = new const char *[fieldCount];
138     size_t *subElemNamesLengths = new size_t[fieldCount];
139     uint32_t *arraySizes = new uint32_t[fieldCount];
140 
141     String8 elemName;
142     for (uint32_t ct = 0; ct < fieldCount; ct ++) {
143         stream->loadString(&elemName);
144         subElemNamesLengths[ct] = elemName.length();
145         char *tmpName = new char[subElemNamesLengths[ct]];
146         memcpy(tmpName, elemName.string(), subElemNamesLengths[ct]);
147         subElemNames[ct] = tmpName;
148         arraySizes[ct] = stream->loadU32();
149         subElems[ct] = Element::createFromStream(rsc, stream);
150     }
151 
152     const Element *elem = Element::create(rsc, fieldCount, subElems, subElemNames,
153                                           subElemNamesLengths, arraySizes);
154     for (uint32_t ct = 0; ct < fieldCount; ct ++) {
155         delete [] subElemNames[ct];
156         subElems[ct]->decUserRef();
157     }
158     delete[] subElems;
159     delete[] subElemNames;
160     delete[] subElemNamesLengths;
161     delete[] arraySizes;
162 
163     return (Element *)elem;
164 }
165 
compute()166 void Element::compute() {
167     mHal.state.dataType = mComponent.getType();
168     mHal.state.dataKind = mComponent.getKind();
169     mHal.state.vectorSize = mComponent.getVectorSize();
170 
171     if (mFieldCount == 0) {
172         mBits = mComponent.getBits();
173         mBitsUnpadded = mComponent.getBitsUnpadded();
174         mHasReference = mComponent.isReference();
175 
176         mHal.state.elementSizeBytes = getSizeBytes();
177         return;
178     }
179 
180     uint32_t noPaddingFieldCount = 0;
181     for (uint32_t ct = 0; ct < mFieldCount; ct ++) {
182         if (mFields[ct].name.string()[0] != '#') {
183             noPaddingFieldCount ++;
184         }
185     }
186 
187     mHal.state.fields = new const Element*[noPaddingFieldCount];
188     mHal.state.fieldArraySizes = new uint32_t[noPaddingFieldCount];
189     mHal.state.fieldNames = new const char*[noPaddingFieldCount];
190     mHal.state.fieldNameLengths = new uint32_t[noPaddingFieldCount];
191     mHal.state.fieldOffsetBytes = new uint32_t[noPaddingFieldCount];
192     mHal.state.fieldsCount = noPaddingFieldCount;
193 
194     size_t bits = 0;
195     size_t bitsUnpadded = 0;
196     for (size_t ct = 0, ctNoPadding = 0; ct < mFieldCount; ct++) {
197         mFields[ct].offsetBits = bits;
198         mFields[ct].offsetBitsUnpadded = bitsUnpadded;
199         bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize;
200         bitsUnpadded += mFields[ct].e->getSizeBitsUnpadded() * mFields[ct].arraySize;
201 
202         if (mFields[ct].e->mHasReference) {
203             mHasReference = true;
204         }
205 
206         if (mFields[ct].name.string()[0] == '#') {
207             continue;
208         }
209 
210         mHal.state.fields[ctNoPadding] = mFields[ct].e.get();
211         mHal.state.fieldArraySizes[ctNoPadding] = mFields[ct].arraySize;
212         mHal.state.fieldNames[ctNoPadding] = mFields[ct].name.string();
213         mHal.state.fieldNameLengths[ctNoPadding] = mFields[ct].name.length() + 1; // to include 0
214         mHal.state.fieldOffsetBytes[ctNoPadding] = mFields[ct].offsetBits >> 3;
215 
216         ctNoPadding ++;
217     }
218 
219     mHal.state.elementSizeBytes = getSizeBytes();
220 }
221 
createRef(Context * rsc,RsDataType dt,RsDataKind dk,bool isNorm,uint32_t vecSize)222 ObjectBaseRef<const Element> Element::createRef(Context *rsc, RsDataType dt, RsDataKind dk,
223                                 bool isNorm, uint32_t vecSize) {
224     ObjectBaseRef<const Element> returnRef;
225     // Look for an existing match.
226     ObjectBase::asyncLock();
227     for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
228         const Element *ee = rsc->mStateElement.mElements[ct];
229         if (!ee->getFieldCount() &&
230             (ee->getComponent().getType() == dt) &&
231             (ee->getComponent().getKind() == dk) &&
232             (ee->getComponent().getIsNormalized() == isNorm) &&
233             (ee->getComponent().getVectorSize() == vecSize)) {
234             // Match
235             returnRef.set(ee);
236             ObjectBase::asyncUnlock();
237             return ee;
238         }
239     }
240     ObjectBase::asyncUnlock();
241 
242     Element *e = new Element(rsc);
243     returnRef.set(e);
244     e->mComponent.set(dt, dk, isNorm, vecSize);
245     e->compute();
246 
247     ObjectBase::asyncLock();
248     rsc->mStateElement.mElements.push(e);
249     ObjectBase::asyncUnlock();
250 
251     return returnRef;
252 }
253 
createRef(Context * rsc,size_t count,const Element ** ein,const char ** nin,const size_t * lengths,const uint32_t * asin)254 ObjectBaseRef<const Element> Element::createRef(Context *rsc, size_t count, const Element **ein,
255                             const char **nin, const size_t * lengths, const uint32_t *asin) {
256 
257     ObjectBaseRef<const Element> returnRef;
258     // Look for an existing match.
259     ObjectBase::asyncLock();
260     for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
261         const Element *ee = rsc->mStateElement.mElements[ct];
262         if (ee->getFieldCount() == count) {
263             bool match = true;
264             for (uint32_t i=0; i < count; i++) {
265                 if ((ee->mFields[i].e.get() != ein[i]) ||
266                     (ee->mFields[i].name.length() != lengths[i]) ||
267                     (ee->mFields[i].name != nin[i]) ||
268                     (ee->mFields[i].arraySize != asin[i])) {
269                     match = false;
270                     break;
271                 }
272             }
273             if (match) {
274                 returnRef.set(ee);
275                 ObjectBase::asyncUnlock();
276                 return returnRef;
277             }
278         }
279     }
280     ObjectBase::asyncUnlock();
281 
282     Element *e = new Element(rsc);
283     returnRef.set(e);
284     e->mFields = new ElementField_t [count];
285     e->mFieldCount = count;
286     for (size_t ct=0; ct < count; ct++) {
287         e->mFields[ct].e.set(ein[ct]);
288         e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
289         e->mFields[ct].arraySize = asin[ct];
290     }
291     e->compute();
292 
293     ObjectBase::asyncLock();
294     rsc->mStateElement.mElements.push(e);
295     ObjectBase::asyncUnlock();
296 
297     return returnRef;
298 }
299 
incRefs(const void * ptr) const300 void Element::incRefs(const void *ptr) const {
301     if (!mFieldCount) {
302         if (mComponent.isReference()) {
303             ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
304             ObjectBase *ob = obp[0];
305             if (ob) ob->incSysRef();
306         }
307         return;
308     }
309 
310     const uint8_t *p = static_cast<const uint8_t *>(ptr);
311     for (uint32_t i=0; i < mFieldCount; i++) {
312         if (mFields[i].e->mHasReference) {
313             const uint8_t *p2 = &p[mFields[i].offsetBits >> 3];
314             for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
315                 mFields[i].e->incRefs(p2);
316                 p2 += mFields[i].e->getSizeBytes();
317             }
318         }
319     }
320 }
321 
decRefs(const void * ptr) const322 void Element::decRefs(const void *ptr) const {
323     if (!mFieldCount) {
324         if (mComponent.isReference()) {
325             ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
326             ObjectBase *ob = obp[0];
327             if (ob) ob->decSysRef();
328         }
329         return;
330     }
331 
332     const uint8_t *p = static_cast<const uint8_t *>(ptr);
333     for (uint32_t i=0; i < mFieldCount; i++) {
334         if (mFields[i].e->mHasReference) {
335             const uint8_t *p2 = &p[mFields[i].offsetBits >> 3];
336             for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
337                 mFields[i].e->decRefs(p2);
338                 p2 += mFields[i].e->getSizeBytes();
339             }
340         }
341     }
342 }
343 
Builder()344 Element::Builder::Builder() {
345     const uint32_t initialCapacity = 32;
346     mBuilderElementRefs.setCapacity(initialCapacity);
347     mBuilderElements.setCapacity(initialCapacity);
348     mBuilderNameStrings.setCapacity(initialCapacity);
349     mBuilderNameLengths.setCapacity(initialCapacity);
350     mBuilderArrays.setCapacity(initialCapacity);
351 }
352 
add(const Element * e,const char * nameStr,uint32_t arraySize)353 void Element::Builder::add(const Element *e, const char *nameStr, uint32_t arraySize) {
354     mBuilderElementRefs.push(ObjectBaseRef<const Element>(e));
355     mBuilderElements.push(e);
356     mBuilderNameStrings.push(nameStr);
357     mBuilderNameLengths.push(strlen(nameStr));
358     mBuilderArrays.push(arraySize);
359 
360 }
361 
create(Context * rsc)362 ObjectBaseRef<const Element> Element::Builder::create(Context *rsc) {
363     return Element::createRef(rsc, mBuilderElements.size(),
364                               &(mBuilderElements.editArray()[0]),
365                               &(mBuilderNameStrings.editArray()[0]),
366                               mBuilderNameLengths.editArray(),
367                               mBuilderArrays.editArray());
368 }
369 
370 
ElementState()371 ElementState::ElementState() {
372 }
373 
~ElementState()374 ElementState::~ElementState() {
375     rsAssert(!mElements.size());
376 }
377 
378 /////////////////////////////////////////
379 //
380 
381 namespace android {
382 namespace renderscript {
383 
rsi_ElementCreate(Context * rsc,RsDataType dt,RsDataKind dk,bool norm,uint32_t vecSize)384 RsElement rsi_ElementCreate(Context *rsc,
385                             RsDataType dt,
386                             RsDataKind dk,
387                             bool norm,
388                             uint32_t vecSize) {
389     return (RsElement)Element::create(rsc, dt, dk, norm, vecSize);
390 }
391 
392 
rsi_ElementCreate2(Context * rsc,const RsElement * ein,size_t ein_length,const char ** names,size_t nameLengths_length,const size_t * nameLengths,const uint32_t * arraySizes,size_t arraySizes_length)393 RsElement rsi_ElementCreate2(Context *rsc,
394                              const RsElement * ein,
395                              size_t ein_length,
396 
397                              const char ** names,
398                              size_t nameLengths_length,
399                              const size_t * nameLengths,
400 
401                              const uint32_t * arraySizes,
402                              size_t arraySizes_length) {
403     return (RsElement)Element::create(rsc, ein_length, (const Element **)ein,
404                                       names, nameLengths, arraySizes);
405 }
406 
407 }
408 }
409 
rsaElementGetNativeData(RsContext con,RsElement elem,uint32_t * elemData,uint32_t elemDataSize)410 void rsaElementGetNativeData(RsContext con, RsElement elem,
411                              uint32_t *elemData, uint32_t elemDataSize) {
412     rsAssert(elemDataSize == 5);
413     // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
414     Element *e = static_cast<Element *>(elem);
415 
416     (*elemData++) = (uint32_t)e->getType();
417     (*elemData++) = (uint32_t)e->getKind();
418     (*elemData++) = e->getComponent().getIsNormalized() ? 1 : 0;
419     (*elemData++) = e->getComponent().getVectorSize();
420     (*elemData++) = e->getFieldCount();
421 }
422 
rsaElementGetSubElements(RsContext con,RsElement elem,uint32_t * ids,const char ** names,uint32_t * arraySizes,uint32_t dataSize)423 void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids,
424                               const char **names, uint32_t *arraySizes, uint32_t dataSize) {
425     Element *e = static_cast<Element *>(elem);
426     rsAssert(e->getFieldCount() == dataSize);
427 
428     for (uint32_t i = 0; i < dataSize; i ++) {
429         e->getField(i)->incUserRef();
430         ids[i] = (uint32_t)e->getField(i);
431         names[i] = e->getFieldName(i);
432         arraySizes[i] = e->getFieldArraySize(i);
433     }
434 }
435