rsElement.cpp revision 70b83c111beceaf8fbb700580833e7fec99272cf
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/*
2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Copyright (C) 2009 The Android Open Source Project
3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License.
6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at
7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software
11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and
14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License.
15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */
16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
17326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
18fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#include "rsContext.h"
19565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
20326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
21326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
22326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
23326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
24afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukElement::Element(Context *rsc) : ObjectBase(rsc) {
254815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mBits = 0;
264815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mFields = NULL;
274815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mFieldCount = 0;
28e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    mHasReference = false;
29326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
30326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
31afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukElement::~Element() {
328154954868694e1f233d87d4933a474518b1cb81Jason Sams    for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) {
338154954868694e1f233d87d4933a474518b1cb81Jason Sams        if (mRSC->mStateElement.mElements[ct] == this) {
348154954868694e1f233d87d4933a474518b1cb81Jason Sams            mRSC->mStateElement.mElements.removeAt(ct);
358154954868694e1f233d87d4933a474518b1cb81Jason Sams            break;
368154954868694e1f233d87d4933a474518b1cb81Jason Sams        }
378154954868694e1f233d87d4933a474518b1cb81Jason Sams    }
38326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    clear();
39326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
40326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
41afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Element::clear() {
424815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    delete [] mFields;
434815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mFields = NULL;
444815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mFieldCount = 0;
45e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    mHasReference = false;
46326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
47326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
48afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouksize_t Element::getSizeBits() const {
494815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    if (!mFieldCount) {
504815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        return mBits;
514815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    }
524815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
53326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    size_t total = 0;
544815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    for (size_t ct=0; ct < mFieldCount; ct++) {
5539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        total += mFields[ct].e->mBits * mFields[ct].arraySize;
56326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
57326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    return total;
58326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
59326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
60afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Element::dumpLOGV(const char *prefix) const {
61e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams    ObjectBase::dumpLOGV(prefix);
62099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk    LOGV("%s Element: fieldCount: %zu,  size bytes: %zu", prefix, mFieldCount, getSizeBytes());
634815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    for (uint32_t ct = 0; ct < mFieldCount; ct++) {
64963bb455b6130fac7a93e2352a4910e446a65a71Alex Sakhartchouk        LOGV("%s Element field index: %u ------------------", prefix, ct);
65963bb455b6130fac7a93e2352a4910e446a65a71Alex Sakhartchouk        LOGV("%s name: %s, offsetBits: %u, arraySize: %u",
66963bb455b6130fac7a93e2352a4910e446a65a71Alex Sakhartchouk             prefix, mFields[ct].name.string(), mFields[ct].offsetBits, mFields[ct].arraySize);
67963bb455b6130fac7a93e2352a4910e446a65a71Alex Sakhartchouk        mFields[ct].e->dumpLOGV(prefix);
68e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams    }
69e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams}
70e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams
71afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Element::serialize(OStream *stream) const {
72fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Need to identify ourselves
73fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32((uint32_t)getClassId());
74fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
75fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name(getName());
76fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addString(&name);
77fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
78fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mComponent.serialize(stream);
79fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
80fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Now serialize all the fields
81fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32(mFieldCount);
82afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    for (uint32_t ct = 0; ct < mFieldCount; ct++) {
83fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        stream->addString(&mFields[ct].name);
8446e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams        stream->addU32(mFields[ct].arraySize);
85fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        mFields[ct].e->serialize(stream);
86fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
87fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
88fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
89afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukElement *Element::createFromStream(Context *rsc, IStream *stream) {
90fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First make sure we are reading the correct object
91b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
92afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_ELEMENT) {
93fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("element loading skipped due to invalid class id\n");
94fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
95fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
96fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
97fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name;
98fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->loadString(&name);
99fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
100fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    Element *elem = new Element(rsc);
101fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    elem->mComponent.loadFromStream(stream);
102fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
103fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    elem->mFieldCount = stream->loadU32();
104afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (elem->mFieldCount) {
105fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        elem->mFields = new ElementField_t [elem->mFieldCount];
106afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        for (uint32_t ct = 0; ct < elem->mFieldCount; ct ++) {
107fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk            stream->loadString(&elem->mFields[ct].name);
10846e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams            elem->mFields[ct].arraySize = stream->loadU32();
109fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk            Element *fieldElem = Element::createFromStream(rsc, stream);
110fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk            elem->mFields[ct].e.set(fieldElem);
111fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        }
112fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
113fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
114fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // We need to check if this already exists
115fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
116fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        Element *ee = rsc->mStateElement.mElements[ct];
117afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        if (ee->isEqual(elem)) {
118225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams            ObjectBase::checkDelete(elem);
119383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            ee->incUserRef();
120383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            return ee;
121fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        }
122fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
123fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
12454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    elem->compute();
125fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    rsc->mStateElement.mElements.push(elem);
126fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return elem;
127fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
128fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
129383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchoukbool Element::isEqual(const Element *other) const {
130afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (other == NULL) {
131383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        return false;
132383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    }
133383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    if (!other->getFieldCount() && !mFieldCount) {
134afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        if ((other->getType() == getType()) &&
135383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk           (other->getKind() == getKind()) &&
136383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk           (other->getComponent().getIsNormalized() == getComponent().getIsNormalized()) &&
137383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk           (other->getComponent().getVectorSize() == getComponent().getVectorSize())) {
138383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            return true;
139383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        }
140383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        return false;
141383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    }
142383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    if (other->getFieldCount() == mFieldCount) {
143383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        for (uint32_t i=0; i < mFieldCount; i++) {
144383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            if ((!other->mFields[i].e->isEqual(mFields[i].e.get())) ||
145383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk                (other->mFields[i].name.length() != mFields[i].name.length()) ||
146383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk                (other->mFields[i].name != mFields[i].name) ||
147383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk                (other->mFields[i].arraySize != mFields[i].arraySize)) {
148383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk                return false;
149383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            }
150383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        }
151383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        return true;
152383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    }
153383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    return false;
154383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk}
155d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams
15654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchoukvoid Element::compute() {
157afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (mFieldCount == 0) {
15854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        mBits = mComponent.getBits();
15954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        mHasReference = mComponent.isReference();
16054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        return;
16154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
16254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
16354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    size_t bits = 0;
16454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    for (size_t ct=0; ct < mFieldCount; ct++) {
16554929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        mFields[ct].offsetBits = bits;
16654929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize;
16754929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
16854929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        if (mFields[ct].e->mHasReference) {
16954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk            mHasReference = true;
17054929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk        }
17154929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    }
17254929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
17354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk}
17454929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk
1758154954868694e1f233d87d4933a474518b1cb81Jason Samsconst Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
176afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                bool isNorm, uint32_t vecSize) {
1778154954868694e1f233d87d4933a474518b1cb81Jason Sams    // Look for an existing match.
1788154954868694e1f233d87d4933a474518b1cb81Jason Sams    for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
1798154954868694e1f233d87d4933a474518b1cb81Jason Sams        const Element *ee = rsc->mStateElement.mElements[ct];
1808154954868694e1f233d87d4933a474518b1cb81Jason Sams        if (!ee->getFieldCount() &&
1818154954868694e1f233d87d4933a474518b1cb81Jason Sams            (ee->getComponent().getType() == dt) &&
1828154954868694e1f233d87d4933a474518b1cb81Jason Sams            (ee->getComponent().getKind() == dk) &&
1838154954868694e1f233d87d4933a474518b1cb81Jason Sams            (ee->getComponent().getIsNormalized() == isNorm) &&
1848154954868694e1f233d87d4933a474518b1cb81Jason Sams            (ee->getComponent().getVectorSize() == vecSize)) {
1858154954868694e1f233d87d4933a474518b1cb81Jason Sams            // Match
1868154954868694e1f233d87d4933a474518b1cb81Jason Sams            ee->incUserRef();
1878154954868694e1f233d87d4933a474518b1cb81Jason Sams            return ee;
1888154954868694e1f233d87d4933a474518b1cb81Jason Sams        }
1898154954868694e1f233d87d4933a474518b1cb81Jason Sams    }
1908154954868694e1f233d87d4933a474518b1cb81Jason Sams
1914815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    Element *e = new Element(rsc);
192d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    e->mComponent.set(dt, dk, isNorm, vecSize);
19354929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    e->compute();
1948154954868694e1f233d87d4933a474518b1cb81Jason Sams    rsc->mStateElement.mElements.push(e);
1954815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    return e;
1964815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
1974815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
1988154954868694e1f233d87d4933a474518b1cb81Jason Samsconst Element * Element::create(Context *rsc, size_t count, const Element **ein,
199afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                            const char **nin, const size_t * lengths, const uint32_t *asin) {
2008154954868694e1f233d87d4933a474518b1cb81Jason Sams    // Look for an existing match.
2018154954868694e1f233d87d4933a474518b1cb81Jason Sams    for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
2028154954868694e1f233d87d4933a474518b1cb81Jason Sams        const Element *ee = rsc->mStateElement.mElements[ct];
2038154954868694e1f233d87d4933a474518b1cb81Jason Sams        if (ee->getFieldCount() == count) {
2048154954868694e1f233d87d4933a474518b1cb81Jason Sams            bool match = true;
2058154954868694e1f233d87d4933a474518b1cb81Jason Sams            for (uint32_t i=0; i < count; i++) {
2068154954868694e1f233d87d4933a474518b1cb81Jason Sams                if ((ee->mFields[i].e.get() != ein[i]) ||
2078154954868694e1f233d87d4933a474518b1cb81Jason Sams                    (ee->mFields[i].name.length() != lengths[i]) ||
20846e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams                    (ee->mFields[i].name != nin[i]) ||
20946e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams                    (ee->mFields[i].arraySize != asin[i])) {
2108154954868694e1f233d87d4933a474518b1cb81Jason Sams                    match = false;
2118154954868694e1f233d87d4933a474518b1cb81Jason Sams                    break;
2128154954868694e1f233d87d4933a474518b1cb81Jason Sams                }
2138154954868694e1f233d87d4933a474518b1cb81Jason Sams            }
2148154954868694e1f233d87d4933a474518b1cb81Jason Sams            if (match) {
2158154954868694e1f233d87d4933a474518b1cb81Jason Sams                ee->incUserRef();
2168154954868694e1f233d87d4933a474518b1cb81Jason Sams                return ee;
2178154954868694e1f233d87d4933a474518b1cb81Jason Sams            }
2188154954868694e1f233d87d4933a474518b1cb81Jason Sams        }
2198154954868694e1f233d87d4933a474518b1cb81Jason Sams    }
2208154954868694e1f233d87d4933a474518b1cb81Jason Sams
2214815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    Element *e = new Element(rsc);
2224815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    e->mFields = new ElementField_t [count];
2234815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    e->mFieldCount = count;
2244815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    for (size_t ct=0; ct < count; ct++) {
2254815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        e->mFields[ct].e.set(ein[ct]);
2264815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
22746e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams        e->mFields[ct].arraySize = asin[ct];
2284815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    }
22954929cce0bf44090424b1f91b676529a2422378fAlex Sakhartchouk    e->compute();
2304815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
2318154954868694e1f233d87d4933a474518b1cb81Jason Sams    rsc->mStateElement.mElements.push(e);
2324815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    return e;
2334815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
2344815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
235afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukString8 Element::getGLSLType(uint32_t indent) const {
236b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    String8 s;
237b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    for (uint32_t ct=0; ct < indent; ct++) {
238b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        s.append(" ");
239b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    }
240b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
241b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    if (!mFieldCount) {
242b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        // Basic component.
243b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        s.append(mComponent.getGLSLType());
244b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    } else {
245b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        rsAssert(0);
246b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        //s.append("struct ");
247b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams        //s.append(getCStructBody(indent));
248b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    }
249b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams
250b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams    return s;
251b4d3568f68b1ae97e2a82061cccf220f8e93cd94Jason Sams}
252d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams
253afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Element::incRefs(const void *ptr) const {
254e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    if (!mFieldCount) {
255e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        if (mComponent.isReference()) {
256e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams            ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
257e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams            ObjectBase *ob = obp[0];
25810e5e570bab66a6cd543c857b26c576795eb240fJason Sams            if (ob) ob->incSysRef();
259e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        }
260e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        return;
261e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
262e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
263e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
264e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    for (uint32_t i=0; i < mFieldCount; i++) {
265e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        if (mFields[i].e->mHasReference) {
26646e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams            p = &p[mFields[i].offsetBits >> 3];
26746e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams            for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
26846e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams                mFields[i].e->incRefs(p);
26946e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams                p += mFields[i].e->getSizeBytes();
27046e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams            }
271e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        }
272e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
273e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
274e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
275afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Element::decRefs(const void *ptr) const {
276e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    if (!mFieldCount) {
277e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        if (mComponent.isReference()) {
278e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams            ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
279e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams            ObjectBase *ob = obp[0];
28010e5e570bab66a6cd543c857b26c576795eb240fJason Sams            if (ob) ob->decSysRef();
281e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        }
282e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        return;
283e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
284e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
285e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
286e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    for (uint32_t i=0; i < mFieldCount; i++) {
287e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        if (mFields[i].e->mHasReference) {
28846e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams            p = &p[mFields[i].offsetBits >> 3];
28946e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams            for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
29046e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams                mFields[i].e->decRefs(p);
29146e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams                p += mFields[i].e->getSizeBytes();
29246e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams            }
293e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        }
294e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
295e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
296d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams
2974815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
298afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukElementState::ElementState() {
299e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    const uint32_t initialCapacity = 32;
300e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderElements.setCapacity(initialCapacity);
301e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderNameStrings.setCapacity(initialCapacity);
302e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderNameLengths.setCapacity(initialCapacity);
303e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderArrays.setCapacity(initialCapacity);
304326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
305326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
306afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukElementState::~ElementState() {
3078154954868694e1f233d87d4933a474518b1cb81Jason Sams    rsAssert(!mElements.size());
308326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
309326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
310e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchoukvoid ElementState::elementBuilderBegin() {
311e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderElements.clear();
312e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderNameStrings.clear();
313e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderNameLengths.clear();
314e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderArrays.clear();
315e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk}
316e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
317e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchoukvoid ElementState::elementBuilderAdd(const Element *e, const char *nameStr, uint32_t arraySize) {
318e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderElements.push(e);
319e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderNameStrings.push(nameStr);
320e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderNameLengths.push(strlen(nameStr));
321e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    mBuilderArrays.push(arraySize);
322e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
323e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk}
324e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
325e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchoukconst Element *ElementState::elementBuilderCreate(Context *rsc) {
326e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    return Element::create(rsc, mBuilderElements.size(),
327e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk                                &(mBuilderElements.editArray()[0]),
328e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk                                &(mBuilderNameStrings.editArray()[0]),
329e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk                                mBuilderNameLengths.editArray(),
330e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk                                mBuilderArrays.editArray());
331e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk}
332e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
3334815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
334326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/////////////////////////////////////////
335e5ffb879ae535a899a486285a23bea05e912480fJason Sams//
336326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
337326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
338326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
339326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
340d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason SamsRsElement rsi_ElementCreate(Context *rsc,
341d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams                            RsDataType dt,
342d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams                            RsDataKind dk,
343d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams                            bool norm,
344afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                            uint32_t vecSize) {
3458154954868694e1f233d87d4933a474518b1cb81Jason Sams    const Element *e = Element::create(rsc, dt, dk, norm, vecSize);
346d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    e->incUserRef();
3478154954868694e1f233d87d4933a474518b1cb81Jason Sams    return (RsElement)e;
348d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams}
3494815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
350d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason SamsRsElement rsi_ElementCreate2(Context *rsc,
351d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams                             const RsElement * ein,
35270b83c111beceaf8fbb700580833e7fec99272cfAlex Sakhartchouk                             size_t ein_length,
353d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams                             const char ** names,
35470b83c111beceaf8fbb700580833e7fec99272cfAlex Sakhartchouk                             size_t names_length,
35546e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams                             const size_t * nameLengths,
35670b83c111beceaf8fbb700580833e7fec99272cfAlex Sakhartchouk                             size_t nameLengths_length,
35770b83c111beceaf8fbb700580833e7fec99272cfAlex Sakhartchouk                             const uint32_t * arraySizes,
35870b83c111beceaf8fbb700580833e7fec99272cfAlex Sakhartchouk                             size_t arraySizes_length) {
35970b83c111beceaf8fbb700580833e7fec99272cfAlex Sakhartchouk    const Element *e = Element::create(rsc, ein_length, (const Element **)ein, names, nameLengths, arraySizes);
360d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    e->incUserRef();
3618154954868694e1f233d87d4933a474518b1cb81Jason Sams    return (RsElement)e;
362326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
363326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
364dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk}
365dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk}
366dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk
367afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsaElementGetNativeData(RsContext con, RsElement elem, uint32_t *elemData, uint32_t elemDataSize) {
368417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk    rsAssert(elemDataSize == 5);
369417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk    // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
370417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk    Element *e = static_cast<Element *>(elem);
371417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk
372417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk    (*elemData++) = (uint32_t)e->getType();
373417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk    (*elemData++) = (uint32_t)e->getKind();
374417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk    (*elemData++) = e->getComponent().getIsNormalized() ? 1 : 0;
375417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk    (*elemData++) = e->getComponent().getVectorSize();
376417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk    (*elemData++) = e->getFieldCount();
377417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk}
378417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk
379afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids, const char **names, uint32_t dataSize) {
380417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk    Element *e = static_cast<Element *>(elem);
381417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk    rsAssert(e->getFieldCount() == dataSize);
382417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk
383afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    for (uint32_t i = 0; i < dataSize; i ++) {
384f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        e->getField(i)->incUserRef();
385417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk        ids[i] = (uint32_t)e->getField(i);
386417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk        names[i] = e->getFieldName(i);
387417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk    }
388417e6a486adb02b3b29ada9725286f554cc6d0d3Alex Sakhartchouk}
389