• 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     clear();
30 }
31 
~Type()32 Type::~Type()
33 {
34     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     }
40     if (mLODs) {
41         delete [] mLODs;
42     }
43 }
44 
clear()45 void 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 
TypeState()59 TypeState::TypeState()
60 {
61 }
62 
~TypeState()63 TypeState::~TypeState()
64 {
65 }
66 
getOffsetForFace(uint32_t face) const67 size_t Type::getOffsetForFace(uint32_t face) const
68 {
69     rsAssert(mFaces);
70     return 0;
71 }
72 
compute()73 void Type::compute()
74 {
75     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 
91     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;
100         offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
101         if (tx > 1) tx >>= 1;
102         if (ty > 1) ty >>= 1;
103         if (tz > 1) tz >>= 1;
104     }
105 
106     // 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 
114     makeGLComponents();
115 }
116 
getLODOffset(uint32_t lod,uint32_t x) const117 uint32_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 
getLODOffset(uint32_t lod,uint32_t x,uint32_t y) const124 uint32_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 
getLODOffset(uint32_t lod,uint32_t x,uint32_t y,uint32_t z) const131 uint32_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 
makeGLComponents()139 void Type::makeGLComponents()
140 {
141     uint32_t userNum = 0;
142 
143     for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
144         const Component &c = getElement()->getField(ct)->getComponent();
145 
146         switch(c.getKind()) {
147         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 
156         case RS_KIND_POSITION:
157             rsAssert(mGL.mVtx.size == 0);
158             mGL.mVtx.size = c.getVectorSize();
159             mGL.mVtx.offset = mElement->getFieldOffsetBytes(ct);
160             mGL.mVtx.type = c.getGLType();
161             mGL.mVtx.normalized = false;
162             mGL.mVtx.name.setTo("Position");
163             break;
164 
165         case RS_KIND_COLOR:
166             rsAssert(mGL.mColor.size == 0);
167             mGL.mColor.size = c.getVectorSize();
168             mGL.mColor.offset = mElement->getFieldOffsetBytes(ct);
169             mGL.mColor.type = c.getGLType();
170             mGL.mColor.normalized = c.getType() != RS_TYPE_FLOAT_32;
171             mGL.mColor.name.setTo("Color");
172             break;
173 
174         case RS_KIND_NORMAL:
175             rsAssert(mGL.mNorm.size == 0);
176             mGL.mNorm.size = c.getVectorSize();
177             mGL.mNorm.offset = mElement->getFieldOffsetBytes(ct);
178             mGL.mNorm.type = c.getGLType();
179             mGL.mNorm.normalized = false;
180             mGL.mNorm.name.setTo("Normal");
181             break;
182 
183         case RS_KIND_TEXTURE:
184             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");
190             break;
191 
192         case RS_KIND_POINT_SIZE:
193             rsAssert(!mGL.mPointSize.size);
194             mGL.mPointSize.size = c.getVectorSize();
195             mGL.mPointSize.offset = mElement->getFieldOffsetBytes(ct);
196             mGL.mPointSize.type = c.getGLType();
197             mGL.mPointSize.normalized = false;
198             mGL.mPointSize.name.setTo("PointSize");
199         break;
200 
201         default:
202             break;
203         }
204     }
205 }
206 
enableGLVertexBuffer(VertexArray * va) const207 void Type::enableGLVertexBuffer(VertexArray *va) const
208 {
209     // Note: We are only going to enable buffers and never disable them
210     // here.  The reason is more than one Allocation may be used as a vertex
211     // 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) {
216         va->addLegacy(mGL.mVtx.type,
217                       mGL.mVtx.size,
218                       stride,
219                       RS_KIND_POSITION,
220                       false,
221                       mGL.mVtx.offset);
222     }
223 
224     if (mGL.mNorm.size) {
225         va->addLegacy(mGL.mNorm.type,
226                      3,
227                      stride,
228                      RS_KIND_NORMAL,
229                      false,
230                      mGL.mNorm.offset);
231     }
232 
233     if (mGL.mColor.size) {
234         va->addLegacy(mGL.mColor.type,
235                      mGL.mColor.size,
236                      stride,
237                      RS_KIND_COLOR,
238                      true,
239                      mGL.mColor.offset);
240     }
241 
242     if (mGL.mTex.size) {
243         va->addLegacy(mGL.mTex.type,
244                      mGL.mTex.size,
245                      stride,
246                      RS_KIND_TEXTURE,
247                      false,
248                      mGL.mTex.offset);
249     }
250 
251     if (mGL.mPointSize.size) {
252         va->addLegacy(mGL.mPointSize.type,
253                      1,
254                      stride,
255                      RS_KIND_POINT_SIZE,
256                      false,
257                      mGL.mPointSize.offset);
258     }
259 
260 }
261 
enableGLVertexBuffer2(VertexArray * va) const262 void 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) {
270             va->addUser(mGL.mUser[ct], stride);
271         }
272     }
273 }
274 
275 
276 
dumpLOGV(const char * prefix) const277 void 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 
getIsNp2() const286 bool 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 
304 
305 //////////////////////////////////////////////////
306 //
307 namespace android {
308 namespace renderscript {
309 
rsi_TypeBegin(Context * rsc,RsElement vse)310 void 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 
rsi_TypeAdd(Context * rsc,RsDimension dim,size_t value)322 void 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 
rsi_TypeCreate(Context * rsc)364 RsType rsi_TypeCreate(Context *rsc)
365 {
366     TypeState * stc = &rsc->mStateType;
367 
368     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 
380     Type * st = new Type(rsc);
381     st->incUserRef();
382     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();
389     stc->mElement.clear();
390     stc->mTypes.push(st);
391     return st;
392 }
393 
394 
395 }
396 }
397 
398