blob: 2602dd4d1ae8ab037761981bf759a3d0e8d35660 [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#ifndef ANDROID_RS_BUILD_FOR_HOST
19#include "rsContext.h"
Jason Sams565ac362009-06-03 16:04:54 -070020#include <GLES/gl.h>
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070021#else
22#include "rsContextHostStub.h"
23#include <OpenGL/gl.h>
24#endif
Jason Sams565ac362009-06-03 16:04:54 -070025
Jason Sams326e0dd2009-05-22 14:03:28 -070026using namespace android;
27using namespace android::renderscript;
28
Jason Sams326e0dd2009-05-22 14:03:28 -070029
Jason Samse514b452009-09-25 14:51:22 -070030Element::Element(Context *rsc) : ObjectBase(rsc)
Jason Sams326e0dd2009-05-22 14:03:28 -070031{
Jason Sams4815c0d2009-12-15 12:58:36 -080032 mBits = 0;
Jason Samsf2649a92009-09-25 16:37:33 -070033 mAllocFile = __FILE__;
34 mAllocLine = __LINE__;
Jason Sams4815c0d2009-12-15 12:58:36 -080035 mFields = NULL;
36 mFieldCount = 0;
Jason Samse3929c92010-08-09 18:13:33 -070037 mHasReference = false;
Jason Sams326e0dd2009-05-22 14:03:28 -070038}
39
Jason Sams326e0dd2009-05-22 14:03:28 -070040
41Element::~Element()
42{
Jason Sams81549542010-02-17 15:38:10 -080043 for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) {
44 if (mRSC->mStateElement.mElements[ct] == this) {
45 mRSC->mStateElement.mElements.removeAt(ct);
46 break;
47 }
48 }
Jason Sams326e0dd2009-05-22 14:03:28 -070049 clear();
50}
51
52void Element::clear()
53{
Jason Sams4815c0d2009-12-15 12:58:36 -080054 delete [] mFields;
55 mFields = NULL;
56 mFieldCount = 0;
Jason Samse3929c92010-08-09 18:13:33 -070057 mHasReference = false;
Jason Sams326e0dd2009-05-22 14:03:28 -070058}
Jason Sams326e0dd2009-05-22 14:03:28 -070059
60size_t Element::getSizeBits() const
61{
Jason Sams4815c0d2009-12-15 12:58:36 -080062 if (!mFieldCount) {
63 return mBits;
64 }
65
Jason Sams326e0dd2009-05-22 14:03:28 -070066 size_t total = 0;
Jason Sams4815c0d2009-12-15 12:58:36 -080067 for (size_t ct=0; ct < mFieldCount; ct++) {
68 total += mFields[ct].e->mBits;
Jason Sams326e0dd2009-05-22 14:03:28 -070069 }
70 return total;
71}
72
Jason Samse12c1c52009-09-27 17:50:38 -070073void Element::dumpLOGV(const char *prefix) const
74{
75 ObjectBase::dumpLOGV(prefix);
Jason Sams4815c0d2009-12-15 12:58:36 -080076 LOGV("%s Element: components %i, size %i", prefix, mFieldCount, mBits);
77 for (uint32_t ct = 0; ct < mFieldCount; ct++) {
Jason Samse12c1c52009-09-27 17:50:38 -070078 char buf[1024];
79 sprintf(buf, "%s component %i: ", prefix, ct);
Jason Sams4815c0d2009-12-15 12:58:36 -080080 //mComponents[ct]->dumpLOGV(buf);
Jason Samse12c1c52009-09-27 17:50:38 -070081 }
82}
83
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070084void Element::serialize(OStream *stream) const
85{
86 // Need to identify ourselves
87 stream->addU32((uint32_t)getClassId());
88
89 String8 name(getName());
90 stream->addString(&name);
91
92 mComponent.serialize(stream);
93
94 // Now serialize all the fields
95 stream->addU32(mFieldCount);
96 for(uint32_t ct = 0; ct < mFieldCount; ct++) {
97 stream->addString(&mFields[ct].name);
98 mFields[ct].e->serialize(stream);
99 }
100}
101
102Element *Element::createFromStream(Context *rsc, IStream *stream)
103{
104 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700105 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
106 if(classID != RS_A3D_CLASS_ID_ELEMENT) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700107 LOGE("element loading skipped due to invalid class id\n");
108 return NULL;
109 }
110
111 String8 name;
112 stream->loadString(&name);
113
114 Element *elem = new Element(rsc);
115 elem->mComponent.loadFromStream(stream);
116 elem->mBits = elem->mComponent.getBits();
Alex Sakhartchouke6d9fbc2010-08-11 10:30:44 -0700117 elem->mHasReference = elem->mComponent.isReference();
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700118
119 elem->mFieldCount = stream->loadU32();
120 if(elem->mFieldCount) {
Jason Samse3929c92010-08-09 18:13:33 -0700121 uint32_t offset = 0;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700122 elem->mFields = new ElementField_t [elem->mFieldCount];
123 for(uint32_t ct = 0; ct < elem->mFieldCount; ct ++) {
124 stream->loadString(&elem->mFields[ct].name);
125 Element *fieldElem = Element::createFromStream(rsc, stream);
126 elem->mFields[ct].e.set(fieldElem);
Jason Samse3929c92010-08-09 18:13:33 -0700127 elem->mFields[ct].offsetBits = offset;
128 offset += fieldElem->getSizeBits();
Alex Sakhartchouke6d9fbc2010-08-11 10:30:44 -0700129 // Check if our sub-elements have references
130 if(fieldElem->mHasReference) {
131 elem->mHasReference = true;
132 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700133 }
134 }
135
136 // We need to check if this already exists
137 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
138 Element *ee = rsc->mStateElement.mElements[ct];
139
140 if (!ee->getFieldCount() ) {
141
142 if((ee->getComponent().getType() == elem->getComponent().getType()) &&
143 (ee->getComponent().getKind() == elem->getComponent().getKind()) &&
144 (ee->getComponent().getIsNormalized() == elem->getComponent().getIsNormalized()) &&
145 (ee->getComponent().getVectorSize() == elem->getComponent().getVectorSize())) {
146 // Match
147 delete elem;
148 ee->incUserRef();
149 return ee;
150 }
151
152 } else if (ee->getFieldCount() == elem->mFieldCount) {
153
154 bool match = true;
155 for (uint32_t i=0; i < elem->mFieldCount; i++) {
156 if ((ee->mFields[i].e.get() != elem->mFields[i].e.get()) ||
157 (ee->mFields[i].name.length() != elem->mFields[i].name.length()) ||
158 (ee->mFields[i].name != elem->mFields[i].name)) {
159 match = false;
160 break;
161 }
162 }
163 if (match) {
164 delete elem;
165 ee->incUserRef();
166 return ee;
167 }
168
169 }
170 }
171
172 rsc->mStateElement.mElements.push(elem);
173 return elem;
174}
175
Jason Samsd01d9702009-12-23 14:35:29 -0800176
Jason Sams81549542010-02-17 15:38:10 -0800177const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
Jason Samsd01d9702009-12-23 14:35:29 -0800178 bool isNorm, uint32_t vecSize)
Jason Sams4815c0d2009-12-15 12:58:36 -0800179{
Jason Sams81549542010-02-17 15:38:10 -0800180 // Look for an existing match.
181 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
182 const Element *ee = rsc->mStateElement.mElements[ct];
183 if (!ee->getFieldCount() &&
184 (ee->getComponent().getType() == dt) &&
185 (ee->getComponent().getKind() == dk) &&
186 (ee->getComponent().getIsNormalized() == isNorm) &&
187 (ee->getComponent().getVectorSize() == vecSize)) {
188 // Match
189 ee->incUserRef();
190 return ee;
191 }
192 }
193
Jason Sams4815c0d2009-12-15 12:58:36 -0800194 Element *e = new Element(rsc);
Jason Samsd01d9702009-12-23 14:35:29 -0800195 e->mComponent.set(dt, dk, isNorm, vecSize);
196 e->mBits = e->mComponent.getBits();
Jason Samse3929c92010-08-09 18:13:33 -0700197 e->mHasReference = e->mComponent.isReference();
Jason Sams81549542010-02-17 15:38:10 -0800198 rsc->mStateElement.mElements.push(e);
Jason Sams4815c0d2009-12-15 12:58:36 -0800199 return e;
200}
201
Jason Sams81549542010-02-17 15:38:10 -0800202const Element * Element::create(Context *rsc, size_t count, const Element **ein,
Jason Samsd01d9702009-12-23 14:35:29 -0800203 const char **nin, const size_t * lengths)
Jason Sams4815c0d2009-12-15 12:58:36 -0800204{
Jason Sams81549542010-02-17 15:38:10 -0800205 // Look for an existing match.
206 for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
207 const Element *ee = rsc->mStateElement.mElements[ct];
208 if (ee->getFieldCount() == count) {
209 bool match = true;
210 for (uint32_t i=0; i < count; i++) {
211 if ((ee->mFields[i].e.get() != ein[i]) ||
212 (ee->mFields[i].name.length() != lengths[i]) ||
213 (ee->mFields[i].name != nin[i])) {
214 match = false;
215 break;
216 }
217 }
218 if (match) {
219 ee->incUserRef();
220 return ee;
221 }
222 }
223 }
224
Jason Sams4815c0d2009-12-15 12:58:36 -0800225 Element *e = new Element(rsc);
226 e->mFields = new ElementField_t [count];
227 e->mFieldCount = count;
Jason Samse3929c92010-08-09 18:13:33 -0700228 size_t bits = 0;
Jason Sams4815c0d2009-12-15 12:58:36 -0800229 for (size_t ct=0; ct < count; ct++) {
230 e->mFields[ct].e.set(ein[ct]);
231 e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
Jason Samse3929c92010-08-09 18:13:33 -0700232 e->mFields[ct].offsetBits = bits;
233 bits += ein[ct]->getSizeBits();
234
235 if (ein[ct]->mHasReference) {
236 e->mHasReference = true;
237 }
Jason Sams4815c0d2009-12-15 12:58:36 -0800238 }
239
Jason Sams81549542010-02-17 15:38:10 -0800240 rsc->mStateElement.mElements.push(e);
Jason Sams4815c0d2009-12-15 12:58:36 -0800241 return e;
242}
243
Jason Samsb4d35682010-01-04 16:52:27 -0800244String8 Element::getGLSLType(uint32_t indent) const
245{
246 String8 s;
247 for (uint32_t ct=0; ct < indent; ct++) {
248 s.append(" ");
249 }
250
251 if (!mFieldCount) {
252 // Basic component.
253 s.append(mComponent.getGLSLType());
254 } else {
255 rsAssert(0);
256 //s.append("struct ");
257 //s.append(getCStructBody(indent));
258 }
259
260 return s;
261}
Jason Samsd01d9702009-12-23 14:35:29 -0800262
Jason Samse3929c92010-08-09 18:13:33 -0700263void Element::incRefs(const void *ptr) const
264{
265 if (!mFieldCount) {
266 if (mComponent.isReference()) {
267 ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
268 ObjectBase *ob = obp[0];
Jason Sams10e5e572010-08-12 12:44:02 -0700269 if (ob) ob->incSysRef();
Jason Samse3929c92010-08-09 18:13:33 -0700270 }
271 return;
272 }
273
274 const uint8_t *p = static_cast<const uint8_t *>(ptr);
275 for (uint32_t i=0; i < mFieldCount; i++) {
276 if (mFields[i].e->mHasReference) {
277 mFields[i].e->incRefs(&p[mFields[i].offsetBits >> 3]);
278 }
279 }
280}
281
282void Element::decRefs(const void *ptr) const
283{
284 if (!mFieldCount) {
285 if (mComponent.isReference()) {
286 ObjectBase *const*obp = static_cast<ObjectBase *const*>(ptr);
287 ObjectBase *ob = obp[0];
Jason Sams10e5e572010-08-12 12:44:02 -0700288 if (ob) ob->decSysRef();
Jason Samse3929c92010-08-09 18:13:33 -0700289 }
290 return;
291 }
292
293 const uint8_t *p = static_cast<const uint8_t *>(ptr);
294 for (uint32_t i=0; i < mFieldCount; i++) {
295 if (mFields[i].e->mHasReference) {
296 mFields[i].e->decRefs(&p[mFields[i].offsetBits >> 3]);
297 }
298 }
299}
Jason Samsd01d9702009-12-23 14:35:29 -0800300
Jason Sams4815c0d2009-12-15 12:58:36 -0800301
Jason Sams326e0dd2009-05-22 14:03:28 -0700302ElementState::ElementState()
303{
304}
305
306ElementState::~ElementState()
307{
Jason Sams81549542010-02-17 15:38:10 -0800308 rsAssert(!mElements.size());
Jason Sams326e0dd2009-05-22 14:03:28 -0700309}
310
Jason Sams4815c0d2009-12-15 12:58:36 -0800311
Jason Sams326e0dd2009-05-22 14:03:28 -0700312/////////////////////////////////////////
Jason Samse5ffb872009-08-09 17:01:55 -0700313//
Jason Sams326e0dd2009-05-22 14:03:28 -0700314
315namespace android {
316namespace renderscript {
317
Jason Samsd01d9702009-12-23 14:35:29 -0800318RsElement rsi_ElementCreate(Context *rsc,
319 RsDataType dt,
320 RsDataKind dk,
321 bool norm,
322 uint32_t vecSize)
Jason Sams326e0dd2009-05-22 14:03:28 -0700323{
Jason Samsd01d9702009-12-23 14:35:29 -0800324 //LOGE("rsi_ElementCreate %i %i %i %i", dt, dk, norm, vecSize);
Jason Sams81549542010-02-17 15:38:10 -0800325 const Element *e = Element::create(rsc, dt, dk, norm, vecSize);
Jason Samsd01d9702009-12-23 14:35:29 -0800326 e->incUserRef();
Jason Sams81549542010-02-17 15:38:10 -0800327 return (RsElement)e;
Jason Sams326e0dd2009-05-22 14:03:28 -0700328}
329
Jason Samsd01d9702009-12-23 14:35:29 -0800330RsElement rsi_ElementCreate2(Context *rsc,
331 size_t count,
332 const RsElement * ein,
333 const char ** names,
334 const size_t * nameLengths)
335{
336 //LOGE("rsi_ElementCreate2 %i", count);
Jason Sams81549542010-02-17 15:38:10 -0800337 const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths);
Jason Samsd01d9702009-12-23 14:35:29 -0800338 e->incUserRef();
Jason Sams81549542010-02-17 15:38:10 -0800339 return (RsElement)e;
Jason Samsd01d9702009-12-23 14:35:29 -0800340}
341
Alex Sakhartchouk417e6a42010-07-15 11:33:03 -0700342void rsi_ElementGetNativeData(Context *rsc, RsElement elem, uint32_t *elemData, uint32_t elemDataSize)
343{
344 rsAssert(elemDataSize == 5);
345 // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
346 Element *e = static_cast<Element *>(elem);
347
348 (*elemData++) = (uint32_t)e->getType();
349 (*elemData++) = (uint32_t)e->getKind();
350 (*elemData++) = e->getComponent().getIsNormalized() ? 1 : 0;
351 (*elemData++) = e->getComponent().getVectorSize();
352 (*elemData++) = e->getFieldCount();
353
354}
355
356void rsi_ElementGetSubElements(Context *rsc, RsElement elem, uint32_t *ids, const char **names, uint32_t dataSize)
357{
358 Element *e = static_cast<Element *>(elem);
359 rsAssert(e->getFieldCount() == dataSize);
360
361 for(uint32_t i = 0; i < dataSize; i ++) {
362 ids[i] = (uint32_t)e->getField(i);
363 names[i] = e->getFieldName(i);
364 }
365
366}
367
Jason Sams326e0dd2009-05-22 14:03:28 -0700368
369}
370}