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