blob: ddaa2f0e142626a1b88f4d28b24b6257f07aef20 [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;
Jason Samse5ffb872009-08-09 17:01:55 -070029 memset(&mGL, 0, sizeof(mGL));
Jason Sams326e0dd2009-05-22 14:03:28 -070030 clear();
31}
32
33Type::~Type()
34{
35 if (mLODs) {
36 delete [] mLODs;
37 }
38}
39
40void Type::clear()
41{
42 if (mLODs) {
43 delete [] mLODs;
44 mLODs = NULL;
45 }
46 mDimX = 0;
47 mDimY = 0;
48 mDimZ = 0;
49 mDimLOD = 0;
50 mFaces = false;
51 mElement.clear();
52}
53
54TypeState::TypeState()
55{
56}
57
58TypeState::~TypeState()
59{
60}
61
62size_t Type::getOffsetForFace(uint32_t face) const
63{
64 rsAssert(mFaces);
65 return 0;
66}
67
68void Type::compute()
69{
Jason Sams326e0dd2009-05-22 14:03:28 -070070 uint32_t oldLODCount = mLODCount;
71 if (mDimLOD) {
72 uint32_t l2x = rsFindHighBit(mDimX) + 1;
73 uint32_t l2y = rsFindHighBit(mDimY) + 1;
74 uint32_t l2z = rsFindHighBit(mDimZ) + 1;
75
76 mLODCount = rsMax(l2x, l2y);
77 mLODCount = rsMax(mLODCount, l2z);
78 } else {
79 mLODCount = 1;
80 }
81 if (mLODCount != oldLODCount) {
82 delete [] mLODs;
83 mLODs = new LOD[mLODCount];
84 }
85
Jason Sams326e0dd2009-05-22 14:03:28 -070086 uint32_t tx = mDimX;
87 uint32_t ty = mDimY;
88 uint32_t tz = mDimZ;
89 size_t offset = 0;
90 for (uint32_t lod=0; lod < mLODCount; lod++) {
91 mLODs[lod].mX = tx;
92 mLODs[lod].mY = ty;
93 mLODs[lod].mZ = tz;
94 mLODs[lod].mOffset = offset;
Jason Sams326e0dd2009-05-22 14:03:28 -070095 offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
Jason Samsa2fdbbb2009-06-22 18:13:36 -070096 tx = (tx + 1) >> 1;
97 ty = (ty + 1) >> 1;
98 tz = (tz + 1) >> 1;
Jason Sams326e0dd2009-05-22 14:03:28 -070099 }
100
Jason Sams326e0dd2009-05-22 14:03:28 -0700101 // At this point the offset is the size of a mipmap chain;
102 mMipChainSizeBytes = offset;
103
104 if (mFaces) {
105 offset *= 6;
106 }
107 mTotalSizeBytes = offset;
108
Jason Samse5ffb872009-08-09 17:01:55 -0700109 makeGLComponents();
Jason Sams326e0dd2009-05-22 14:03:28 -0700110}
111
112uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const
113{
114 uint32_t offset = mLODs[lod].mOffset;
115 offset += x * mElement->getSizeBytes();
116 return offset;
117}
118
119uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const
120{
121 uint32_t offset = mLODs[lod].mOffset;
122 offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
123 return offset;
124}
125
126uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const
127{
128 uint32_t offset = mLODs[lod].mOffset;
129 offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
130 return offset;
131}
132
133
Jason Samse5ffb872009-08-09 17:01:55 -0700134void Type::makeGLComponents()
135{
136 uint32_t texNum = 0;
137 memset(&mGL, 0, sizeof(mGL));
138
139 for (uint32_t ct=0; ct < getElement()->getComponentCount(); ct++) {
140 const Component *c = getElement()->getComponent(ct);
141
142 switch(c->getKind()) {
143 case Component::X:
144 rsAssert(mGL.mVtx.size == 0);
145 mGL.mVtx.size = 1;
146 mGL.mVtx.offset = mElement->getComponentOffsetBytes(ct);
147 mGL.mVtx.type = c->getGLType();
148 break;
149 case Component::Y:
150 rsAssert(mGL.mVtx.size == 1);
151 rsAssert(mGL.mVtx.type == c->getGLType());
152 mGL.mVtx.size = 2;
153 break;
154 case Component::Z:
155 rsAssert(mGL.mVtx.size == 2);
156 rsAssert(mGL.mVtx.type == c->getGLType());
157 mGL.mVtx.size = 3;
158 break;
159 case Component::W:
160 rsAssert(mGL.mVtx.size == 4);
161 rsAssert(mGL.mVtx.type == c->getGLType());
162 mGL.mVtx.size = 4;
163 break;
164
165 case Component::RED:
166 rsAssert(mGL.mColor.size == 0);
167 mGL.mColor.size = 1;
168 mGL.mColor.offset = mElement->getComponentOffsetBytes(ct);
169 mGL.mColor.type = c->getGLType();
170 break;
171 case Component::GREEN:
172 rsAssert(mGL.mColor.size == 1);
173 rsAssert(mGL.mColor.type == c->getGLType());
174 mGL.mColor.size = 2;
175 break;
176 case Component::BLUE:
177 rsAssert(mGL.mColor.size == 2);
178 rsAssert(mGL.mColor.type == c->getGLType());
179 mGL.mColor.size = 3;
180 break;
181 case Component::ALPHA:
Jason Sams707aaf32009-08-18 14:14:24 -0700182 // Can be RGBA or A at this point
183 if (mGL.mColor.size > 0) {
184 rsAssert(mGL.mColor.size == 3);
185 rsAssert(mGL.mColor.type == c->getGLType());
186 mGL.mColor.size = 4;
187 } else {
188 mGL.mColor.size = 1;
189 mGL.mColor.offset = mElement->getComponentOffsetBytes(ct);
190 mGL.mColor.type = c->getGLType();
191 }
Jason Samse5ffb872009-08-09 17:01:55 -0700192 break;
193
194 case Component::NX:
195 rsAssert(mGL.mNorm.size == 0);
196 mGL.mNorm.size = 1;
197 mGL.mNorm.offset = mElement->getComponentOffsetBytes(ct);
198 mGL.mNorm.type = c->getGLType();
199 break;
200 case Component::NY:
201 rsAssert(mGL.mNorm.size == 1);
202 rsAssert(mGL.mNorm.type == c->getGLType());
203 mGL.mNorm.size = 2;
204 break;
205 case Component::NZ:
206 rsAssert(mGL.mNorm.size == 2);
207 rsAssert(mGL.mNorm.type == c->getGLType());
208 mGL.mNorm.size = 3;
209 break;
210
211 case Component::S:
212 if (mGL.mTex[texNum].size) {
213 texNum++;
214 }
215 mGL.mTex[texNum].size = 1;
216 mGL.mTex[texNum].offset = mElement->getComponentOffsetBytes(ct);
217 mGL.mTex[texNum].type = c->getGLType();
218 break;
219 case Component::T:
220 rsAssert(mGL.mTex[texNum].size == 1);
221 rsAssert(mGL.mTex[texNum].type == c->getGLType());
222 mGL.mTex[texNum].size = 2;
223 break;
224 case Component::R:
225 rsAssert(mGL.mTex[texNum].size == 2);
226 rsAssert(mGL.mTex[texNum].type == c->getGLType());
227 mGL.mTex[texNum].size = 3;
228 break;
229 case Component::Q:
230 rsAssert(mGL.mTex[texNum].size == 3);
231 rsAssert(mGL.mTex[texNum].type == c->getGLType());
232 mGL.mTex[texNum].size = 4;
233 break;
234
Jason Samse0158412009-08-20 16:10:36 -0700235 case Component::POINT_SIZE:
236 rsAssert(!mGL.mPointSize.size);
237 mGL.mPointSize.size = 1;
238 mGL.mPointSize.offset = mElement->getComponentOffsetBytes(ct);
239 mGL.mPointSize.type = c->getGLType();
240 break;
241
Jason Samse5ffb872009-08-09 17:01:55 -0700242 default:
243 break;
244 }
245 }
246}
247
248void Type::enableGLVertexBuffer() const
249{
250 // Note: We are only going to enable buffers and never disable them
251 // here. The reasonis more than one Allocation may be used as a vertex
252 // source. So we cannot disable arrays that may have been in use by
253 // another allocation.
254
255 uint32_t stride = mElement->getSizeBytes();
256 if (mGL.mVtx.size) {
Jason Sams9397e302009-08-27 20:23:34 -0700257 //LOGE("va vtx %i %x, %i, %p", mGL.mVtx.size, mGL.mVtx.type, stride, (void *)mGL.mVtx.offset);
Jason Samse5ffb872009-08-09 17:01:55 -0700258 glEnableClientState(GL_VERTEX_ARRAY);
259 glVertexPointer(mGL.mVtx.size,
260 mGL.mVtx.type,
261 stride,
262 (void *)mGL.mVtx.offset);
263 }
264
265 if (mGL.mNorm.size) {
Jason Sams9397e302009-08-27 20:23:34 -0700266 //LOGE("va norm %i %x, %i, %p", mGL.mNorm.size, mGL.mNorm.type, stride, (void *)mGL.mNorm.offset);
Jason Samse5ffb872009-08-09 17:01:55 -0700267 glEnableClientState(GL_NORMAL_ARRAY);
268 rsAssert(mGL.mNorm.size == 3);
Jason Sams9397e302009-08-27 20:23:34 -0700269 glNormalPointer(mGL.mNorm.type,
Jason Samse5ffb872009-08-09 17:01:55 -0700270 stride,
271 (void *)mGL.mNorm.offset);
272 }
273
274 if (mGL.mColor.size) {
275 glEnableClientState(GL_COLOR_ARRAY);
276 glColorPointer(mGL.mColor.size,
277 mGL.mColor.type,
278 stride,
279 (void *)mGL.mColor.offset);
280 }
281
282 for (uint32_t ct=0; ct < RS_MAX_TEXTURE; ct++) {
283 if (mGL.mTex[ct].size) {
Jason Sams9397e302009-08-27 20:23:34 -0700284 //LOGE("va tex%i %i %x, %i, %p", ct, mGL.mTex[ct].size, mGL.mTex[ct].type, stride, (void *)mGL.mTex[ct].offset);
Jason Samse5ffb872009-08-09 17:01:55 -0700285 glClientActiveTexture(GL_TEXTURE0 + ct);
286 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
287 glTexCoordPointer(mGL.mTex[ct].size,
288 mGL.mTex[ct].type,
289 stride,
290 (void *)mGL.mTex[ct].offset);
291 }
292 }
293 glClientActiveTexture(GL_TEXTURE0);
294
Jason Samse0158412009-08-20 16:10:36 -0700295 if (mGL.mPointSize.size) {
296 glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
297 glPointSizePointerOES(mGL.mPointSize.type,
298 stride,
299 (void *)mGL.mPointSize.offset);
300 }
301
Jason Samse5ffb872009-08-09 17:01:55 -0700302}
303
304
Jason Samse12c1c52009-09-27 17:50:38 -0700305void Type::dumpLOGV(const char *prefix) const
306{
307 char buf[1024];
308 ObjectBase::dumpLOGV(prefix);
309 LOGV("%s Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
310 sprintf(buf, "%s element: ", prefix);
311 mElement->dumpLOGV(buf);
312}
313
314
Jason Sams326e0dd2009-05-22 14:03:28 -0700315//////////////////////////////////////////////////
Jason Samse5ffb872009-08-09 17:01:55 -0700316//
Jason Sams326e0dd2009-05-22 14:03:28 -0700317namespace android {
318namespace renderscript {
319
320void rsi_TypeBegin(Context *rsc, RsElement vse)
321{
322 TypeState * stc = &rsc->mStateType;
323
324 stc->mX = 0;
325 stc->mY = 0;
326 stc->mZ = 0;
327 stc->mLOD = false;
328 stc->mFaces = false;
329 stc->mElement.set(static_cast<const Element *>(vse));
330}
331
332void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value)
333{
334 TypeState * stc = &rsc->mStateType;
335
336 if (dim < 0) {
337 //error
338 return;
339 }
340
341
342 switch (dim) {
343 case RS_DIMENSION_X:
344 stc->mX = value;
345 return;
346 case RS_DIMENSION_Y:
347 stc->mY = value;
348 return;
349 case RS_DIMENSION_Z:
350 stc->mZ = value;
351 return;
352 case RS_DIMENSION_FACE:
353 stc->mFaces = (value != 0);
354 return;
355 case RS_DIMENSION_LOD:
356 stc->mLOD = (value != 0);
357 return;
358 default:
359 break;
360 }
361
362
363 int32_t arrayNum = dim - RS_DIMENSION_ARRAY_0;
364 if ((dim < 0) || (dim > RS_DIMENSION_MAX)) {
365 LOGE("rsTypeAdd: Bad dimension");
366 //error
367 return;
368 }
369
370 // todo: implement array support
371
372}
373
374RsType rsi_TypeCreate(Context *rsc)
375{
376 TypeState * stc = &rsc->mStateType;
377
Jason Samse514b452009-09-25 14:51:22 -0700378 Type * st = new Type(rsc);
Jason Sams9397e302009-08-27 20:23:34 -0700379 st->incUserRef();
Jason Sams326e0dd2009-05-22 14:03:28 -0700380 st->setDimX(stc->mX);
381 st->setDimY(stc->mY);
382 st->setDimZ(stc->mZ);
383 st->setElement(stc->mElement.get());
384 st->setDimLOD(stc->mLOD);
385 st->setDimFaces(stc->mFaces);
386 st->compute();
Jason Sams83128012009-09-25 16:50:36 -0700387 stc->mElement.clear();
Jason Sams326e0dd2009-05-22 14:03:28 -0700388
Jason Sams326e0dd2009-05-22 14:03:28 -0700389 return st;
390}
391
Jason Sams326e0dd2009-05-22 14:03:28 -0700392
393}
394}
395