• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
18 #include <GLES/gl.h>
19 
20 using namespace android;
21 using namespace android::renderscript;
22 
Type(Context * rsc)23 Type::Type(Context *rsc) : ObjectBase(rsc)
24 {
25     mAllocFile = __FILE__;
26     mAllocLine = __LINE__;
27     mLODs = 0;
28     mLODCount = 0;
29     memset(&mGL, 0, sizeof(mGL));
30     clear();
31 }
32 
~Type()33 Type::~Type()
34 {
35     if (mLODs) {
36         delete [] mLODs;
37     }
38 }
39 
clear()40 void 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 
TypeState()54 TypeState::TypeState()
55 {
56 }
57 
~TypeState()58 TypeState::~TypeState()
59 {
60 }
61 
getOffsetForFace(uint32_t face) const62 size_t Type::getOffsetForFace(uint32_t face) const
63 {
64     rsAssert(mFaces);
65     return 0;
66 }
67 
compute()68 void Type::compute()
69 {
70     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 
86     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;
95         offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
96         tx = (tx + 1) >> 1;
97         ty = (ty + 1) >> 1;
98         tz = (tz + 1) >> 1;
99     }
100 
101     // 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 
109     makeGLComponents();
110 }
111 
getLODOffset(uint32_t lod,uint32_t x) const112 uint32_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 
getLODOffset(uint32_t lod,uint32_t x,uint32_t y) const119 uint32_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 
getLODOffset(uint32_t lod,uint32_t x,uint32_t y,uint32_t z) const126 uint32_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 
makeGLComponents()134 void 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:
182             // 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             }
192         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 
235         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 
242         default:
243             break;
244         }
245     }
246 }
247 
enableGLVertexBuffer() const248 void 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) {
257         //LOGE("va vtx %i %x, %i, %p", mGL.mVtx.size, mGL.mVtx.type, stride, (void *)mGL.mVtx.offset);
258         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) {
266         //LOGE("va norm %i %x, %i, %p", mGL.mNorm.size, mGL.mNorm.type, stride, (void *)mGL.mNorm.offset);
267         glEnableClientState(GL_NORMAL_ARRAY);
268         rsAssert(mGL.mNorm.size == 3);
269         glNormalPointer(mGL.mNorm.type,
270                         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) {
284             //LOGE("va tex%i %i %x, %i, %p", ct, mGL.mTex[ct].size, mGL.mTex[ct].type, stride, (void *)mGL.mTex[ct].offset);
285             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 
295     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 
302 }
303 
304 
dumpLOGV(const char * prefix) const305 void 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 
315 //////////////////////////////////////////////////
316 //
317 namespace android {
318 namespace renderscript {
319 
rsi_TypeBegin(Context * rsc,RsElement vse)320 void 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 
rsi_TypeAdd(Context * rsc,RsDimension dim,size_t value)332 void 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 
rsi_TypeCreate(Context * rsc)374 RsType rsi_TypeCreate(Context *rsc)
375 {
376     TypeState * stc = &rsc->mStateType;
377 
378     Type * st = new Type(rsc);
379     st->incUserRef();
380     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();
387     stc->mElement.clear();
388 
389     return st;
390 }
391 
392 
393 }
394 }
395 
396