xref: /aosp_15_r20/frameworks/rs/rsElement.cpp (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
1*e1eccf28SAndroid Build Coastguard Worker /*
2*e1eccf28SAndroid Build Coastguard Worker  * Copyright (C) 2009 The Android Open Source Project
3*e1eccf28SAndroid Build Coastguard Worker  *
4*e1eccf28SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e1eccf28SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e1eccf28SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e1eccf28SAndroid Build Coastguard Worker  *
8*e1eccf28SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*e1eccf28SAndroid Build Coastguard Worker  *
10*e1eccf28SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e1eccf28SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e1eccf28SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1eccf28SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e1eccf28SAndroid Build Coastguard Worker  * limitations under the License.
15*e1eccf28SAndroid Build Coastguard Worker  */
16*e1eccf28SAndroid Build Coastguard Worker 
17*e1eccf28SAndroid Build Coastguard Worker 
18*e1eccf28SAndroid Build Coastguard Worker #include "rsContext.h"
19*e1eccf28SAndroid Build Coastguard Worker 
20*e1eccf28SAndroid Build Coastguard Worker namespace android {
21*e1eccf28SAndroid Build Coastguard Worker namespace renderscript {
22*e1eccf28SAndroid Build Coastguard Worker 
Element(Context * rsc)23*e1eccf28SAndroid Build Coastguard Worker Element::Element(Context *rsc) : ObjectBase(rsc) {
24*e1eccf28SAndroid Build Coastguard Worker     mBits = 0;
25*e1eccf28SAndroid Build Coastguard Worker     mBitsUnpadded = 0;
26*e1eccf28SAndroid Build Coastguard Worker     mFields = nullptr;
27*e1eccf28SAndroid Build Coastguard Worker     mFieldCount = 0;
28*e1eccf28SAndroid Build Coastguard Worker     mHasReference = false;
29*e1eccf28SAndroid Build Coastguard Worker     memset(&mHal, 0, sizeof(mHal));
30*e1eccf28SAndroid Build Coastguard Worker }
31*e1eccf28SAndroid Build Coastguard Worker 
~Element()32*e1eccf28SAndroid Build Coastguard Worker Element::~Element() {
33*e1eccf28SAndroid Build Coastguard Worker     clear();
34*e1eccf28SAndroid Build Coastguard Worker }
35*e1eccf28SAndroid Build Coastguard Worker 
operator delete(void * ptr)36*e1eccf28SAndroid Build Coastguard Worker void Element::operator delete(void* ptr) {
37*e1eccf28SAndroid Build Coastguard Worker     if (ptr) {
38*e1eccf28SAndroid Build Coastguard Worker         Element *e = (Element*) ptr;
39*e1eccf28SAndroid Build Coastguard Worker         e->getContext()->mHal.funcs.freeRuntimeMem(ptr);
40*e1eccf28SAndroid Build Coastguard Worker     }
41*e1eccf28SAndroid Build Coastguard Worker }
42*e1eccf28SAndroid Build Coastguard Worker 
preDestroy() const43*e1eccf28SAndroid Build Coastguard Worker void Element::preDestroy() const {
44*e1eccf28SAndroid Build Coastguard Worker     auto& elements = mRSC->mStateElement.mElements;
45*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct = 0; ct < elements.size(); ct++) {
46*e1eccf28SAndroid Build Coastguard Worker         if (elements[ct] == this) {
47*e1eccf28SAndroid Build Coastguard Worker             elements.erase(elements.begin() + ct);
48*e1eccf28SAndroid Build Coastguard Worker             break;
49*e1eccf28SAndroid Build Coastguard Worker         }
50*e1eccf28SAndroid Build Coastguard Worker     }
51*e1eccf28SAndroid Build Coastguard Worker }
52*e1eccf28SAndroid Build Coastguard Worker 
clear()53*e1eccf28SAndroid Build Coastguard Worker void Element::clear() {
54*e1eccf28SAndroid Build Coastguard Worker     if (mFields) {
55*e1eccf28SAndroid Build Coastguard Worker         for (size_t i = 0; i < mFieldCount; i++) {
56*e1eccf28SAndroid Build Coastguard Worker             delete[] mFields[i].name;
57*e1eccf28SAndroid Build Coastguard Worker         }
58*e1eccf28SAndroid Build Coastguard Worker         delete [] mFields;
59*e1eccf28SAndroid Build Coastguard Worker     }
60*e1eccf28SAndroid Build Coastguard Worker     mFields = nullptr;
61*e1eccf28SAndroid Build Coastguard Worker     mFieldCount = 0;
62*e1eccf28SAndroid Build Coastguard Worker     mHasReference = false;
63*e1eccf28SAndroid Build Coastguard Worker 
64*e1eccf28SAndroid Build Coastguard Worker     delete [] mHal.state.fields;
65*e1eccf28SAndroid Build Coastguard Worker     delete [] mHal.state.fieldArraySizes;
66*e1eccf28SAndroid Build Coastguard Worker     delete [] mHal.state.fieldNames;
67*e1eccf28SAndroid Build Coastguard Worker     delete [] mHal.state.fieldNameLengths;
68*e1eccf28SAndroid Build Coastguard Worker     delete [] mHal.state.fieldOffsetBytes;
69*e1eccf28SAndroid Build Coastguard Worker }
70*e1eccf28SAndroid Build Coastguard Worker 
getSizeBits() const71*e1eccf28SAndroid Build Coastguard Worker size_t Element::getSizeBits() const {
72*e1eccf28SAndroid Build Coastguard Worker     if (!mFieldCount) {
73*e1eccf28SAndroid Build Coastguard Worker         return mBits;
74*e1eccf28SAndroid Build Coastguard Worker     }
75*e1eccf28SAndroid Build Coastguard Worker 
76*e1eccf28SAndroid Build Coastguard Worker     size_t total = 0;
77*e1eccf28SAndroid Build Coastguard Worker     for (size_t ct=0; ct < mFieldCount; ct++) {
78*e1eccf28SAndroid Build Coastguard Worker         total += mFields[ct].e->mBits * mFields[ct].arraySize;
79*e1eccf28SAndroid Build Coastguard Worker     }
80*e1eccf28SAndroid Build Coastguard Worker     return total;
81*e1eccf28SAndroid Build Coastguard Worker }
82*e1eccf28SAndroid Build Coastguard Worker 
getSizeBitsUnpadded() const83*e1eccf28SAndroid Build Coastguard Worker size_t Element::getSizeBitsUnpadded() const {
84*e1eccf28SAndroid Build Coastguard Worker     if (!mFieldCount) {
85*e1eccf28SAndroid Build Coastguard Worker         return mBitsUnpadded;
86*e1eccf28SAndroid Build Coastguard Worker     }
87*e1eccf28SAndroid Build Coastguard Worker 
88*e1eccf28SAndroid Build Coastguard Worker     size_t total = 0;
89*e1eccf28SAndroid Build Coastguard Worker     for (size_t ct=0; ct < mFieldCount; ct++) {
90*e1eccf28SAndroid Build Coastguard Worker         total += mFields[ct].e->mBitsUnpadded * mFields[ct].arraySize;
91*e1eccf28SAndroid Build Coastguard Worker     }
92*e1eccf28SAndroid Build Coastguard Worker     return total;
93*e1eccf28SAndroid Build Coastguard Worker }
94*e1eccf28SAndroid Build Coastguard Worker 
dumpLOGV(const char * prefix) const95*e1eccf28SAndroid Build Coastguard Worker void Element::dumpLOGV(const char *prefix) const {
96*e1eccf28SAndroid Build Coastguard Worker     ObjectBase::dumpLOGV(prefix);
97*e1eccf28SAndroid Build Coastguard Worker     ALOGV("%s Element: fieldCount: %zu,  size bytes: %zu", prefix, mFieldCount, getSizeBytes());
98*e1eccf28SAndroid Build Coastguard Worker     mComponent.dumpLOGV(prefix);
99*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
100*e1eccf28SAndroid Build Coastguard Worker         ALOGV("%s Element field index: %u ------------------", prefix, ct);
101*e1eccf28SAndroid Build Coastguard Worker         ALOGV("%s name: %s, offsetBits: %u, arraySize: %u",
102*e1eccf28SAndroid Build Coastguard Worker              prefix, mFields[ct].name, mFields[ct].offsetBits, mFields[ct].arraySize);
103*e1eccf28SAndroid Build Coastguard Worker         mFields[ct].e->dumpLOGV(prefix);
104*e1eccf28SAndroid Build Coastguard Worker     }
105*e1eccf28SAndroid Build Coastguard Worker }
106*e1eccf28SAndroid Build Coastguard Worker 
serialize(Context * rsc,OStream * stream) const107*e1eccf28SAndroid Build Coastguard Worker void Element::serialize(Context *rsc, OStream *stream) const {
108*e1eccf28SAndroid Build Coastguard Worker     // Need to identify ourselves
109*e1eccf28SAndroid Build Coastguard Worker     stream->addU32((uint32_t)getClassId());
110*e1eccf28SAndroid Build Coastguard Worker     stream->addString(getName());
111*e1eccf28SAndroid Build Coastguard Worker 
112*e1eccf28SAndroid Build Coastguard Worker     mComponent.serialize(stream);
113*e1eccf28SAndroid Build Coastguard Worker 
114*e1eccf28SAndroid Build Coastguard Worker     // Now serialize all the fields
115*e1eccf28SAndroid Build Coastguard Worker     stream->addU32(mFieldCount);
116*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
117*e1eccf28SAndroid Build Coastguard Worker         stream->addString(mFields[ct].name);
118*e1eccf28SAndroid Build Coastguard Worker         stream->addU32(mFields[ct].arraySize);
119*e1eccf28SAndroid Build Coastguard Worker         mFields[ct].e->serialize(rsc, stream);
120*e1eccf28SAndroid Build Coastguard Worker     }
121*e1eccf28SAndroid Build Coastguard Worker }
122*e1eccf28SAndroid Build Coastguard Worker 
createFromStream(Context * rsc,IStream * stream)123*e1eccf28SAndroid Build Coastguard Worker Element *Element::createFromStream(Context *rsc, IStream *stream) {
124*e1eccf28SAndroid Build Coastguard Worker     // First make sure we are reading the correct object
125*e1eccf28SAndroid Build Coastguard Worker     RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
126*e1eccf28SAndroid Build Coastguard Worker     if (classID != RS_A3D_CLASS_ID_ELEMENT) {
127*e1eccf28SAndroid Build Coastguard Worker         ALOGE("element loading skipped due to invalid class id\n");
128*e1eccf28SAndroid Build Coastguard Worker         return nullptr;
129*e1eccf28SAndroid Build Coastguard Worker     }
130*e1eccf28SAndroid Build Coastguard Worker 
131*e1eccf28SAndroid Build Coastguard Worker     const char *name = stream->loadString();
132*e1eccf28SAndroid Build Coastguard Worker 
133*e1eccf28SAndroid Build Coastguard Worker     Component component;
134*e1eccf28SAndroid Build Coastguard Worker     component.loadFromStream(stream);
135*e1eccf28SAndroid Build Coastguard Worker 
136*e1eccf28SAndroid Build Coastguard Worker     uint32_t fieldCount = stream->loadU32();
137*e1eccf28SAndroid Build Coastguard Worker     if (!fieldCount) {
138*e1eccf28SAndroid Build Coastguard Worker         return (Element *)Element::create(rsc,
139*e1eccf28SAndroid Build Coastguard Worker                                           component.getType(),
140*e1eccf28SAndroid Build Coastguard Worker                                           component.getKind(),
141*e1eccf28SAndroid Build Coastguard Worker                                           component.getIsNormalized(),
142*e1eccf28SAndroid Build Coastguard Worker                                           component.getVectorSize());
143*e1eccf28SAndroid Build Coastguard Worker     }
144*e1eccf28SAndroid Build Coastguard Worker 
145*e1eccf28SAndroid Build Coastguard Worker     const Element **subElems = new const Element *[fieldCount];
146*e1eccf28SAndroid Build Coastguard Worker     const char **subElemNames = new const char *[fieldCount];
147*e1eccf28SAndroid Build Coastguard Worker     size_t *subElemNamesLengths = new size_t[fieldCount];
148*e1eccf28SAndroid Build Coastguard Worker     uint32_t *arraySizes = new uint32_t[fieldCount];
149*e1eccf28SAndroid Build Coastguard Worker 
150*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct = 0; ct < fieldCount; ct ++) {
151*e1eccf28SAndroid Build Coastguard Worker         subElemNames[ct] = stream->loadString();
152*e1eccf28SAndroid Build Coastguard Worker         subElemNamesLengths[ct] = strlen(subElemNames[ct]);
153*e1eccf28SAndroid Build Coastguard Worker         arraySizes[ct] = stream->loadU32();
154*e1eccf28SAndroid Build Coastguard Worker         subElems[ct] = Element::createFromStream(rsc, stream);
155*e1eccf28SAndroid Build Coastguard Worker     }
156*e1eccf28SAndroid Build Coastguard Worker 
157*e1eccf28SAndroid Build Coastguard Worker     const Element *elem = Element::create(rsc, fieldCount, subElems, subElemNames,
158*e1eccf28SAndroid Build Coastguard Worker                                           subElemNamesLengths, arraySizes);
159*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct = 0; ct < fieldCount; ct ++) {
160*e1eccf28SAndroid Build Coastguard Worker         delete [] subElemNames[ct];
161*e1eccf28SAndroid Build Coastguard Worker         subElems[ct]->decUserRef();
162*e1eccf28SAndroid Build Coastguard Worker     }
163*e1eccf28SAndroid Build Coastguard Worker     delete[] name;
164*e1eccf28SAndroid Build Coastguard Worker     delete[] subElems;
165*e1eccf28SAndroid Build Coastguard Worker     delete[] subElemNames;
166*e1eccf28SAndroid Build Coastguard Worker     delete[] subElemNamesLengths;
167*e1eccf28SAndroid Build Coastguard Worker     delete[] arraySizes;
168*e1eccf28SAndroid Build Coastguard Worker 
169*e1eccf28SAndroid Build Coastguard Worker     return (Element *)elem;
170*e1eccf28SAndroid Build Coastguard Worker }
171*e1eccf28SAndroid Build Coastguard Worker 
compute()172*e1eccf28SAndroid Build Coastguard Worker void Element::compute() {
173*e1eccf28SAndroid Build Coastguard Worker     mHal.state.dataType = mComponent.getType();
174*e1eccf28SAndroid Build Coastguard Worker     mHal.state.dataKind = mComponent.getKind();
175*e1eccf28SAndroid Build Coastguard Worker     mHal.state.vectorSize = mComponent.getVectorSize();
176*e1eccf28SAndroid Build Coastguard Worker 
177*e1eccf28SAndroid Build Coastguard Worker     if (mFieldCount == 0) {
178*e1eccf28SAndroid Build Coastguard Worker         mBits = mComponent.getBits();
179*e1eccf28SAndroid Build Coastguard Worker         mBitsUnpadded = mComponent.getBitsUnpadded();
180*e1eccf28SAndroid Build Coastguard Worker         mHasReference = mComponent.isReference();
181*e1eccf28SAndroid Build Coastguard Worker 
182*e1eccf28SAndroid Build Coastguard Worker         mHal.state.elementSizeBytes = getSizeBytes();
183*e1eccf28SAndroid Build Coastguard Worker         return;
184*e1eccf28SAndroid Build Coastguard Worker     }
185*e1eccf28SAndroid Build Coastguard Worker 
186*e1eccf28SAndroid Build Coastguard Worker     uint32_t noPaddingFieldCount = 0;
187*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct = 0; ct < mFieldCount; ct ++) {
188*e1eccf28SAndroid Build Coastguard Worker         if (mFields[ct].name[0] != '#') {
189*e1eccf28SAndroid Build Coastguard Worker             noPaddingFieldCount ++;
190*e1eccf28SAndroid Build Coastguard Worker         }
191*e1eccf28SAndroid Build Coastguard Worker     }
192*e1eccf28SAndroid Build Coastguard Worker 
193*e1eccf28SAndroid Build Coastguard Worker     mHal.state.fields = new const Element*[noPaddingFieldCount];
194*e1eccf28SAndroid Build Coastguard Worker     mHal.state.fieldArraySizes = new uint32_t[noPaddingFieldCount];
195*e1eccf28SAndroid Build Coastguard Worker     mHal.state.fieldNames = new const char*[noPaddingFieldCount];
196*e1eccf28SAndroid Build Coastguard Worker     mHal.state.fieldNameLengths = new uint32_t[noPaddingFieldCount];
197*e1eccf28SAndroid Build Coastguard Worker     mHal.state.fieldOffsetBytes = new uint32_t[noPaddingFieldCount];
198*e1eccf28SAndroid Build Coastguard Worker     mHal.state.fieldsCount = noPaddingFieldCount;
199*e1eccf28SAndroid Build Coastguard Worker 
200*e1eccf28SAndroid Build Coastguard Worker     size_t bits = 0;
201*e1eccf28SAndroid Build Coastguard Worker     size_t bitsUnpadded = 0;
202*e1eccf28SAndroid Build Coastguard Worker     for (size_t ct = 0, ctNoPadding = 0; ct < mFieldCount; ct++) {
203*e1eccf28SAndroid Build Coastguard Worker         mFields[ct].offsetBits = bits;
204*e1eccf28SAndroid Build Coastguard Worker         mFields[ct].offsetBitsUnpadded = bitsUnpadded;
205*e1eccf28SAndroid Build Coastguard Worker         bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize;
206*e1eccf28SAndroid Build Coastguard Worker         bitsUnpadded += mFields[ct].e->getSizeBitsUnpadded() * mFields[ct].arraySize;
207*e1eccf28SAndroid Build Coastguard Worker 
208*e1eccf28SAndroid Build Coastguard Worker         if (mFields[ct].e->mHasReference) {
209*e1eccf28SAndroid Build Coastguard Worker             mHasReference = true;
210*e1eccf28SAndroid Build Coastguard Worker         }
211*e1eccf28SAndroid Build Coastguard Worker 
212*e1eccf28SAndroid Build Coastguard Worker         if (mFields[ct].name[0] == '#') {
213*e1eccf28SAndroid Build Coastguard Worker             continue;
214*e1eccf28SAndroid Build Coastguard Worker         }
215*e1eccf28SAndroid Build Coastguard Worker 
216*e1eccf28SAndroid Build Coastguard Worker         mHal.state.fields[ctNoPadding] = mFields[ct].e.get();
217*e1eccf28SAndroid Build Coastguard Worker         mHal.state.fieldArraySizes[ctNoPadding] = mFields[ct].arraySize;
218*e1eccf28SAndroid Build Coastguard Worker         mHal.state.fieldNames[ctNoPadding] = mFields[ct].name;
219*e1eccf28SAndroid Build Coastguard Worker         mHal.state.fieldNameLengths[ctNoPadding] = strlen(mFields[ct].name) + 1; // to include 0
220*e1eccf28SAndroid Build Coastguard Worker         mHal.state.fieldOffsetBytes[ctNoPadding] = mFields[ct].offsetBits >> 3;
221*e1eccf28SAndroid Build Coastguard Worker 
222*e1eccf28SAndroid Build Coastguard Worker         ctNoPadding ++;
223*e1eccf28SAndroid Build Coastguard Worker     }
224*e1eccf28SAndroid Build Coastguard Worker 
225*e1eccf28SAndroid Build Coastguard Worker     mBits = bits;
226*e1eccf28SAndroid Build Coastguard Worker     mBitsUnpadded = bitsUnpadded;
227*e1eccf28SAndroid Build Coastguard Worker     mHal.state.elementSizeBytes = getSizeBytes();
228*e1eccf28SAndroid Build Coastguard Worker }
229*e1eccf28SAndroid Build Coastguard Worker 
createRef(Context * rsc,RsDataType dt,RsDataKind dk,bool isNorm,uint32_t vecSize)230*e1eccf28SAndroid Build Coastguard Worker ObjectBaseRef<const Element> Element::createRef(Context *rsc, RsDataType dt, RsDataKind dk,
231*e1eccf28SAndroid Build Coastguard Worker                                 bool isNorm, uint32_t vecSize) {
232*e1eccf28SAndroid Build Coastguard Worker     ObjectBaseRef<const Element> returnRef;
233*e1eccf28SAndroid Build Coastguard Worker     // Look for an existing match.
234*e1eccf28SAndroid Build Coastguard Worker     ObjectBase::asyncLock();
235*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
236*e1eccf28SAndroid Build Coastguard Worker         const Element *ee = rsc->mStateElement.mElements[ct];
237*e1eccf28SAndroid Build Coastguard Worker         if (!ee->getFieldCount() &&
238*e1eccf28SAndroid Build Coastguard Worker             (ee->getComponent().getType() == dt) &&
239*e1eccf28SAndroid Build Coastguard Worker             (ee->getComponent().getKind() == dk) &&
240*e1eccf28SAndroid Build Coastguard Worker             (ee->getComponent().getIsNormalized() == isNorm) &&
241*e1eccf28SAndroid Build Coastguard Worker             (ee->getComponent().getVectorSize() == vecSize)) {
242*e1eccf28SAndroid Build Coastguard Worker             // Match
243*e1eccf28SAndroid Build Coastguard Worker             returnRef.set(ee);
244*e1eccf28SAndroid Build Coastguard Worker             ObjectBase::asyncUnlock();
245*e1eccf28SAndroid Build Coastguard Worker             return ee;
246*e1eccf28SAndroid Build Coastguard Worker         }
247*e1eccf28SAndroid Build Coastguard Worker     }
248*e1eccf28SAndroid Build Coastguard Worker     ObjectBase::asyncUnlock();
249*e1eccf28SAndroid Build Coastguard Worker 
250*e1eccf28SAndroid Build Coastguard Worker     // Element objects must use allocator specified by the driver
251*e1eccf28SAndroid Build Coastguard Worker     void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Element), 0);
252*e1eccf28SAndroid Build Coastguard Worker     if (!allocMem) {
253*e1eccf28SAndroid Build Coastguard Worker         rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Element");
254*e1eccf28SAndroid Build Coastguard Worker         return nullptr;
255*e1eccf28SAndroid Build Coastguard Worker     }
256*e1eccf28SAndroid Build Coastguard Worker 
257*e1eccf28SAndroid Build Coastguard Worker     Element *e = new (allocMem) Element(rsc);
258*e1eccf28SAndroid Build Coastguard Worker     returnRef.set(e);
259*e1eccf28SAndroid Build Coastguard Worker     e->mComponent.set(dt, dk, isNorm, vecSize);
260*e1eccf28SAndroid Build Coastguard Worker     e->compute();
261*e1eccf28SAndroid Build Coastguard Worker 
262*e1eccf28SAndroid Build Coastguard Worker #ifdef RS_FIND_OFFSETS
263*e1eccf28SAndroid Build Coastguard Worker     ALOGE("pointer for element: %p", e);
264*e1eccf28SAndroid Build Coastguard Worker     ALOGE("pointer for element.drv: %p", &e->mHal.drv);
265*e1eccf28SAndroid Build Coastguard Worker #endif
266*e1eccf28SAndroid Build Coastguard Worker 
267*e1eccf28SAndroid Build Coastguard Worker 
268*e1eccf28SAndroid Build Coastguard Worker     ObjectBase::asyncLock();
269*e1eccf28SAndroid Build Coastguard Worker     rsc->mStateElement.mElements.push_back(e);
270*e1eccf28SAndroid Build Coastguard Worker     ObjectBase::asyncUnlock();
271*e1eccf28SAndroid Build Coastguard Worker 
272*e1eccf28SAndroid Build Coastguard Worker     return returnRef;
273*e1eccf28SAndroid Build Coastguard Worker }
274*e1eccf28SAndroid Build Coastguard Worker 
createRef(Context * rsc,size_t count,const Element ** ein,const char ** nin,const size_t * lengths,const uint32_t * asin)275*e1eccf28SAndroid Build Coastguard Worker ObjectBaseRef<const Element> Element::createRef(Context *rsc, size_t count, const Element **ein,
276*e1eccf28SAndroid Build Coastguard Worker                             const char **nin, const size_t * lengths, const uint32_t *asin) {
277*e1eccf28SAndroid Build Coastguard Worker 
278*e1eccf28SAndroid Build Coastguard Worker     ObjectBaseRef<const Element> returnRef;
279*e1eccf28SAndroid Build Coastguard Worker     // Look for an existing match.
280*e1eccf28SAndroid Build Coastguard Worker     ObjectBase::asyncLock();
281*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
282*e1eccf28SAndroid Build Coastguard Worker         const Element *ee = rsc->mStateElement.mElements[ct];
283*e1eccf28SAndroid Build Coastguard Worker         if (ee->getFieldCount() == count) {
284*e1eccf28SAndroid Build Coastguard Worker             bool match = true;
285*e1eccf28SAndroid Build Coastguard Worker             for (uint32_t i=0; i < count; i++) {
286*e1eccf28SAndroid Build Coastguard Worker                 size_t len;
287*e1eccf28SAndroid Build Coastguard Worker                 uint32_t asize = 1;
288*e1eccf28SAndroid Build Coastguard Worker                 if (lengths) {
289*e1eccf28SAndroid Build Coastguard Worker                     len = lengths[i];
290*e1eccf28SAndroid Build Coastguard Worker                 } else {
291*e1eccf28SAndroid Build Coastguard Worker                     len = strlen(nin[i]);
292*e1eccf28SAndroid Build Coastguard Worker                 }
293*e1eccf28SAndroid Build Coastguard Worker                 if (asin) {
294*e1eccf28SAndroid Build Coastguard Worker                     asize = asin[i];
295*e1eccf28SAndroid Build Coastguard Worker                 }
296*e1eccf28SAndroid Build Coastguard Worker 
297*e1eccf28SAndroid Build Coastguard Worker                 if ((ee->mFields[i].e.get() != ein[i]) ||
298*e1eccf28SAndroid Build Coastguard Worker                     (strlen(ee->mFields[i].name) != len) ||
299*e1eccf28SAndroid Build Coastguard Worker                     strcmp(ee->mFields[i].name, nin[i]) ||
300*e1eccf28SAndroid Build Coastguard Worker                     (ee->mFields[i].arraySize != asize)) {
301*e1eccf28SAndroid Build Coastguard Worker                     match = false;
302*e1eccf28SAndroid Build Coastguard Worker                     break;
303*e1eccf28SAndroid Build Coastguard Worker                 }
304*e1eccf28SAndroid Build Coastguard Worker             }
305*e1eccf28SAndroid Build Coastguard Worker             if (match) {
306*e1eccf28SAndroid Build Coastguard Worker                 returnRef.set(ee);
307*e1eccf28SAndroid Build Coastguard Worker                 ObjectBase::asyncUnlock();
308*e1eccf28SAndroid Build Coastguard Worker                 return returnRef;
309*e1eccf28SAndroid Build Coastguard Worker             }
310*e1eccf28SAndroid Build Coastguard Worker         }
311*e1eccf28SAndroid Build Coastguard Worker     }
312*e1eccf28SAndroid Build Coastguard Worker     ObjectBase::asyncUnlock();
313*e1eccf28SAndroid Build Coastguard Worker 
314*e1eccf28SAndroid Build Coastguard Worker     // Element objects must use allocator specified by the driver
315*e1eccf28SAndroid Build Coastguard Worker     void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Element), 0);
316*e1eccf28SAndroid Build Coastguard Worker     if (!allocMem) {
317*e1eccf28SAndroid Build Coastguard Worker         rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Element");
318*e1eccf28SAndroid Build Coastguard Worker         return nullptr;
319*e1eccf28SAndroid Build Coastguard Worker     }
320*e1eccf28SAndroid Build Coastguard Worker 
321*e1eccf28SAndroid Build Coastguard Worker     Element *e = new (allocMem) Element(rsc);
322*e1eccf28SAndroid Build Coastguard Worker     returnRef.set(e);
323*e1eccf28SAndroid Build Coastguard Worker     e->mFields = new ElementField_t [count];
324*e1eccf28SAndroid Build Coastguard Worker     e->mFieldCount = count;
325*e1eccf28SAndroid Build Coastguard Worker     for (size_t ct=0; ct < count; ct++) {
326*e1eccf28SAndroid Build Coastguard Worker         size_t len;
327*e1eccf28SAndroid Build Coastguard Worker         uint32_t asize = 1;
328*e1eccf28SAndroid Build Coastguard Worker         if (lengths) {
329*e1eccf28SAndroid Build Coastguard Worker             len = lengths[ct];
330*e1eccf28SAndroid Build Coastguard Worker         } else {
331*e1eccf28SAndroid Build Coastguard Worker             len = strlen(nin[ct]);
332*e1eccf28SAndroid Build Coastguard Worker         }
333*e1eccf28SAndroid Build Coastguard Worker         if (asin) {
334*e1eccf28SAndroid Build Coastguard Worker             asize = asin[ct];
335*e1eccf28SAndroid Build Coastguard Worker         }
336*e1eccf28SAndroid Build Coastguard Worker 
337*e1eccf28SAndroid Build Coastguard Worker         e->mFields[ct].e.set(ein[ct]);
338*e1eccf28SAndroid Build Coastguard Worker         e->mFields[ct].name = rsuCopyString(nin[ct], len);
339*e1eccf28SAndroid Build Coastguard Worker         e->mFields[ct].arraySize = asize;
340*e1eccf28SAndroid Build Coastguard Worker     }
341*e1eccf28SAndroid Build Coastguard Worker     e->compute();
342*e1eccf28SAndroid Build Coastguard Worker 
343*e1eccf28SAndroid Build Coastguard Worker     ObjectBase::asyncLock();
344*e1eccf28SAndroid Build Coastguard Worker     rsc->mStateElement.mElements.push_back(e);
345*e1eccf28SAndroid Build Coastguard Worker     ObjectBase::asyncUnlock();
346*e1eccf28SAndroid Build Coastguard Worker 
347*e1eccf28SAndroid Build Coastguard Worker     return returnRef;
348*e1eccf28SAndroid Build Coastguard Worker }
349*e1eccf28SAndroid Build Coastguard Worker 
incRefs(const void * ptr) const350*e1eccf28SAndroid Build Coastguard Worker void Element::incRefs(const void *ptr) const {
351*e1eccf28SAndroid Build Coastguard Worker     if (!mFieldCount) {
352*e1eccf28SAndroid Build Coastguard Worker         if (mComponent.isReference()) {
353*e1eccf28SAndroid Build Coastguard Worker             ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
354*e1eccf28SAndroid Build Coastguard Worker             ObjectBase *ob = obp[0];
355*e1eccf28SAndroid Build Coastguard Worker             if (ob) ob->incSysRef();
356*e1eccf28SAndroid Build Coastguard Worker         }
357*e1eccf28SAndroid Build Coastguard Worker         return;
358*e1eccf28SAndroid Build Coastguard Worker     }
359*e1eccf28SAndroid Build Coastguard Worker 
360*e1eccf28SAndroid Build Coastguard Worker     const uint8_t *p = static_cast<const uint8_t *>(ptr);
361*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t i=0; i < mFieldCount; i++) {
362*e1eccf28SAndroid Build Coastguard Worker         if (mFields[i].e->mHasReference) {
363*e1eccf28SAndroid Build Coastguard Worker             const uint8_t *p2 = &p[mFields[i].offsetBits >> 3];
364*e1eccf28SAndroid Build Coastguard Worker             for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
365*e1eccf28SAndroid Build Coastguard Worker                 mFields[i].e->incRefs(p2);
366*e1eccf28SAndroid Build Coastguard Worker                 p2 += mFields[i].e->getSizeBytes();
367*e1eccf28SAndroid Build Coastguard Worker             }
368*e1eccf28SAndroid Build Coastguard Worker         }
369*e1eccf28SAndroid Build Coastguard Worker     }
370*e1eccf28SAndroid Build Coastguard Worker }
371*e1eccf28SAndroid Build Coastguard Worker 
decRefs(const void * ptr) const372*e1eccf28SAndroid Build Coastguard Worker void Element::decRefs(const void *ptr) const {
373*e1eccf28SAndroid Build Coastguard Worker     if (!mFieldCount) {
374*e1eccf28SAndroid Build Coastguard Worker         if (mComponent.isReference()) {
375*e1eccf28SAndroid Build Coastguard Worker             ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
376*e1eccf28SAndroid Build Coastguard Worker             ObjectBase *ob = obp[0];
377*e1eccf28SAndroid Build Coastguard Worker             if (ob) ob->decSysRef();
378*e1eccf28SAndroid Build Coastguard Worker         }
379*e1eccf28SAndroid Build Coastguard Worker         return;
380*e1eccf28SAndroid Build Coastguard Worker     }
381*e1eccf28SAndroid Build Coastguard Worker 
382*e1eccf28SAndroid Build Coastguard Worker     const uint8_t *p = static_cast<const uint8_t *>(ptr);
383*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t i=0; i < mFieldCount; i++) {
384*e1eccf28SAndroid Build Coastguard Worker         if (mFields[i].e->mHasReference) {
385*e1eccf28SAndroid Build Coastguard Worker             const uint8_t *p2 = &p[mFields[i].offsetBits >> 3];
386*e1eccf28SAndroid Build Coastguard Worker             for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
387*e1eccf28SAndroid Build Coastguard Worker                 mFields[i].e->decRefs(p2);
388*e1eccf28SAndroid Build Coastguard Worker                 p2 += mFields[i].e->getSizeBytes();
389*e1eccf28SAndroid Build Coastguard Worker             }
390*e1eccf28SAndroid Build Coastguard Worker         }
391*e1eccf28SAndroid Build Coastguard Worker     }
392*e1eccf28SAndroid Build Coastguard Worker }
393*e1eccf28SAndroid Build Coastguard Worker 
callUpdateCacheObject(const Context * rsc,void * dstObj) const394*e1eccf28SAndroid Build Coastguard Worker void Element::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
395*e1eccf28SAndroid Build Coastguard Worker     if (rsc->mHal.funcs.element.updateCachedObject != nullptr) {
396*e1eccf28SAndroid Build Coastguard Worker         rsc->mHal.funcs.element.updateCachedObject(rsc, this, (rs_element *)dstObj);
397*e1eccf28SAndroid Build Coastguard Worker     } else {
398*e1eccf28SAndroid Build Coastguard Worker         *((const void **)dstObj) = this;
399*e1eccf28SAndroid Build Coastguard Worker     }
400*e1eccf28SAndroid Build Coastguard Worker }
401*e1eccf28SAndroid Build Coastguard Worker 
ElementState()402*e1eccf28SAndroid Build Coastguard Worker ElementState::ElementState() {
403*e1eccf28SAndroid Build Coastguard Worker }
404*e1eccf28SAndroid Build Coastguard Worker 
~ElementState()405*e1eccf28SAndroid Build Coastguard Worker ElementState::~ElementState() {
406*e1eccf28SAndroid Build Coastguard Worker     rsAssert(!mElements.size());
407*e1eccf28SAndroid Build Coastguard Worker }
408*e1eccf28SAndroid Build Coastguard Worker 
409*e1eccf28SAndroid Build Coastguard Worker /////////////////////////////////////////
410*e1eccf28SAndroid Build Coastguard Worker //
411*e1eccf28SAndroid Build Coastguard Worker 
rsi_ElementCreate(Context * rsc,RsDataType dt,RsDataKind dk,bool norm,uint32_t vecSize)412*e1eccf28SAndroid Build Coastguard Worker RsElement rsi_ElementCreate(Context *rsc,
413*e1eccf28SAndroid Build Coastguard Worker                             RsDataType dt,
414*e1eccf28SAndroid Build Coastguard Worker                             RsDataKind dk,
415*e1eccf28SAndroid Build Coastguard Worker                             bool norm,
416*e1eccf28SAndroid Build Coastguard Worker                             uint32_t vecSize) {
417*e1eccf28SAndroid Build Coastguard Worker     return (RsElement)Element::create(rsc, dt, dk, norm, vecSize);
418*e1eccf28SAndroid Build Coastguard Worker }
419*e1eccf28SAndroid Build Coastguard Worker 
420*e1eccf28SAndroid Build Coastguard Worker 
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)421*e1eccf28SAndroid Build Coastguard Worker RsElement rsi_ElementCreate2(Context *rsc,
422*e1eccf28SAndroid Build Coastguard Worker                              const RsElement * ein,
423*e1eccf28SAndroid Build Coastguard Worker                              size_t ein_length,
424*e1eccf28SAndroid Build Coastguard Worker 
425*e1eccf28SAndroid Build Coastguard Worker                              const char ** names,
426*e1eccf28SAndroid Build Coastguard Worker                              size_t nameLengths_length,
427*e1eccf28SAndroid Build Coastguard Worker                              const size_t * nameLengths,
428*e1eccf28SAndroid Build Coastguard Worker 
429*e1eccf28SAndroid Build Coastguard Worker                              const uint32_t * arraySizes,
430*e1eccf28SAndroid Build Coastguard Worker                              size_t arraySizes_length) {
431*e1eccf28SAndroid Build Coastguard Worker     return (RsElement)Element::create(rsc, ein_length, (const Element **)ein,
432*e1eccf28SAndroid Build Coastguard Worker                                       names, nameLengths, arraySizes);
433*e1eccf28SAndroid Build Coastguard Worker }
434*e1eccf28SAndroid Build Coastguard Worker 
435*e1eccf28SAndroid Build Coastguard Worker } // namespace renderscript
436*e1eccf28SAndroid Build Coastguard Worker } // namespace android
437