• 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     if (mFields) {
48         for (size_t i = 0; i < mFieldCount; i++) {
49             delete[] mFields[i].name;
50         }
51         delete [] mFields;
52     }
53     mFields = NULL;
54     mFieldCount = 0;
55     mHasReference = false;
56 
57     delete [] mHal.state.fields;
58     delete [] mHal.state.fieldArraySizes;
59     delete [] mHal.state.fieldNames;
60     delete [] mHal.state.fieldNameLengths;
61     delete [] mHal.state.fieldOffsetBytes;
62 }
63 
getSizeBits() const64 size_t Element::getSizeBits() const {
65     if (!mFieldCount) {
66         return mBits;
67     }
68 
69     size_t total = 0;
70     for (size_t ct=0; ct < mFieldCount; ct++) {
71         total += mFields[ct].e->mBits * mFields[ct].arraySize;
72     }
73     return total;
74 }
75 
getSizeBitsUnpadded() const76 size_t Element::getSizeBitsUnpadded() const {
77     if (!mFieldCount) {
78         return mBitsUnpadded;
79     }
80 
81     size_t total = 0;
82     for (size_t ct=0; ct < mFieldCount; ct++) {
83         total += mFields[ct].e->mBitsUnpadded * mFields[ct].arraySize;
84     }
85     return total;
86 }
87 
dumpLOGV(const char * prefix) const88 void Element::dumpLOGV(const char *prefix) const {
89     ObjectBase::dumpLOGV(prefix);
90     ALOGV("%s Element: fieldCount: %zu,  size bytes: %zu", prefix, mFieldCount, getSizeBytes());
91     mComponent.dumpLOGV(prefix);
92     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
93         ALOGV("%s Element field index: %u ------------------", prefix, ct);
94         ALOGV("%s name: %s, offsetBits: %u, arraySize: %u",
95              prefix, mFields[ct].name, mFields[ct].offsetBits, mFields[ct].arraySize);
96         mFields[ct].e->dumpLOGV(prefix);
97     }
98 }
99 
serialize(Context * rsc,OStream * stream) const100 void Element::serialize(Context *rsc, OStream *stream) const {
101     // Need to identify ourselves
102     stream->addU32((uint32_t)getClassId());
103     stream->addString(getName());
104 
105     mComponent.serialize(stream);
106 
107     // Now serialize all the fields
108     stream->addU32(mFieldCount);
109     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
110         stream->addString(mFields[ct].name);
111         stream->addU32(mFields[ct].arraySize);
112         mFields[ct].e->serialize(rsc, stream);
113     }
114 }
115 
createFromStream(Context * rsc,IStream * stream)116 Element *Element::createFromStream(Context *rsc, IStream *stream) {
117     // First make sure we are reading the correct object
118     RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
119     if (classID != RS_A3D_CLASS_ID_ELEMENT) {
120         ALOGE("element loading skipped due to invalid class id\n");
121         return NULL;
122     }
123 
124     const char *name = stream->loadString();
125 
126     Component component;
127     component.loadFromStream(stream);
128 
129     uint32_t fieldCount = stream->loadU32();
130     if (!fieldCount) {
131         return (Element *)Element::create(rsc,
132                                           component.getType(),
133                                           component.getKind(),
134                                           component.getIsNormalized(),
135                                           component.getVectorSize());
136     }
137 
138     const Element **subElems = new const Element *[fieldCount];
139     const char **subElemNames = new const char *[fieldCount];
140     size_t *subElemNamesLengths = new size_t[fieldCount];
141     uint32_t *arraySizes = new uint32_t[fieldCount];
142 
143     for (uint32_t ct = 0; ct < fieldCount; ct ++) {
144         subElemNames[ct] = stream->loadString();
145         subElemNamesLengths[ct] = strlen(subElemNames[ct]);
146         arraySizes[ct] = stream->loadU32();
147         subElems[ct] = Element::createFromStream(rsc, stream);
148     }
149 
150     const Element *elem = Element::create(rsc, fieldCount, subElems, subElemNames,
151                                           subElemNamesLengths, arraySizes);
152     for (uint32_t ct = 0; ct < fieldCount; ct ++) {
153         delete [] subElemNames[ct];
154         subElems[ct]->decUserRef();
155     }
156     delete[] name;
157     delete[] subElems;
158     delete[] subElemNames;
159     delete[] subElemNamesLengths;
160     delete[] arraySizes;
161 
162     return (Element *)elem;
163 }
164 
compute()165 void 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 
createRef(Context * rsc,RsDataType dt,RsDataKind dk,bool isNorm,uint32_t vecSize)221 ObjectBaseRef<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 *e = new Element(rsc);
242     returnRef.set(e);
243     e->mComponent.set(dt, dk, isNorm, vecSize);
244     e->compute();
245 
246     ObjectBase::asyncLock();
247     rsc->mStateElement.mElements.push(e);
248     ObjectBase::asyncUnlock();
249 
250     return returnRef;
251 }
252 
createRef(Context * rsc,size_t count,const Element ** ein,const char ** nin,const size_t * lengths,const uint32_t * asin)253 ObjectBaseRef<const Element> Element::createRef(Context *rsc, size_t count, const Element **ein,
254                             const char **nin, const size_t * lengths, const uint32_t *asin) {
255 
256     ObjectBaseRef<const Element> returnRef;
257     // Look for an existing match.
258     ObjectBase::asyncLock();
259     for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
260         const Element *ee = rsc->mStateElement.mElements[ct];
261         if (ee->getFieldCount() == count) {
262             bool match = true;
263             for (uint32_t i=0; i < count; i++) {
264                 size_t len;
265                 uint32_t asize = 1;
266                 if (lengths) {
267                     len = lengths[i];
268                 } else {
269                     len = strlen(nin[i]);
270                 }
271                 if (asin) {
272                     asize = asin[i];
273                 }
274 
275                 if ((ee->mFields[i].e.get() != ein[i]) ||
276                     (strlen(ee->mFields[i].name) != len) ||
277                     strcmp(ee->mFields[i].name, nin[i]) ||
278                     (ee->mFields[i].arraySize != asize)) {
279                     match = false;
280                     break;
281                 }
282             }
283             if (match) {
284                 returnRef.set(ee);
285                 ObjectBase::asyncUnlock();
286                 return returnRef;
287             }
288         }
289     }
290     ObjectBase::asyncUnlock();
291 
292     Element *e = new Element(rsc);
293     returnRef.set(e);
294     e->mFields = new ElementField_t [count];
295     e->mFieldCount = count;
296     for (size_t ct=0; ct < count; ct++) {
297         size_t len;
298         uint32_t asize = 1;
299         if (lengths) {
300             len = lengths[ct];
301         } else {
302             len = strlen(nin[ct]);
303         }
304         if (asin) {
305             asize = asin[ct];
306         }
307 
308         e->mFields[ct].e.set(ein[ct]);
309         e->mFields[ct].name = rsuCopyString(nin[ct], len);
310         e->mFields[ct].arraySize = asize;
311     }
312     e->compute();
313 
314     ObjectBase::asyncLock();
315     rsc->mStateElement.mElements.push(e);
316     ObjectBase::asyncUnlock();
317 
318     return returnRef;
319 }
320 
incRefs(const void * ptr) const321 void Element::incRefs(const void *ptr) const {
322     if (!mFieldCount) {
323         if (mComponent.isReference()) {
324             ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
325             ObjectBase *ob = obp[0];
326             if (ob) ob->incSysRef();
327         }
328         return;
329     }
330 
331     const uint8_t *p = static_cast<const uint8_t *>(ptr);
332     for (uint32_t i=0; i < mFieldCount; i++) {
333         if (mFields[i].e->mHasReference) {
334             const uint8_t *p2 = &p[mFields[i].offsetBits >> 3];
335             for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
336                 mFields[i].e->incRefs(p2);
337                 p2 += mFields[i].e->getSizeBytes();
338             }
339         }
340     }
341 }
342 
decRefs(const void * ptr) const343 void Element::decRefs(const void *ptr) const {
344     if (!mFieldCount) {
345         if (mComponent.isReference()) {
346             ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
347             ObjectBase *ob = obp[0];
348             if (ob) ob->decSysRef();
349         }
350         return;
351     }
352 
353     const uint8_t *p = static_cast<const uint8_t *>(ptr);
354     for (uint32_t i=0; i < mFieldCount; i++) {
355         if (mFields[i].e->mHasReference) {
356             const uint8_t *p2 = &p[mFields[i].offsetBits >> 3];
357             for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
358                 mFields[i].e->decRefs(p2);
359                 p2 += mFields[i].e->getSizeBytes();
360             }
361         }
362     }
363 }
364 
ElementState()365 ElementState::ElementState() {
366 }
367 
~ElementState()368 ElementState::~ElementState() {
369     rsAssert(!mElements.size());
370 }
371 
372 /////////////////////////////////////////
373 //
374 
375 namespace android {
376 namespace renderscript {
377 
rsi_ElementCreate(Context * rsc,RsDataType dt,RsDataKind dk,bool norm,uint32_t vecSize)378 RsElement rsi_ElementCreate(Context *rsc,
379                             RsDataType dt,
380                             RsDataKind dk,
381                             bool norm,
382                             uint32_t vecSize) {
383     return (RsElement)Element::create(rsc, dt, dk, norm, vecSize);
384 }
385 
386 
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)387 RsElement rsi_ElementCreate2(Context *rsc,
388                              const RsElement * ein,
389                              size_t ein_length,
390 
391                              const char ** names,
392                              size_t nameLengths_length,
393                              const size_t * nameLengths,
394 
395                              const uint32_t * arraySizes,
396                              size_t arraySizes_length) {
397     return (RsElement)Element::create(rsc, ein_length, (const Element **)ein,
398                                       names, nameLengths, arraySizes);
399 }
400 
401 }
402 }
403 
rsaElementGetNativeData(RsContext con,RsElement elem,uint32_t * elemData,uint32_t elemDataSize)404 extern "C" void rsaElementGetNativeData(RsContext con, RsElement elem,
405                              uint32_t *elemData, uint32_t elemDataSize) {
406     rsAssert(elemDataSize == 5);
407     // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
408     Element *e = static_cast<Element *>(elem);
409 
410     (*elemData++) = (uint32_t)e->getType();
411     (*elemData++) = (uint32_t)e->getKind();
412     (*elemData++) = e->getComponent().getIsNormalized() ? 1 : 0;
413     (*elemData++) = e->getComponent().getVectorSize();
414     (*elemData++) = e->getFieldCount();
415 }
416 
rsaElementGetSubElements(RsContext con,RsElement elem,uintptr_t * ids,const char ** names,size_t * arraySizes,uint32_t dataSize)417 extern "C" void rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids,
418                               const char **names, size_t *arraySizes, uint32_t dataSize) {
419     Element *e = static_cast<Element *>(elem);
420     rsAssert(e->getFieldCount() == dataSize);
421 
422     for (uint32_t i = 0; i < dataSize; i ++) {
423         e->getField(i)->incUserRef();
424         ids[i] = (uintptr_t)e->getField(i);
425         names[i] = e->getFieldName(i);
426         arraySizes[i] = e->getFieldArraySize(i);
427     }
428 }
429