blob: 79cfd412c1453f48bafc9e2c3e4b7a1dc7f613d5 [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
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070017#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Sams326e0dd2009-05-22 14:03:28 -070018#include "rsContext.h"
Jason Samse5ffb872009-08-09 17:01:55 -070019#include <GLES/gl.h>
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070020#else
21#include "rsContextHostStub.h"
22#include <OpenGL/gl.h>
23#endif
Jason Sams326e0dd2009-05-22 14:03:28 -070024
25using namespace android;
26using namespace android::renderscript;
27
Jason Samse514b452009-09-25 14:51:22 -070028Type::Type(Context *rsc) : ObjectBase(rsc)
Jason Sams326e0dd2009-05-22 14:03:28 -070029{
Jason Samsf2649a92009-09-25 16:37:33 -070030 mAllocFile = __FILE__;
31 mAllocLine = __LINE__;
Jason Sams326e0dd2009-05-22 14:03:28 -070032 mLODs = 0;
33 mLODCount = 0;
34 clear();
35}
36
37Type::~Type()
38{
Jason Sams81549542010-02-17 15:38:10 -080039 for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
40 if (mRSC->mStateType.mTypes[ct] == this) {
41 mRSC->mStateType.mTypes.removeAt(ct);
42 break;
43 }
44 }
Jason Sams326e0dd2009-05-22 14:03:28 -070045 if (mLODs) {
46 delete [] mLODs;
47 }
48}
49
50void Type::clear()
51{
52 if (mLODs) {
53 delete [] mLODs;
54 mLODs = NULL;
55 }
56 mDimX = 0;
57 mDimY = 0;
58 mDimZ = 0;
59 mDimLOD = 0;
60 mFaces = false;
61 mElement.clear();
62}
63
64TypeState::TypeState()
65{
66}
67
68TypeState::~TypeState()
69{
70}
71
72size_t Type::getOffsetForFace(uint32_t face) const
73{
74 rsAssert(mFaces);
75 return 0;
76}
77
78void Type::compute()
79{
Jason Sams326e0dd2009-05-22 14:03:28 -070080 uint32_t oldLODCount = mLODCount;
81 if (mDimLOD) {
82 uint32_t l2x = rsFindHighBit(mDimX) + 1;
83 uint32_t l2y = rsFindHighBit(mDimY) + 1;
84 uint32_t l2z = rsFindHighBit(mDimZ) + 1;
85
86 mLODCount = rsMax(l2x, l2y);
87 mLODCount = rsMax(mLODCount, l2z);
88 } else {
89 mLODCount = 1;
90 }
91 if (mLODCount != oldLODCount) {
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -070092 if(mLODs){
93 delete [] mLODs;
Alex Sakhartchouk417e6a42010-07-15 11:33:03 -070094 }
Jason Sams326e0dd2009-05-22 14:03:28 -070095 mLODs = new LOD[mLODCount];
96 }
97
Jason Sams326e0dd2009-05-22 14:03:28 -070098 uint32_t tx = mDimX;
99 uint32_t ty = mDimY;
100 uint32_t tz = mDimZ;
101 size_t offset = 0;
102 for (uint32_t lod=0; lod < mLODCount; lod++) {
103 mLODs[lod].mX = tx;
104 mLODs[lod].mY = ty;
105 mLODs[lod].mZ = tz;
106 mLODs[lod].mOffset = offset;
Jason Sams326e0dd2009-05-22 14:03:28 -0700107 offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
Jason Sams7c528982010-01-07 16:25:08 -0800108 if (tx > 1) tx >>= 1;
109 if (ty > 1) ty >>= 1;
110 if (tz > 1) tz >>= 1;
Jason Sams326e0dd2009-05-22 14:03:28 -0700111 }
112
Jason Sams326e0dd2009-05-22 14:03:28 -0700113 // At this point the offset is the size of a mipmap chain;
114 mMipChainSizeBytes = offset;
115
116 if (mFaces) {
117 offset *= 6;
118 }
119 mTotalSizeBytes = offset;
120
Jason Samse5ffb872009-08-09 17:01:55 -0700121 makeGLComponents();
Jason Sams326e0dd2009-05-22 14:03:28 -0700122}
123
124uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const
125{
126 uint32_t offset = mLODs[lod].mOffset;
127 offset += x * mElement->getSizeBytes();
128 return offset;
129}
130
131uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const
132{
133 uint32_t offset = mLODs[lod].mOffset;
134 offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
135 return offset;
136}
137
138uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const
139{
140 uint32_t offset = mLODs[lod].mOffset;
141 offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
142 return offset;
143}
144
145
Jason Samse5ffb872009-08-09 17:01:55 -0700146void Type::makeGLComponents()
147{
Alex Sakhartchouk032f3592010-07-20 10:59:25 -0700148 if(getElement()->getFieldCount() >= RS_MAX_ATTRIBS) {
149 return;
150 }
151
Jason Sams433eca32010-01-06 11:57:52 -0800152 uint32_t userNum = 0;
Jason Samse5ffb872009-08-09 17:01:55 -0700153
Jason Sams4815c0d2009-12-15 12:58:36 -0800154 for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
Jason Samsd01d9702009-12-23 14:35:29 -0800155 const Component &c = getElement()->getField(ct)->getComponent();
Jason Samse5ffb872009-08-09 17:01:55 -0700156
Jason Sams79f52df2010-06-01 15:47:01 -0700157 mAttribs[userNum].size = c.getVectorSize();
158 mAttribs[userNum].offset = mElement->getFieldOffsetBytes(ct);
159 mAttribs[userNum].type = c.getGLType();
160 mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
161 mAttribs[userNum].name.setTo(getElement()->getFieldName(ct));
162 userNum ++;
Jason Samse5ffb872009-08-09 17:01:55 -0700163 }
164}
165
Jason Sams79f52df2010-06-01 15:47:01 -0700166
Jason Samsc460e552009-11-25 13:22:07 -0800167void Type::enableGLVertexBuffer(VertexArray *va) const
Jason Samse5ffb872009-08-09 17:01:55 -0700168{
Jason Sams433eca32010-01-06 11:57:52 -0800169 uint32_t stride = mElement->getSizeBytes();
170 for (uint32_t ct=0; ct < RS_MAX_ATTRIBS; ct++) {
Jason Sams79f52df2010-06-01 15:47:01 -0700171 if (mAttribs[ct].size) {
172 va->add(mAttribs[ct], stride);
Jason Sams433eca32010-01-06 11:57:52 -0800173 }
174 }
175}
176
177
Jason Samse5ffb872009-08-09 17:01:55 -0700178
Jason Samse12c1c52009-09-27 17:50:38 -0700179void Type::dumpLOGV(const char *prefix) const
180{
181 char buf[1024];
182 ObjectBase::dumpLOGV(prefix);
183 LOGV("%s Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
184 sprintf(buf, "%s element: ", prefix);
185 mElement->dumpLOGV(buf);
186}
187
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700188void Type::serialize(OStream *stream) const
189{
190 // Need to identify ourselves
191 stream->addU32((uint32_t)getClassId());
192
193 String8 name(getName());
194 stream->addString(&name);
195
196 mElement->serialize(stream);
197
198 stream->addU32(mDimX);
199 stream->addU32(mDimY);
200 stream->addU32(mDimZ);
201
202 stream->addU8((uint8_t)(mDimLOD ? 1 : 0));
203 stream->addU8((uint8_t)(mFaces ? 1 : 0));
204}
205
206Type *Type::createFromStream(Context *rsc, IStream *stream)
207{
208 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700209 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
210 if(classID != RS_A3D_CLASS_ID_TYPE) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700211 LOGE("type loading skipped due to invalid class id\n");
212 return NULL;
213 }
214
215 String8 name;
216 stream->loadString(&name);
217
218 Element *elem = Element::createFromStream(rsc, stream);
219 if(!elem) {
220 return NULL;
221 }
222
223 Type *type = new Type(rsc);
224 type->mDimX = stream->loadU32();
225 type->mDimY = stream->loadU32();
226 type->mDimZ = stream->loadU32();
227
228 uint8_t temp = stream->loadU8();
229 type->mDimLOD = temp != 0;
230
231 temp = stream->loadU8();
232 type->mFaces = temp != 0;
233
234 type->setElement(elem);
235
236 return type;
237}
238
Jason Samsef21edc2010-02-22 15:37:51 -0800239bool Type::getIsNp2() const
240{
241 uint32_t x = getDimX();
242 uint32_t y = getDimY();
243 uint32_t z = getDimZ();
244
245 if (x && (x & (x-1))) {
246 return true;
247 }
248 if (y && (y & (y-1))) {
249 return true;
250 }
251 if (z && (z & (z-1))) {
252 return true;
253 }
254 return false;
255}
256
Jason Samse12c1c52009-09-27 17:50:38 -0700257
Jason Sams326e0dd2009-05-22 14:03:28 -0700258//////////////////////////////////////////////////
Jason Samse5ffb872009-08-09 17:01:55 -0700259//
Jason Sams326e0dd2009-05-22 14:03:28 -0700260namespace android {
261namespace renderscript {
262
263void rsi_TypeBegin(Context *rsc, RsElement vse)
264{
265 TypeState * stc = &rsc->mStateType;
266
267 stc->mX = 0;
268 stc->mY = 0;
269 stc->mZ = 0;
270 stc->mLOD = false;
271 stc->mFaces = false;
272 stc->mElement.set(static_cast<const Element *>(vse));
273}
274
275void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value)
276{
277 TypeState * stc = &rsc->mStateType;
278
279 if (dim < 0) {
280 //error
281 return;
282 }
283
284
285 switch (dim) {
286 case RS_DIMENSION_X:
287 stc->mX = value;
288 return;
289 case RS_DIMENSION_Y:
290 stc->mY = value;
291 return;
292 case RS_DIMENSION_Z:
293 stc->mZ = value;
294 return;
295 case RS_DIMENSION_FACE:
296 stc->mFaces = (value != 0);
297 return;
298 case RS_DIMENSION_LOD:
299 stc->mLOD = (value != 0);
300 return;
301 default:
302 break;
303 }
304
305
306 int32_t arrayNum = dim - RS_DIMENSION_ARRAY_0;
307 if ((dim < 0) || (dim > RS_DIMENSION_MAX)) {
308 LOGE("rsTypeAdd: Bad dimension");
309 //error
310 return;
311 }
312
313 // todo: implement array support
314
315}
316
317RsType rsi_TypeCreate(Context *rsc)
318{
319 TypeState * stc = &rsc->mStateType;
320
Jason Sams81549542010-02-17 15:38:10 -0800321 for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
322 Type *t = stc->mTypes[ct];
323 if (t->getElement() != stc->mElement.get()) continue;
324 if (t->getDimX() != stc->mX) continue;
325 if (t->getDimY() != stc->mY) continue;
326 if (t->getDimZ() != stc->mZ) continue;
327 if (t->getDimLOD() != stc->mLOD) continue;
328 if (t->getDimFaces() != stc->mFaces) continue;
329 t->incUserRef();
330 return t;
331 }
332
Jason Samse514b452009-09-25 14:51:22 -0700333 Type * st = new Type(rsc);
Jason Sams9397e302009-08-27 20:23:34 -0700334 st->incUserRef();
Jason Sams326e0dd2009-05-22 14:03:28 -0700335 st->setDimX(stc->mX);
336 st->setDimY(stc->mY);
337 st->setDimZ(stc->mZ);
338 st->setElement(stc->mElement.get());
339 st->setDimLOD(stc->mLOD);
340 st->setDimFaces(stc->mFaces);
341 st->compute();
Jason Sams83128012009-09-25 16:50:36 -0700342 stc->mElement.clear();
Jason Sams81549542010-02-17 15:38:10 -0800343 stc->mTypes.push(st);
Jason Sams326e0dd2009-05-22 14:03:28 -0700344 return st;
345}
346
Alex Sakhartchouk417e6a42010-07-15 11:33:03 -0700347void rsi_TypeGetNativeData(Context *rsc, RsType type, uint32_t *typeData, uint32_t typeDataSize)
348{
349 rsAssert(typeDataSize == 6);
350 // Pack the data in the follofing way mDimX; mDimY; mDimZ;
351 // mDimLOD; mDimFaces; mElement; into typeData
352 Type *t = static_cast<Type *>(type);
353
354 (*typeData++) = t->getDimX();
355 (*typeData++) = t->getDimY();
356 (*typeData++) = t->getDimZ();
357 (*typeData++) = t->getDimLOD();
358 (*typeData++) = t->getDimFaces() ? 1 : 0;
359 (*typeData++) = (uint32_t)t->getElement();
360
361}
362
Jason Sams326e0dd2009-05-22 14:03:28 -0700363
364}
365}
366