rsElement.cpp revision 87319de2b16a185cf360827c96a42cf1fcaae744
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#ifndef ANDROID_RS_BUILD_FOR_HOST
19#include "rsContext.h"
20#include <GLES/gl.h>
21#else
22#include "rsContextHostStub.h"
23#include <OpenGL/gl.h>
24#endif
25
26using namespace android;
27using namespace android::renderscript;
28
29
30Element::Element(Context *rsc) : ObjectBase(rsc) {
31    mBits = 0;
32    mFields = NULL;
33    mFieldCount = 0;
34    mHasReference = false;
35}
36
37Element::~Element() {
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    clear();
45}
46
47void Element::clear() {
48    delete [] mFields;
49    mFields = NULL;
50    mFieldCount = 0;
51    mHasReference = false;
52}
53
54size_t Element::getSizeBits() const {
55    if (!mFieldCount) {
56        return mBits;
57    }
58
59    size_t total = 0;
60    for (size_t ct=0; ct < mFieldCount; ct++) {
61        total += mFields[ct].e->mBits * mFields[ct].arraySize;
62    }
63    return total;
64}
65
66void Element::dumpLOGV(const char *prefix) const {
67    ObjectBase::dumpLOGV(prefix);
68    LOGV("%s Element: fieldCount: %i,  size bytes: %i", prefix, mFieldCount, getSizeBytes());
69    for (uint32_t ct = 0; ct < mFieldCount; ct++) {
70        LOGV("%s Element field index: %u ------------------", prefix, ct);
71        LOGV("%s name: %s, offsetBits: %u, arraySize: %u",
72             prefix, mFields[ct].name.string(), mFields[ct].offsetBits, mFields[ct].arraySize);
73        mFields[ct].e->dumpLOGV(prefix);
74    }
75}
76
77void Element::serialize(OStream *stream) const {
78    // Need to identify ourselves
79    stream->addU32((uint32_t)getClassId());
80
81    String8 name(getName());
82    stream->addString(&name);
83
84    mComponent.serialize(stream);
85
86    // Now serialize all the fields
87    stream->addU32(mFieldCount);
88    for (uint32_t ct = 0; ct < mFieldCount; ct++) {
89        stream->addString(&mFields[ct].name);
90        stream->addU32(mFields[ct].arraySize);
91        mFields[ct].e->serialize(stream);
92    }
93}
94
95Element *Element::createFromStream(Context *rsc, IStream *stream) {
96    // First make sure we are reading the correct object
97    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
98    if (classID != RS_A3D_CLASS_ID_ELEMENT) {
99        LOGE("element loading skipped due to invalid class id\n");
100        return NULL;
101    }
102
103    String8 name;
104    stream->loadString(&name);
105
106    Element *elem = new Element(rsc);
107    elem->mComponent.loadFromStream(stream);
108
109    elem->mFieldCount = stream->loadU32();
110    if (elem->mFieldCount) {
111        elem->mFields = new ElementField_t [elem->mFieldCount];
112        for (uint32_t ct = 0; ct < elem->mFieldCount; ct ++) {
113            stream->loadString(&elem->mFields[ct].name);
114            elem->mFields[ct].arraySize = stream->loadU32();
115            Element *fieldElem = Element::createFromStream(rsc, stream);
116            elem->mFields[ct].e.set(fieldElem);
117        }
118    }
119
120    // We need to check if this already exists
121    for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
122        Element *ee = rsc->mStateElement.mElements[ct];
123        if (ee->isEqual(elem)) {
124            ObjectBase::checkDelete(elem);
125            ee->incUserRef();
126            return ee;
127        }
128    }
129
130    elem->compute();
131    rsc->mStateElement.mElements.push(elem);
132    return elem;
133}
134
135bool Element::isEqual(const Element *other) const {
136    if (other == NULL) {
137        return false;
138    }
139    if (!other->getFieldCount() && !mFieldCount) {
140        if ((other->getType() == getType()) &&
141           (other->getKind() == getKind()) &&
142           (other->getComponent().getIsNormalized() == getComponent().getIsNormalized()) &&
143           (other->getComponent().getVectorSize() == getComponent().getVectorSize())) {
144            return true;
145        }
146        return false;
147    }
148    if (other->getFieldCount() == mFieldCount) {
149        for (uint32_t i=0; i < mFieldCount; i++) {
150            if ((!other->mFields[i].e->isEqual(mFields[i].e.get())) ||
151                (other->mFields[i].name.length() != mFields[i].name.length()) ||
152                (other->mFields[i].name != mFields[i].name) ||
153                (other->mFields[i].arraySize != mFields[i].arraySize)) {
154                return false;
155            }
156        }
157        return true;
158    }
159    return false;
160}
161
162void Element::compute() {
163    if (mFieldCount == 0) {
164        mBits = mComponent.getBits();
165        mHasReference = mComponent.isReference();
166        return;
167    }
168
169    size_t bits = 0;
170    for (size_t ct=0; ct < mFieldCount; ct++) {
171        mFields[ct].offsetBits = bits;
172        bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize;
173
174        if (mFields[ct].e->mHasReference) {
175            mHasReference = true;
176        }
177    }
178
179}
180
181const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
182                                bool isNorm, uint32_t vecSize) {
183    // Look for an existing match.
184    for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
185        const Element *ee = rsc->mStateElement.mElements[ct];
186        if (!ee->getFieldCount() &&
187            (ee->getComponent().getType() == dt) &&
188            (ee->getComponent().getKind() == dk) &&
189            (ee->getComponent().getIsNormalized() == isNorm) &&
190            (ee->getComponent().getVectorSize() == vecSize)) {
191            // Match
192            ee->incUserRef();
193            return ee;
194        }
195    }
196
197    Element *e = new Element(rsc);
198    e->mComponent.set(dt, dk, isNorm, vecSize);
199    e->compute();
200    rsc->mStateElement.mElements.push(e);
201    return e;
202}
203
204const Element * Element::create(Context *rsc, size_t count, const Element **ein,
205                            const char **nin, const size_t * lengths, const uint32_t *asin) {
206    // Look for an existing match.
207    for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
208        const Element *ee = rsc->mStateElement.mElements[ct];
209        if (ee->getFieldCount() == count) {
210            bool match = true;
211            for (uint32_t i=0; i < count; i++) {
212                if ((ee->mFields[i].e.get() != ein[i]) ||
213                    (ee->mFields[i].name.length() != lengths[i]) ||
214                    (ee->mFields[i].name != nin[i]) ||
215                    (ee->mFields[i].arraySize != asin[i])) {
216                    match = false;
217                    break;
218                }
219            }
220            if (match) {
221                ee->incUserRef();
222                return ee;
223            }
224        }
225    }
226
227    Element *e = new Element(rsc);
228    e->mFields = new ElementField_t [count];
229    e->mFieldCount = count;
230    for (size_t ct=0; ct < count; ct++) {
231        e->mFields[ct].e.set(ein[ct]);
232        e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
233        e->mFields[ct].arraySize = asin[ct];
234    }
235    e->compute();
236
237    rsc->mStateElement.mElements.push(e);
238    return e;
239}
240
241String8 Element::getGLSLType(uint32_t indent) const {
242    String8 s;
243    for (uint32_t ct=0; ct < indent; ct++) {
244        s.append(" ");
245    }
246
247    if (!mFieldCount) {
248        // Basic component.
249        s.append(mComponent.getGLSLType());
250    } else {
251        rsAssert(0);
252        //s.append("struct ");
253        //s.append(getCStructBody(indent));
254    }
255
256    return s;
257}
258
259void Element::incRefs(const void *ptr) const {
260    if (!mFieldCount) {
261        if (mComponent.isReference()) {
262            ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
263            ObjectBase *ob = obp[0];
264            if (ob) ob->incSysRef();
265        }
266        return;
267    }
268
269    const uint8_t *p = static_cast<const uint8_t *>(ptr);
270    for (uint32_t i=0; i < mFieldCount; i++) {
271        if (mFields[i].e->mHasReference) {
272            p = &p[mFields[i].offsetBits >> 3];
273            for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
274                mFields[i].e->incRefs(p);
275                p += mFields[i].e->getSizeBytes();
276            }
277        }
278    }
279}
280
281void Element::decRefs(const void *ptr) const {
282    if (!mFieldCount) {
283        if (mComponent.isReference()) {
284            ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
285            ObjectBase *ob = obp[0];
286            if (ob) ob->decSysRef();
287        }
288        return;
289    }
290
291    const uint8_t *p = static_cast<const uint8_t *>(ptr);
292    for (uint32_t i=0; i < mFieldCount; i++) {
293        if (mFields[i].e->mHasReference) {
294            p = &p[mFields[i].offsetBits >> 3];
295            for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
296                mFields[i].e->decRefs(p);
297                p += mFields[i].e->getSizeBytes();
298            }
299        }
300    }
301}
302
303
304ElementState::ElementState() {
305    const uint32_t initialCapacity = 32;
306    mBuilderElements.setCapacity(initialCapacity);
307    mBuilderNameStrings.setCapacity(initialCapacity);
308    mBuilderNameLengths.setCapacity(initialCapacity);
309    mBuilderArrays.setCapacity(initialCapacity);
310}
311
312ElementState::~ElementState() {
313    rsAssert(!mElements.size());
314}
315
316void ElementState::elementBuilderBegin() {
317    mBuilderElements.clear();
318    mBuilderNameStrings.clear();
319    mBuilderNameLengths.clear();
320    mBuilderArrays.clear();
321}
322
323void ElementState::elementBuilderAdd(const Element *e, const char *nameStr, uint32_t arraySize) {
324    mBuilderElements.push(e);
325    mBuilderNameStrings.push(nameStr);
326    mBuilderNameLengths.push(strlen(nameStr));
327    mBuilderArrays.push(arraySize);
328
329}
330
331const Element *ElementState::elementBuilderCreate(Context *rsc) {
332    return Element::create(rsc, mBuilderElements.size(),
333                                &(mBuilderElements.editArray()[0]),
334                                &(mBuilderNameStrings.editArray()[0]),
335                                mBuilderNameLengths.editArray(),
336                                mBuilderArrays.editArray());
337}
338
339
340/////////////////////////////////////////
341//
342
343namespace android {
344namespace renderscript {
345
346RsElement rsi_ElementCreate(Context *rsc,
347                            RsDataType dt,
348                            RsDataKind dk,
349                            bool norm,
350                            uint32_t vecSize) {
351    const Element *e = Element::create(rsc, dt, dk, norm, vecSize);
352    e->incUserRef();
353    return (RsElement)e;
354}
355
356RsElement rsi_ElementCreate2(Context *rsc,
357                             size_t count,
358                             const RsElement * ein,
359                             const char ** names,
360                             const size_t * nameLengths,
361                             const uint32_t * arraySizes) {
362    const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths, arraySizes);
363    e->incUserRef();
364    return (RsElement)e;
365}
366
367}
368}
369
370void rsaElementGetNativeData(RsContext con, RsElement elem, uint32_t *elemData, uint32_t elemDataSize) {
371    rsAssert(elemDataSize == 5);
372    // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
373    Element *e = static_cast<Element *>(elem);
374
375    (*elemData++) = (uint32_t)e->getType();
376    (*elemData++) = (uint32_t)e->getKind();
377    (*elemData++) = e->getComponent().getIsNormalized() ? 1 : 0;
378    (*elemData++) = e->getComponent().getVectorSize();
379    (*elemData++) = e->getFieldCount();
380}
381
382void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids, const char **names, uint32_t dataSize) {
383    Element *e = static_cast<Element *>(elem);
384    rsAssert(e->getFieldCount() == dataSize);
385
386    for (uint32_t i = 0; i < dataSize; i ++) {
387        e->getField(i)->incUserRef();
388        ids[i] = (uint32_t)e->getField(i);
389        names[i] = e->getFieldName(i);
390    }
391}
392