blob: d5d5ca5c90325ace0adcb342b4ce8e28237cf758 [file] [log] [blame]
Jason Sams326e0dd2009-05-22 14:03:28 -07001/*
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
Jason Sams326e0dd2009-05-22 14:03:28 -070017
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070018#include "rsContext.h"
Jason Sams565ac362009-06-03 16:04:54 -070019
Jason Sams326e0dd2009-05-22 14:03:28 -070020using namespace android;
21using namespace android::renderscript;
22
Jason Sams326e0dd2009-05-22 14:03:28 -070023
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080024Element::Element(Context *rsc) : ObjectBase(rsc) {
Jason Sams4815c0d2009-12-15 12:58:36 -080025 mBits = 0;
Jason Sams4815c0d2009-12-15 12:58:36 -080026 mFields = NULL;
27 mFieldCount = 0;
Jason Samse3929c92010-08-09 18:13:33 -070028 mHasReference = false;
Jason Sams326e0dd2009-05-22 14:03:28 -070029}
30
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080031Element::~Element() {
Jason Sams81549542010-02-17 15:38:10 -080032 for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) {
33 if (mRSC->mStateElement.mElements[ct] == this) {
34 mRSC->mStateElement.mElements.removeAt(ct);
35 break;
36 }
37 }
Jason Sams326e0dd2009-05-22 14:03:28 -070038 clear();
39}
40
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080041void Element::clear() {
Jason Sams4815c0d2009-12-15 12:58:36 -080042 delete [] mFields;
43 mFields = NULL;
44 mFieldCount = 0;
Jason Samse3929c92010-08-09 18:13:33 -070045 mHasReference = false;
Jason Sams326e0dd2009-05-22 14:03:28 -070046}
Jason Sams326e0dd2009-05-22 14:03:28 -070047
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080048size_t Element::getSizeBits() const {
Jason Sams4815c0d2009-12-15 12:58:36 -080049 if (!mFieldCount) {
50 return mBits;
51 }
52
Jason Sams326e0dd2009-05-22 14:03:28 -070053 size_t total = 0;
Jason Sams4815c0d2009-12-15 12:58:36 -080054 for (size_t ct=0; ct < mFieldCount; ct++) {
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -070055 total += mFields[ct].e->mBits * mFields[ct].arraySize;
Jason Sams326e0dd2009-05-22 14:03:28 -070056 }
57 return total;
58}
59
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080060void Element::dumpLOGV(const char *prefix) const {
Jason Samse12c1c52009-09-27 17:50:38 -070061 ObjectBase::dumpLOGV(prefix);
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -080062 LOGV("%s Element: fieldCount: %zu, size bytes: %zu", prefix, mFieldCount, getSizeBytes());
Jason Sams4815c0d2009-12-15 12:58:36 -080063 for (uint32_t ct = 0; ct < mFieldCount; ct++) {
Alex Sakhartchouk963bb452010-10-13 14:22:02 -070064 LOGV("%s Element field index: %u ------------------", prefix, ct);
65 LOGV("%s name: %s, offsetBits: %u, arraySize: %u",
66 prefix, mFields[ct].name.string(), mFields[ct].offsetBits, mFields[ct].arraySize);
67 mFields[ct].e->dumpLOGV(prefix);
Jason Samse12c1c52009-09-27 17:50:38 -070068 }
69}
70
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080071void Element::serialize(OStream *stream) const {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070072 // Need to identify ourselves
73 stream->addU32((uint32_t)getClassId());
74
75 String8 name(getName());
76 stream->addString(&name);
77
78 mComponent.serialize(stream);
79
80 // Now serialize all the fields
81 stream->addU32(mFieldCount);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080082 for (uint32_t ct = 0; ct < mFieldCount; ct++) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070083 stream->addString(&mFields[ct].name);
Jason Sams46e45542010-09-02 17:35:23 -070084 stream->addU32(mFields[ct].arraySize);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070085 mFields[ct].e->serialize(stream);
86 }
87}
88
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080089Element *Element::createFromStream(Context *rsc, IStream *stream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070090 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070091 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080092 if (classID != RS_A3D_CLASS_ID_ELEMENT) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070093 LOGE("element loading skipped due to invalid class id\n");
94 return NULL;
95 }
96
97 String8 name;
98 stream->loadString(&name);
99
100 Element *elem = new Element(rsc);
101 elem->mComponent.loadFromStream(stream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700102
103 elem->mFieldCount = stream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800104 if (elem->mFieldCount) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700105 elem->mFields = new ElementField_t [elem->mFieldCount];
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800106 for (uint32_t ct = 0; ct < elem->mFieldCount; ct ++) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700107 stream->loadString(&elem->mFields[ct].name);
Jason Sams46e45542010-09-02 17:35:23 -0700108 elem->mFields[ct].arraySize = stream->loadU32();
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700109 Element *fieldElem = Element::createFromStream(rsc, stream);
110 elem->mFields[ct].e.set(fieldElem);
111 }
112 }
113
114 // We need to check if this already exists
115 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
116 Element *ee = rsc->mStateElement.mElements[ct];
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800117 if (ee->isEqual(elem)) {
Jason Sams225afd32010-10-21 14:06:55 -0700118 ObjectBase::checkDelete(elem);
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700119 ee->incUserRef();
120 return ee;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700121 }
122 }
123
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800124 elem->compute();
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700125 rsc->mStateElement.mElements.push(elem);
126 return elem;
127}
128
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700129bool Element::isEqual(const Element *other) const {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800130 if (other == NULL) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700131 return false;
132 }
133 if (!other->getFieldCount() && !mFieldCount) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800134 if ((other->getType() == getType()) &&
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700135 (other->getKind() == getKind()) &&
136 (other->getComponent().getIsNormalized() == getComponent().getIsNormalized()) &&
137 (other->getComponent().getVectorSize() == getComponent().getVectorSize())) {
138 return true;
139 }
140 return false;
141 }
142 if (other->getFieldCount() == mFieldCount) {
143 for (uint32_t i=0; i < mFieldCount; i++) {
144 if ((!other->mFields[i].e->isEqual(mFields[i].e.get())) ||
145 (other->mFields[i].name.length() != mFields[i].name.length()) ||
146 (other->mFields[i].name != mFields[i].name) ||
147 (other->mFields[i].arraySize != mFields[i].arraySize)) {
148 return false;
149 }
150 }
151 return true;
152 }
153 return false;
154}
Jason Samsd01d9702009-12-23 14:35:29 -0800155
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800156void Element::compute() {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800157 if (mFieldCount == 0) {
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800158 mBits = mComponent.getBits();
159 mHasReference = mComponent.isReference();
160 return;
161 }
162
163 size_t bits = 0;
164 for (size_t ct=0; ct < mFieldCount; ct++) {
165 mFields[ct].offsetBits = bits;
166 bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize;
167
168 if (mFields[ct].e->mHasReference) {
169 mHasReference = true;
170 }
171 }
172
173}
174
Jason Sams81549542010-02-17 15:38:10 -0800175const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800176 bool isNorm, uint32_t vecSize) {
Jason Sams81549542010-02-17 15:38:10 -0800177 // Look for an existing match.
178 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
179 const Element *ee = rsc->mStateElement.mElements[ct];
180 if (!ee->getFieldCount() &&
181 (ee->getComponent().getType() == dt) &&
182 (ee->getComponent().getKind() == dk) &&
183 (ee->getComponent().getIsNormalized() == isNorm) &&
184 (ee->getComponent().getVectorSize() == vecSize)) {
185 // Match
186 ee->incUserRef();
187 return ee;
188 }
189 }
190
Jason Sams4815c0d2009-12-15 12:58:36 -0800191 Element *e = new Element(rsc);
Jason Samsd01d9702009-12-23 14:35:29 -0800192 e->mComponent.set(dt, dk, isNorm, vecSize);
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800193 e->compute();
Jason Sams81549542010-02-17 15:38:10 -0800194 rsc->mStateElement.mElements.push(e);
Jason Sams4815c0d2009-12-15 12:58:36 -0800195 return e;
196}
197
Jason Sams81549542010-02-17 15:38:10 -0800198const Element * Element::create(Context *rsc, size_t count, const Element **ein,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800199 const char **nin, const size_t * lengths, const uint32_t *asin) {
Jason Sams81549542010-02-17 15:38:10 -0800200 // Look for an existing match.
201 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
202 const Element *ee = rsc->mStateElement.mElements[ct];
203 if (ee->getFieldCount() == count) {
204 bool match = true;
205 for (uint32_t i=0; i < count; i++) {
206 if ((ee->mFields[i].e.get() != ein[i]) ||
207 (ee->mFields[i].name.length() != lengths[i]) ||
Jason Sams46e45542010-09-02 17:35:23 -0700208 (ee->mFields[i].name != nin[i]) ||
209 (ee->mFields[i].arraySize != asin[i])) {
Jason Sams81549542010-02-17 15:38:10 -0800210 match = false;
211 break;
212 }
213 }
214 if (match) {
215 ee->incUserRef();
216 return ee;
217 }
218 }
219 }
220
Jason Sams4815c0d2009-12-15 12:58:36 -0800221 Element *e = new Element(rsc);
222 e->mFields = new ElementField_t [count];
223 e->mFieldCount = count;
Jason Sams4815c0d2009-12-15 12:58:36 -0800224 for (size_t ct=0; ct < count; ct++) {
225 e->mFields[ct].e.set(ein[ct]);
226 e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
Jason Sams46e45542010-09-02 17:35:23 -0700227 e->mFields[ct].arraySize = asin[ct];
Jason Sams4815c0d2009-12-15 12:58:36 -0800228 }
Alex Sakhartchouk54929cc2010-11-08 15:10:52 -0800229 e->compute();
Jason Sams4815c0d2009-12-15 12:58:36 -0800230
Jason Sams81549542010-02-17 15:38:10 -0800231 rsc->mStateElement.mElements.push(e);
Jason Sams4815c0d2009-12-15 12:58:36 -0800232 return e;
233}
234
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800235String8 Element::getGLSLType(uint32_t indent) const {
Jason Samsb4d35682010-01-04 16:52:27 -0800236 String8 s;
237 for (uint32_t ct=0; ct < indent; ct++) {
238 s.append(" ");
239 }
240
241 if (!mFieldCount) {
242 // Basic component.
243 s.append(mComponent.getGLSLType());
244 } else {
245 rsAssert(0);
246 //s.append("struct ");
247 //s.append(getCStructBody(indent));
248 }
249
250 return s;
251}
Jason Samsd01d9702009-12-23 14:35:29 -0800252
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800253void Element::incRefs(const void *ptr) const {
Jason Samse3929c92010-08-09 18:13:33 -0700254 if (!mFieldCount) {
255 if (mComponent.isReference()) {
256 ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
257 ObjectBase *ob = obp[0];
Jason Sams10e5e572010-08-12 12:44:02 -0700258 if (ob) ob->incSysRef();
Jason Samse3929c92010-08-09 18:13:33 -0700259 }
260 return;
261 }
262
263 const uint8_t *p = static_cast<const uint8_t *>(ptr);
264 for (uint32_t i=0; i < mFieldCount; i++) {
265 if (mFields[i].e->mHasReference) {
Jason Sams46e45542010-09-02 17:35:23 -0700266 p = &p[mFields[i].offsetBits >> 3];
267 for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
268 mFields[i].e->incRefs(p);
269 p += mFields[i].e->getSizeBytes();
270 }
Jason Samse3929c92010-08-09 18:13:33 -0700271 }
272 }
273}
274
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800275void Element::decRefs(const void *ptr) const {
Jason Samse3929c92010-08-09 18:13:33 -0700276 if (!mFieldCount) {
277 if (mComponent.isReference()) {
278 ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
279 ObjectBase *ob = obp[0];
Jason Sams10e5e572010-08-12 12:44:02 -0700280 if (ob) ob->decSysRef();
Jason Samse3929c92010-08-09 18:13:33 -0700281 }
282 return;
283 }
284
285 const uint8_t *p = static_cast<const uint8_t *>(ptr);
286 for (uint32_t i=0; i < mFieldCount; i++) {
287 if (mFields[i].e->mHasReference) {
Jason Sams46e45542010-09-02 17:35:23 -0700288 p = &p[mFields[i].offsetBits >> 3];
289 for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
290 mFields[i].e->decRefs(p);
291 p += mFields[i].e->getSizeBytes();
292 }
Jason Samse3929c92010-08-09 18:13:33 -0700293 }
294 }
295}
Jason Samsd01d9702009-12-23 14:35:29 -0800296
Jason Sams4815c0d2009-12-15 12:58:36 -0800297
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800298ElementState::ElementState() {
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700299 const uint32_t initialCapacity = 32;
300 mBuilderElements.setCapacity(initialCapacity);
301 mBuilderNameStrings.setCapacity(initialCapacity);
302 mBuilderNameLengths.setCapacity(initialCapacity);
303 mBuilderArrays.setCapacity(initialCapacity);
Jason Sams326e0dd2009-05-22 14:03:28 -0700304}
305
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800306ElementState::~ElementState() {
Jason Sams81549542010-02-17 15:38:10 -0800307 rsAssert(!mElements.size());
Jason Sams326e0dd2009-05-22 14:03:28 -0700308}
309
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700310void ElementState::elementBuilderBegin() {
311 mBuilderElements.clear();
312 mBuilderNameStrings.clear();
313 mBuilderNameLengths.clear();
314 mBuilderArrays.clear();
315}
316
317void ElementState::elementBuilderAdd(const Element *e, const char *nameStr, uint32_t arraySize) {
318 mBuilderElements.push(e);
319 mBuilderNameStrings.push(nameStr);
320 mBuilderNameLengths.push(strlen(nameStr));
321 mBuilderArrays.push(arraySize);
322
323}
324
325const Element *ElementState::elementBuilderCreate(Context *rsc) {
326 return Element::create(rsc, mBuilderElements.size(),
327 &(mBuilderElements.editArray()[0]),
328 &(mBuilderNameStrings.editArray()[0]),
329 mBuilderNameLengths.editArray(),
330 mBuilderArrays.editArray());
331}
332
Jason Sams4815c0d2009-12-15 12:58:36 -0800333
Jason Sams326e0dd2009-05-22 14:03:28 -0700334/////////////////////////////////////////
Jason Samse5ffb872009-08-09 17:01:55 -0700335//
Jason Sams326e0dd2009-05-22 14:03:28 -0700336
337namespace android {
338namespace renderscript {
339
Jason Samsd01d9702009-12-23 14:35:29 -0800340RsElement rsi_ElementCreate(Context *rsc,
341 RsDataType dt,
342 RsDataKind dk,
343 bool norm,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800344 uint32_t vecSize) {
Jason Sams81549542010-02-17 15:38:10 -0800345 const Element *e = Element::create(rsc, dt, dk, norm, vecSize);
Jason Samsd01d9702009-12-23 14:35:29 -0800346 e->incUserRef();
Jason Sams81549542010-02-17 15:38:10 -0800347 return (RsElement)e;
Jason Sams326e0dd2009-05-22 14:03:28 -0700348}
349
Jason Samsd01d9702009-12-23 14:35:29 -0800350RsElement rsi_ElementCreate2(Context *rsc,
Jason Samsd01d9702009-12-23 14:35:29 -0800351 const RsElement * ein,
Alex Sakhartchouk70b83c12011-04-06 10:57:51 -0700352 size_t ein_length,
Jason Samsd01d9702009-12-23 14:35:29 -0800353 const char ** names,
Alex Sakhartchouk70b83c12011-04-06 10:57:51 -0700354 size_t names_length,
Jason Sams46e45542010-09-02 17:35:23 -0700355 const size_t * nameLengths,
Alex Sakhartchouk70b83c12011-04-06 10:57:51 -0700356 size_t nameLengths_length,
357 const uint32_t * arraySizes,
358 size_t arraySizes_length) {
359 const Element *e = Element::create(rsc, ein_length, (const Element **)ein, names, nameLengths, arraySizes);
Jason Samsd01d9702009-12-23 14:35:29 -0800360 e->incUserRef();
Jason Sams81549542010-02-17 15:38:10 -0800361 return (RsElement)e;
Jason Samsd01d9702009-12-23 14:35:29 -0800362}
363
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700364}
365}
366
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800367void rsaElementGetNativeData(RsContext con, RsElement elem, uint32_t *elemData, uint32_t elemDataSize) {
Alex Sakhartchouk417e6a42010-07-15 11:33:03 -0700368 rsAssert(elemDataSize == 5);
369 // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
370 Element *e = static_cast<Element *>(elem);
371
372 (*elemData++) = (uint32_t)e->getType();
373 (*elemData++) = (uint32_t)e->getKind();
374 (*elemData++) = e->getComponent().getIsNormalized() ? 1 : 0;
375 (*elemData++) = e->getComponent().getVectorSize();
376 (*elemData++) = e->getFieldCount();
Alex Sakhartchouk417e6a42010-07-15 11:33:03 -0700377}
378
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800379void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids, const char **names, uint32_t dataSize) {
Alex Sakhartchouk417e6a42010-07-15 11:33:03 -0700380 Element *e = static_cast<Element *>(elem);
381 rsAssert(e->getFieldCount() == dataSize);
382
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800383 for (uint32_t i = 0; i < dataSize; i ++) {
Jason Samsf0c1df42010-10-26 13:09:17 -0700384 e->getField(i)->incUserRef();
Alex Sakhartchouk417e6a42010-07-15 11:33:03 -0700385 ids[i] = (uint32_t)e->getField(i);
386 names[i] = e->getFieldName(i);
387 }
Alex Sakhartchouk417e6a42010-07-15 11:33:03 -0700388}