blob: c09e9798c64b0b3b26aa20cc2dd87286deded093 [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
17#include "rsContext.h"
Jason Samse5ffb872009-08-09 17:01:55 -070018#include <GLES/gl.h>
Jason Sams326e0dd2009-05-22 14:03:28 -070019
20using namespace android;
21using namespace android::renderscript;
22
Jason Samse514b452009-09-25 14:51:22 -070023Type::Type(Context *rsc) : ObjectBase(rsc)
Jason Sams326e0dd2009-05-22 14:03:28 -070024{
Jason Samsf2649a92009-09-25 16:37:33 -070025 mAllocFile = __FILE__;
26 mAllocLine = __LINE__;
Jason Sams326e0dd2009-05-22 14:03:28 -070027 mLODs = 0;
28 mLODCount = 0;
29 clear();
30}
31
32Type::~Type()
33{
Jason Sams81549542010-02-17 15:38:10 -080034 for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
35 if (mRSC->mStateType.mTypes[ct] == this) {
36 mRSC->mStateType.mTypes.removeAt(ct);
37 break;
38 }
39 }
Jason Sams326e0dd2009-05-22 14:03:28 -070040 if (mLODs) {
41 delete [] mLODs;
42 }
43}
44
45void Type::clear()
46{
47 if (mLODs) {
48 delete [] mLODs;
49 mLODs = NULL;
50 }
51 mDimX = 0;
52 mDimY = 0;
53 mDimZ = 0;
54 mDimLOD = 0;
55 mFaces = false;
56 mElement.clear();
57}
58
59TypeState::TypeState()
60{
61}
62
63TypeState::~TypeState()
64{
65}
66
67size_t Type::getOffsetForFace(uint32_t face) const
68{
69 rsAssert(mFaces);
70 return 0;
71}
72
73void Type::compute()
74{
Jason Sams326e0dd2009-05-22 14:03:28 -070075 uint32_t oldLODCount = mLODCount;
76 if (mDimLOD) {
77 uint32_t l2x = rsFindHighBit(mDimX) + 1;
78 uint32_t l2y = rsFindHighBit(mDimY) + 1;
79 uint32_t l2z = rsFindHighBit(mDimZ) + 1;
80
81 mLODCount = rsMax(l2x, l2y);
82 mLODCount = rsMax(mLODCount, l2z);
83 } else {
84 mLODCount = 1;
85 }
86 if (mLODCount != oldLODCount) {
87 delete [] mLODs;
88 mLODs = new LOD[mLODCount];
89 }
90
Jason Sams326e0dd2009-05-22 14:03:28 -070091 uint32_t tx = mDimX;
92 uint32_t ty = mDimY;
93 uint32_t tz = mDimZ;
94 size_t offset = 0;
95 for (uint32_t lod=0; lod < mLODCount; lod++) {
96 mLODs[lod].mX = tx;
97 mLODs[lod].mY = ty;
98 mLODs[lod].mZ = tz;
99 mLODs[lod].mOffset = offset;
Jason Sams326e0dd2009-05-22 14:03:28 -0700100 offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
Jason Sams7c528982010-01-07 16:25:08 -0800101 if (tx > 1) tx >>= 1;
102 if (ty > 1) ty >>= 1;
103 if (tz > 1) tz >>= 1;
Jason Sams326e0dd2009-05-22 14:03:28 -0700104 }
105
Jason Sams326e0dd2009-05-22 14:03:28 -0700106 // At this point the offset is the size of a mipmap chain;
107 mMipChainSizeBytes = offset;
108
109 if (mFaces) {
110 offset *= 6;
111 }
112 mTotalSizeBytes = offset;
113
Jason Samse5ffb872009-08-09 17:01:55 -0700114 makeGLComponents();
Jason Sams326e0dd2009-05-22 14:03:28 -0700115}
116
117uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const
118{
119 uint32_t offset = mLODs[lod].mOffset;
120 offset += x * mElement->getSizeBytes();
121 return offset;
122}
123
124uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const
125{
126 uint32_t offset = mLODs[lod].mOffset;
127 offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
128 return offset;
129}
130
131uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const
132{
133 uint32_t offset = mLODs[lod].mOffset;
134 offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
135 return offset;
136}
137
138
Jason Samse5ffb872009-08-09 17:01:55 -0700139void Type::makeGLComponents()
140{
Jason Sams433eca32010-01-06 11:57:52 -0800141 uint32_t userNum = 0;
Jason Samse5ffb872009-08-09 17:01:55 -0700142
Jason Sams4815c0d2009-12-15 12:58:36 -0800143 for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
Jason Samsd01d9702009-12-23 14:35:29 -0800144 const Component &c = getElement()->getField(ct)->getComponent();
Jason Samse5ffb872009-08-09 17:01:55 -0700145
Jason Samsd01d9702009-12-23 14:35:29 -0800146 switch(c.getKind()) {
Jason Sams433eca32010-01-06 11:57:52 -0800147 case RS_KIND_USER:
148 mGL.mUser[userNum].size = c.getVectorSize();
149 mGL.mUser[userNum].offset = mElement->getFieldOffsetBytes(ct);
150 mGL.mUser[userNum].type = c.getGLType();
151 mGL.mUser[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
152 mGL.mUser[userNum].name.setTo(getElement()->getFieldName(ct));
153 userNum ++;
154 break;
155
Jason Samsd01d9702009-12-23 14:35:29 -0800156 case RS_KIND_POSITION:
Jason Samse5ffb872009-08-09 17:01:55 -0700157 rsAssert(mGL.mVtx.size == 0);
Jason Samsd01d9702009-12-23 14:35:29 -0800158 mGL.mVtx.size = c.getVectorSize();
Jason Sams4815c0d2009-12-15 12:58:36 -0800159 mGL.mVtx.offset = mElement->getFieldOffsetBytes(ct);
Jason Samsd01d9702009-12-23 14:35:29 -0800160 mGL.mVtx.type = c.getGLType();
Jason Sams433eca32010-01-06 11:57:52 -0800161 mGL.mVtx.normalized = false;
162 mGL.mVtx.name.setTo("Position");
Jason Samse5ffb872009-08-09 17:01:55 -0700163 break;
Jason Samse5ffb872009-08-09 17:01:55 -0700164
Jason Samsd01d9702009-12-23 14:35:29 -0800165 case RS_KIND_COLOR:
Jason Samse5ffb872009-08-09 17:01:55 -0700166 rsAssert(mGL.mColor.size == 0);
Jason Samsd01d9702009-12-23 14:35:29 -0800167 mGL.mColor.size = c.getVectorSize();
Jason Sams4815c0d2009-12-15 12:58:36 -0800168 mGL.mColor.offset = mElement->getFieldOffsetBytes(ct);
Jason Samsd01d9702009-12-23 14:35:29 -0800169 mGL.mColor.type = c.getGLType();
Jason Sams433eca32010-01-06 11:57:52 -0800170 mGL.mColor.normalized = c.getType() != RS_TYPE_FLOAT_32;
171 mGL.mColor.name.setTo("Color");
Jason Samse5ffb872009-08-09 17:01:55 -0700172 break;
Jason Samse5ffb872009-08-09 17:01:55 -0700173
Jason Samsd01d9702009-12-23 14:35:29 -0800174 case RS_KIND_NORMAL:
Jason Samse5ffb872009-08-09 17:01:55 -0700175 rsAssert(mGL.mNorm.size == 0);
Jason Samsd01d9702009-12-23 14:35:29 -0800176 mGL.mNorm.size = c.getVectorSize();
Jason Sams4815c0d2009-12-15 12:58:36 -0800177 mGL.mNorm.offset = mElement->getFieldOffsetBytes(ct);
Jason Samsd01d9702009-12-23 14:35:29 -0800178 mGL.mNorm.type = c.getGLType();
Jason Sams433eca32010-01-06 11:57:52 -0800179 mGL.mNorm.normalized = false;
180 mGL.mNorm.name.setTo("Normal");
Jason Samsd01d9702009-12-23 14:35:29 -0800181 break;
Jason Samse5ffb872009-08-09 17:01:55 -0700182
Jason Samsd01d9702009-12-23 14:35:29 -0800183 case RS_KIND_TEXTURE:
Jason Sams433eca32010-01-06 11:57:52 -0800184 rsAssert(mGL.mTex.size == 0);
185 mGL.mTex.size = c.getVectorSize();
186 mGL.mTex.offset = mElement->getFieldOffsetBytes(ct);
187 mGL.mTex.type = c.getGLType();
188 mGL.mTex.normalized = false;
189 mGL.mTex.name.setTo("Texture");
Jason Samsd01d9702009-12-23 14:35:29 -0800190 break;
Jason Samse5ffb872009-08-09 17:01:55 -0700191
Jason Sams4815c0d2009-12-15 12:58:36 -0800192 case RS_KIND_POINT_SIZE:
Jason Samse0158412009-08-20 16:10:36 -0700193 rsAssert(!mGL.mPointSize.size);
Jason Samsd01d9702009-12-23 14:35:29 -0800194 mGL.mPointSize.size = c.getVectorSize();
Jason Sams4815c0d2009-12-15 12:58:36 -0800195 mGL.mPointSize.offset = mElement->getFieldOffsetBytes(ct);
Jason Samsd01d9702009-12-23 14:35:29 -0800196 mGL.mPointSize.type = c.getGLType();
Jason Sams433eca32010-01-06 11:57:52 -0800197 mGL.mPointSize.normalized = false;
198 mGL.mPointSize.name.setTo("PointSize");
Jason Samse0158412009-08-20 16:10:36 -0700199 break;
200
Jason Samse5ffb872009-08-09 17:01:55 -0700201 default:
202 break;
203 }
204 }
205}
206
Jason Samsc460e552009-11-25 13:22:07 -0800207void Type::enableGLVertexBuffer(VertexArray *va) const
Jason Samse5ffb872009-08-09 17:01:55 -0700208{
209 // Note: We are only going to enable buffers and never disable them
Jason Sams433eca32010-01-06 11:57:52 -0800210 // here. The reason is more than one Allocation may be used as a vertex
Jason Samse5ffb872009-08-09 17:01:55 -0700211 // source. So we cannot disable arrays that may have been in use by
212 // another allocation.
213
214 uint32_t stride = mElement->getSizeBytes();
215 if (mGL.mVtx.size) {
Jason Samsbe504f22010-01-25 12:31:24 -0800216 va->addLegacy(mGL.mVtx.type,
217 mGL.mVtx.size,
218 stride,
219 RS_KIND_POSITION,
220 false,
221 mGL.mVtx.offset);
Jason Samse5ffb872009-08-09 17:01:55 -0700222 }
223
224 if (mGL.mNorm.size) {
Jason Samsbe504f22010-01-25 12:31:24 -0800225 va->addLegacy(mGL.mNorm.type,
226 3,
227 stride,
228 RS_KIND_NORMAL,
229 false,
230 mGL.mNorm.offset);
Jason Samse5ffb872009-08-09 17:01:55 -0700231 }
232
233 if (mGL.mColor.size) {
Jason Samsbe504f22010-01-25 12:31:24 -0800234 va->addLegacy(mGL.mColor.type,
235 mGL.mColor.size,
Jason Samsc460e552009-11-25 13:22:07 -0800236 stride,
Jason Samsbe504f22010-01-25 12:31:24 -0800237 RS_KIND_COLOR,
238 true,
Jason Samsc460e552009-11-25 13:22:07 -0800239 mGL.mColor.offset);
Jason Samse5ffb872009-08-09 17:01:55 -0700240 }
241
Jason Sams433eca32010-01-06 11:57:52 -0800242 if (mGL.mTex.size) {
Jason Samsbe504f22010-01-25 12:31:24 -0800243 va->addLegacy(mGL.mTex.type,
244 mGL.mTex.size,
245 stride,
246 RS_KIND_TEXTURE,
247 false,
248 mGL.mTex.offset);
Jason Samse5ffb872009-08-09 17:01:55 -0700249 }
Jason Samse5ffb872009-08-09 17:01:55 -0700250
Jason Samse0158412009-08-20 16:10:36 -0700251 if (mGL.mPointSize.size) {
Jason Samsbe504f22010-01-25 12:31:24 -0800252 va->addLegacy(mGL.mPointSize.type,
253 1,
254 stride,
255 RS_KIND_POINT_SIZE,
256 false,
257 mGL.mPointSize.offset);
Jason Samse0158412009-08-20 16:10:36 -0700258 }
259
Jason Samse5ffb872009-08-09 17:01:55 -0700260}
261
Jason Sams433eca32010-01-06 11:57:52 -0800262void Type::enableGLVertexBuffer2(VertexArray *va) const
263{
264 // Do legacy buffers
265 enableGLVertexBuffer(va);
266
267 uint32_t stride = mElement->getSizeBytes();
268 for (uint32_t ct=0; ct < RS_MAX_ATTRIBS; ct++) {
269 if (mGL.mUser[ct].size) {
Jason Samsbe504f22010-01-25 12:31:24 -0800270 va->addUser(mGL.mUser[ct], stride);
Jason Sams433eca32010-01-06 11:57:52 -0800271 }
272 }
273}
274
275
Jason Samse5ffb872009-08-09 17:01:55 -0700276
Jason Samse12c1c52009-09-27 17:50:38 -0700277void Type::dumpLOGV(const char *prefix) const
278{
279 char buf[1024];
280 ObjectBase::dumpLOGV(prefix);
281 LOGV("%s Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
282 sprintf(buf, "%s element: ", prefix);
283 mElement->dumpLOGV(buf);
284}
285
Jason Samsef21edc2010-02-22 15:37:51 -0800286bool Type::getIsNp2() const
287{
288 uint32_t x = getDimX();
289 uint32_t y = getDimY();
290 uint32_t z = getDimZ();
291
292 if (x && (x & (x-1))) {
293 return true;
294 }
295 if (y && (y & (y-1))) {
296 return true;
297 }
298 if (z && (z & (z-1))) {
299 return true;
300 }
301 return false;
302}
303
Jason Samse12c1c52009-09-27 17:50:38 -0700304
Jason Sams326e0dd2009-05-22 14:03:28 -0700305//////////////////////////////////////////////////
Jason Samse5ffb872009-08-09 17:01:55 -0700306//
Jason Sams326e0dd2009-05-22 14:03:28 -0700307namespace android {
308namespace renderscript {
309
310void rsi_TypeBegin(Context *rsc, RsElement vse)
311{
312 TypeState * stc = &rsc->mStateType;
313
314 stc->mX = 0;
315 stc->mY = 0;
316 stc->mZ = 0;
317 stc->mLOD = false;
318 stc->mFaces = false;
319 stc->mElement.set(static_cast<const Element *>(vse));
320}
321
322void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value)
323{
324 TypeState * stc = &rsc->mStateType;
325
326 if (dim < 0) {
327 //error
328 return;
329 }
330
331
332 switch (dim) {
333 case RS_DIMENSION_X:
334 stc->mX = value;
335 return;
336 case RS_DIMENSION_Y:
337 stc->mY = value;
338 return;
339 case RS_DIMENSION_Z:
340 stc->mZ = value;
341 return;
342 case RS_DIMENSION_FACE:
343 stc->mFaces = (value != 0);
344 return;
345 case RS_DIMENSION_LOD:
346 stc->mLOD = (value != 0);
347 return;
348 default:
349 break;
350 }
351
352
353 int32_t arrayNum = dim - RS_DIMENSION_ARRAY_0;
354 if ((dim < 0) || (dim > RS_DIMENSION_MAX)) {
355 LOGE("rsTypeAdd: Bad dimension");
356 //error
357 return;
358 }
359
360 // todo: implement array support
361
362}
363
364RsType rsi_TypeCreate(Context *rsc)
365{
366 TypeState * stc = &rsc->mStateType;
367
Jason Sams81549542010-02-17 15:38:10 -0800368 for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
369 Type *t = stc->mTypes[ct];
370 if (t->getElement() != stc->mElement.get()) continue;
371 if (t->getDimX() != stc->mX) continue;
372 if (t->getDimY() != stc->mY) continue;
373 if (t->getDimZ() != stc->mZ) continue;
374 if (t->getDimLOD() != stc->mLOD) continue;
375 if (t->getDimFaces() != stc->mFaces) continue;
376 t->incUserRef();
377 return t;
378 }
379
Jason Samse514b452009-09-25 14:51:22 -0700380 Type * st = new Type(rsc);
Jason Sams9397e302009-08-27 20:23:34 -0700381 st->incUserRef();
Jason Sams326e0dd2009-05-22 14:03:28 -0700382 st->setDimX(stc->mX);
383 st->setDimY(stc->mY);
384 st->setDimZ(stc->mZ);
385 st->setElement(stc->mElement.get());
386 st->setDimLOD(stc->mLOD);
387 st->setDimFaces(stc->mFaces);
388 st->compute();
Jason Sams83128012009-09-25 16:50:36 -0700389 stc->mElement.clear();
Jason Sams81549542010-02-17 15:38:10 -0800390 stc->mTypes.push(st);
Jason Sams326e0dd2009-05-22 14:03:28 -0700391 return st;
392}
393
Jason Sams326e0dd2009-05-22 14:03:28 -0700394
395}
396}
397