rsType.cpp revision d01d970cf5973aa5186cc02c80fb2c143a69b0b1
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    memset(&mGL, 0, sizeof(mGL));
30    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{
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
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
134void Type::makeGLComponents()
135{
136    uint32_t texNum = 0;
137    memset(&mGL, 0, sizeof(mGL));
138
139    for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
140        const Component &c = getElement()->getField(ct)->getComponent();
141
142        switch(c.getKind()) {
143        case RS_KIND_POSITION:
144            rsAssert(mGL.mVtx.size == 0);
145            mGL.mVtx.size = c.getVectorSize();
146            mGL.mVtx.offset = mElement->getFieldOffsetBytes(ct);
147            mGL.mVtx.type = c.getGLType();
148            break;
149
150        case RS_KIND_COLOR:
151            rsAssert(mGL.mColor.size == 0);
152            mGL.mColor.size = c.getVectorSize();
153            mGL.mColor.offset = mElement->getFieldOffsetBytes(ct);
154            mGL.mColor.type = c.getGLType();
155            break;
156
157        case RS_KIND_NORMAL:
158            rsAssert(mGL.mNorm.size == 0);
159            mGL.mNorm.size = c.getVectorSize();
160            mGL.mNorm.offset = mElement->getFieldOffsetBytes(ct);
161            mGL.mNorm.type = c.getGLType();
162            break;
163
164        case RS_KIND_TEXTURE:
165            if (mGL.mTex[texNum].size) {
166                texNum++;
167            }
168            mGL.mTex[texNum].size = c.getVectorSize();
169            mGL.mTex[texNum].offset = mElement->getFieldOffsetBytes(ct);
170            mGL.mTex[texNum].type = c.getGLType();
171            break;
172
173        case RS_KIND_POINT_SIZE:
174            rsAssert(!mGL.mPointSize.size);
175            mGL.mPointSize.size = c.getVectorSize();
176            mGL.mPointSize.offset = mElement->getFieldOffsetBytes(ct);
177            mGL.mPointSize.type = c.getGLType();
178        break;
179
180        default:
181            break;
182        }
183    }
184}
185
186void Type::enableGLVertexBuffer(VertexArray *va) const
187{
188    // Note: We are only going to enable buffers and never disable them
189    // here.  The reasonis more than one Allocation may be used as a vertex
190    // source.  So we cannot disable arrays that may have been in use by
191    // another allocation.
192
193    uint32_t stride = mElement->getSizeBytes();
194    if (mGL.mVtx.size) {
195        va->setPosition(mGL.mVtx.size,
196                        mGL.mVtx.type,
197                        stride,
198                        mGL.mVtx.offset);
199    }
200
201    if (mGL.mNorm.size) {
202        va->setNormal(mGL.mNorm.type,
203                      stride,
204                      mGL.mNorm.offset);
205    }
206
207    if (mGL.mColor.size) {
208        va->setColor(mGL.mColor.size,
209                     mGL.mColor.type,
210                     stride,
211                     mGL.mColor.offset);
212    }
213
214    for (uint32_t ct=0; ct < RS_MAX_TEXTURE; ct++) {
215        if (mGL.mTex[ct].size) {
216            va->setTexture(mGL.mTex[ct].size,
217                           mGL.mTex[ct].type,
218                           stride,
219                           mGL.mTex[ct].offset,
220                           ct);
221        }
222    }
223
224    if (mGL.mPointSize.size) {
225        va->setPointSize(mGL.mPointSize.type,
226                         stride,
227                         mGL.mPointSize.offset);
228    }
229
230}
231
232
233void Type::dumpLOGV(const char *prefix) const
234{
235    char buf[1024];
236    ObjectBase::dumpLOGV(prefix);
237    LOGV("%s   Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
238    sprintf(buf, "%s element: ", prefix);
239    mElement->dumpLOGV(buf);
240}
241
242
243//////////////////////////////////////////////////
244//
245namespace android {
246namespace renderscript {
247
248void rsi_TypeBegin(Context *rsc, RsElement vse)
249{
250    TypeState * stc = &rsc->mStateType;
251
252    stc->mX = 0;
253    stc->mY = 0;
254    stc->mZ = 0;
255    stc->mLOD = false;
256    stc->mFaces = false;
257    stc->mElement.set(static_cast<const Element *>(vse));
258}
259
260void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value)
261{
262    TypeState * stc = &rsc->mStateType;
263
264    if (dim < 0) {
265        //error
266        return;
267    }
268
269
270    switch (dim) {
271    case RS_DIMENSION_X:
272        stc->mX = value;
273        return;
274    case RS_DIMENSION_Y:
275        stc->mY = value;
276        return;
277    case RS_DIMENSION_Z:
278        stc->mZ = value;
279        return;
280    case RS_DIMENSION_FACE:
281        stc->mFaces = (value != 0);
282        return;
283    case RS_DIMENSION_LOD:
284        stc->mLOD = (value != 0);
285        return;
286    default:
287        break;
288    }
289
290
291    int32_t arrayNum = dim - RS_DIMENSION_ARRAY_0;
292    if ((dim < 0) || (dim > RS_DIMENSION_MAX)) {
293        LOGE("rsTypeAdd: Bad dimension");
294        //error
295        return;
296    }
297
298    // todo: implement array support
299
300}
301
302RsType rsi_TypeCreate(Context *rsc)
303{
304    TypeState * stc = &rsc->mStateType;
305
306    Type * st = new Type(rsc);
307    st->incUserRef();
308    st->setDimX(stc->mX);
309    st->setDimY(stc->mY);
310    st->setDimZ(stc->mZ);
311    st->setElement(stc->mElement.get());
312    st->setDimLOD(stc->mLOD);
313    st->setDimFaces(stc->mFaces);
314    st->compute();
315    stc->mElement.clear();
316
317    return st;
318}
319
320
321}
322}
323
324