rsType.cpp revision 433eca30b2efe0cf84bbda33f2dfdfd6dcafaf59
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
20using namespace android;
21using namespace android::renderscript;
22
23Type::Type(Context *rsc) : ObjectBase(rsc)
24{
25    mAllocFile = __FILE__;
26    mAllocLine = __LINE__;
27    mLODs = 0;
28    mLODCount = 0;
29    clear();
30}
31
32Type::~Type()
33{
34    if (mLODs) {
35        delete [] mLODs;
36    }
37}
38
39void Type::clear()
40{
41    if (mLODs) {
42        delete [] mLODs;
43        mLODs = NULL;
44    }
45    mDimX = 0;
46    mDimY = 0;
47    mDimZ = 0;
48    mDimLOD = 0;
49    mFaces = false;
50    mElement.clear();
51}
52
53TypeState::TypeState()
54{
55}
56
57TypeState::~TypeState()
58{
59}
60
61size_t Type::getOffsetForFace(uint32_t face) const
62{
63    rsAssert(mFaces);
64    return 0;
65}
66
67void Type::compute()
68{
69    uint32_t oldLODCount = mLODCount;
70    if (mDimLOD) {
71        uint32_t l2x = rsFindHighBit(mDimX) + 1;
72        uint32_t l2y = rsFindHighBit(mDimY) + 1;
73        uint32_t l2z = rsFindHighBit(mDimZ) + 1;
74
75        mLODCount = rsMax(l2x, l2y);
76        mLODCount = rsMax(mLODCount, l2z);
77    } else {
78        mLODCount = 1;
79    }
80    if (mLODCount != oldLODCount) {
81        delete [] mLODs;
82        mLODs = new LOD[mLODCount];
83    }
84
85    uint32_t tx = mDimX;
86    uint32_t ty = mDimY;
87    uint32_t tz = mDimZ;
88    size_t offset = 0;
89    for (uint32_t lod=0; lod < mLODCount; lod++) {
90        mLODs[lod].mX = tx;
91        mLODs[lod].mY = ty;
92        mLODs[lod].mZ = tz;
93        mLODs[lod].mOffset = offset;
94        offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
95        tx = (tx + 1) >> 1;
96        ty = (ty + 1) >> 1;
97        tz = (tz + 1) >> 1;
98    }
99
100    // At this point the offset is the size of a mipmap chain;
101    mMipChainSizeBytes = offset;
102
103    if (mFaces) {
104        offset *= 6;
105    }
106    mTotalSizeBytes = offset;
107
108    makeGLComponents();
109}
110
111uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const
112{
113    uint32_t offset = mLODs[lod].mOffset;
114    offset += x * mElement->getSizeBytes();
115    return offset;
116}
117
118uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const
119{
120    uint32_t offset = mLODs[lod].mOffset;
121    offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
122    return offset;
123}
124
125uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const
126{
127    uint32_t offset = mLODs[lod].mOffset;
128    offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
129    return offset;
130}
131
132
133void Type::makeGLComponents()
134{
135    uint32_t userNum = 0;
136
137    for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
138        const Component &c = getElement()->getField(ct)->getComponent();
139
140        switch(c.getKind()) {
141        case RS_KIND_USER:
142            mGL.mUser[userNum].size = c.getVectorSize();
143            mGL.mUser[userNum].offset = mElement->getFieldOffsetBytes(ct);
144            mGL.mUser[userNum].type = c.getGLType();
145            mGL.mUser[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
146            mGL.mUser[userNum].name.setTo(getElement()->getFieldName(ct));
147            userNum ++;
148            break;
149
150        case RS_KIND_POSITION:
151            rsAssert(mGL.mVtx.size == 0);
152            mGL.mVtx.size = c.getVectorSize();
153            mGL.mVtx.offset = mElement->getFieldOffsetBytes(ct);
154            mGL.mVtx.type = c.getGLType();
155            mGL.mVtx.normalized = false;
156            mGL.mVtx.name.setTo("Position");
157            break;
158
159        case RS_KIND_COLOR:
160            rsAssert(mGL.mColor.size == 0);
161            mGL.mColor.size = c.getVectorSize();
162            mGL.mColor.offset = mElement->getFieldOffsetBytes(ct);
163            mGL.mColor.type = c.getGLType();
164            mGL.mColor.normalized = c.getType() != RS_TYPE_FLOAT_32;
165            mGL.mColor.name.setTo("Color");
166            break;
167
168        case RS_KIND_NORMAL:
169            rsAssert(mGL.mNorm.size == 0);
170            mGL.mNorm.size = c.getVectorSize();
171            mGL.mNorm.offset = mElement->getFieldOffsetBytes(ct);
172            mGL.mNorm.type = c.getGLType();
173            mGL.mNorm.normalized = false;
174            mGL.mNorm.name.setTo("Normal");
175            break;
176
177        case RS_KIND_TEXTURE:
178            rsAssert(mGL.mTex.size == 0);
179            mGL.mTex.size = c.getVectorSize();
180            mGL.mTex.offset = mElement->getFieldOffsetBytes(ct);
181            mGL.mTex.type = c.getGLType();
182            mGL.mTex.normalized = false;
183            mGL.mTex.name.setTo("Texture");
184            break;
185
186        case RS_KIND_POINT_SIZE:
187            rsAssert(!mGL.mPointSize.size);
188            mGL.mPointSize.size = c.getVectorSize();
189            mGL.mPointSize.offset = mElement->getFieldOffsetBytes(ct);
190            mGL.mPointSize.type = c.getGLType();
191            mGL.mPointSize.normalized = false;
192            mGL.mPointSize.name.setTo("PointSize");
193        break;
194
195        default:
196            break;
197        }
198    }
199}
200
201void Type::enableGLVertexBuffer(VertexArray *va) const
202{
203    // Note: We are only going to enable buffers and never disable them
204    // here.  The reason is more than one Allocation may be used as a vertex
205    // source.  So we cannot disable arrays that may have been in use by
206    // another allocation.
207
208    uint32_t stride = mElement->getSizeBytes();
209    if (mGL.mVtx.size) {
210        va->setPosition(mGL.mVtx.size,
211                        mGL.mVtx.type,
212                        stride,
213                        mGL.mVtx.offset);
214    }
215
216    if (mGL.mNorm.size) {
217        va->setNormal(mGL.mNorm.type,
218                      stride,
219                      mGL.mNorm.offset);
220    }
221
222    if (mGL.mColor.size) {
223        va->setColor(mGL.mColor.size,
224                     mGL.mColor.type,
225                     stride,
226                     mGL.mColor.offset);
227    }
228
229    if (mGL.mTex.size) {
230        va->setTexture(mGL.mTex.size,
231                       mGL.mTex.type,
232                       stride,
233                       mGL.mTex.offset);
234    }
235
236    if (mGL.mPointSize.size) {
237        va->setPointSize(mGL.mPointSize.type,
238                         stride,
239                         mGL.mPointSize.offset);
240    }
241
242}
243
244void Type::enableGLVertexBuffer2(VertexArray *va) const
245{
246    // Do legacy buffers
247    enableGLVertexBuffer(va);
248
249    uint32_t stride = mElement->getSizeBytes();
250    for (uint32_t ct=0; ct < RS_MAX_ATTRIBS; ct++) {
251        if (mGL.mUser[ct].size) {
252            va->setUser(mGL.mUser[ct], stride);
253        }
254    }
255}
256
257
258
259void Type::dumpLOGV(const char *prefix) const
260{
261    char buf[1024];
262    ObjectBase::dumpLOGV(prefix);
263    LOGV("%s   Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
264    sprintf(buf, "%s element: ", prefix);
265    mElement->dumpLOGV(buf);
266}
267
268
269//////////////////////////////////////////////////
270//
271namespace android {
272namespace renderscript {
273
274void rsi_TypeBegin(Context *rsc, RsElement vse)
275{
276    TypeState * stc = &rsc->mStateType;
277
278    stc->mX = 0;
279    stc->mY = 0;
280    stc->mZ = 0;
281    stc->mLOD = false;
282    stc->mFaces = false;
283    stc->mElement.set(static_cast<const Element *>(vse));
284}
285
286void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value)
287{
288    TypeState * stc = &rsc->mStateType;
289
290    if (dim < 0) {
291        //error
292        return;
293    }
294
295
296    switch (dim) {
297    case RS_DIMENSION_X:
298        stc->mX = value;
299        return;
300    case RS_DIMENSION_Y:
301        stc->mY = value;
302        return;
303    case RS_DIMENSION_Z:
304        stc->mZ = value;
305        return;
306    case RS_DIMENSION_FACE:
307        stc->mFaces = (value != 0);
308        return;
309    case RS_DIMENSION_LOD:
310        stc->mLOD = (value != 0);
311        return;
312    default:
313        break;
314    }
315
316
317    int32_t arrayNum = dim - RS_DIMENSION_ARRAY_0;
318    if ((dim < 0) || (dim > RS_DIMENSION_MAX)) {
319        LOGE("rsTypeAdd: Bad dimension");
320        //error
321        return;
322    }
323
324    // todo: implement array support
325
326}
327
328RsType rsi_TypeCreate(Context *rsc)
329{
330    TypeState * stc = &rsc->mStateType;
331
332    Type * st = new Type(rsc);
333    st->incUserRef();
334    st->setDimX(stc->mX);
335    st->setDimY(stc->mY);
336    st->setDimZ(stc->mZ);
337    st->setElement(stc->mElement.get());
338    st->setDimLOD(stc->mLOD);
339    st->setDimFaces(stc->mFaces);
340    st->compute();
341    stc->mElement.clear();
342
343    return st;
344}
345
346
347}
348}
349
350