rsType.cpp revision 326e0ddf89e8df2837752fbfd7a014814b32082c
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
19using namespace android;
20using namespace android::renderscript;
21
22Type::Type()
23{
24    mLODs = 0;
25    mLODCount = 0;
26    clear();
27}
28
29Type::~Type()
30{
31    if (mLODs) {
32        delete [] mLODs;
33    }
34}
35
36void Type::clear()
37{
38    if (mLODs) {
39        delete [] mLODs;
40        mLODs = NULL;
41    }
42    mDimX = 0;
43    mDimY = 0;
44    mDimZ = 0;
45    mDimLOD = 0;
46    mFaces = false;
47    mElement.clear();
48}
49
50TypeState::TypeState()
51{
52}
53
54TypeState::~TypeState()
55{
56}
57
58size_t Type::getOffsetForFace(uint32_t face) const
59{
60    rsAssert(mFaces);
61    return 0;
62}
63
64void Type::compute()
65{
66    //LOGE("compute");
67    uint32_t oldLODCount = mLODCount;
68    if (mDimLOD) {
69        uint32_t l2x = rsFindHighBit(mDimX) + 1;
70        uint32_t l2y = rsFindHighBit(mDimY) + 1;
71        uint32_t l2z = rsFindHighBit(mDimZ) + 1;
72
73        mLODCount = rsMax(l2x, l2y);
74        mLODCount = rsMax(mLODCount, l2z);
75    } else {
76        mLODCount = 1;
77    }
78    if (mLODCount != oldLODCount) {
79        delete [] mLODs;
80        mLODs = new LOD[mLODCount];
81    }
82
83    //LOGE("xyz %i %i %i", mDimX, mDimY, mDimZ);
84    //LOGE("mips %i", mLODCount);
85    //LOGE("e size %i", mElement->getSizeBytes());
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        //LOGE("txyz %i %i %i", tx, ty, tz);
96        offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
97        tx >>= 1;
98        ty >>= 1;
99        tz >>= 1;
100    }
101
102    //LOGE("size %i", offset);
103
104    // At this point the offset is the size of a mipmap chain;
105    mMipChainSizeBytes = offset;
106
107    if (mFaces) {
108        offset *= 6;
109    }
110    mTotalSizeBytes = offset;
111
112}
113
114uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const
115{
116    uint32_t offset = mLODs[lod].mOffset;
117    offset += x * mElement->getSizeBytes();
118    return offset;
119}
120
121uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const
122{
123    uint32_t offset = mLODs[lod].mOffset;
124    offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
125    return offset;
126}
127
128uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const
129{
130    uint32_t offset = mLODs[lod].mOffset;
131    offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
132    return offset;
133}
134
135
136//////////////////////////////////////////////////
137//
138namespace android {
139namespace renderscript {
140
141void rsi_TypeBegin(Context *rsc, RsElement vse)
142{
143    TypeState * stc = &rsc->mStateType;
144
145    stc->mX = 0;
146    stc->mY = 0;
147    stc->mZ = 0;
148    stc->mLOD = false;
149    stc->mFaces = false;
150    stc->mElement.set(static_cast<const Element *>(vse));
151}
152
153void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value)
154{
155    TypeState * stc = &rsc->mStateType;
156
157    if (dim < 0) {
158        //error
159        return;
160    }
161
162
163    switch (dim) {
164    case RS_DIMENSION_X:
165        stc->mX = value;
166        return;
167    case RS_DIMENSION_Y:
168        stc->mY = value;
169        return;
170    case RS_DIMENSION_Z:
171        stc->mZ = value;
172        return;
173    case RS_DIMENSION_FACE:
174        stc->mFaces = (value != 0);
175        return;
176    case RS_DIMENSION_LOD:
177        stc->mLOD = (value != 0);
178        return;
179    default:
180        break;
181    }
182
183
184    int32_t arrayNum = dim - RS_DIMENSION_ARRAY_0;
185    if ((dim < 0) || (dim > RS_DIMENSION_MAX)) {
186        LOGE("rsTypeAdd: Bad dimension");
187        //error
188        return;
189    }
190
191    // todo: implement array support
192
193}
194
195RsType rsi_TypeCreate(Context *rsc)
196{
197    TypeState * stc = &rsc->mStateType;
198
199    Type * st = new Type();
200    st->setDimX(stc->mX);
201    st->setDimY(stc->mY);
202    st->setDimZ(stc->mZ);
203    st->setElement(stc->mElement.get());
204    st->setDimLOD(stc->mLOD);
205    st->setDimFaces(stc->mFaces);
206    st->compute();
207
208    stc->mAllTypes.add(st);
209
210    return st;
211}
212
213void rsi_TypeDestroy(Context *rsc, RsType vst)
214{
215    TypeState * stc = &rsc->mStateType;
216    Type * st = static_cast<Type *>(vst);
217
218    for (size_t ct = 0; ct < stc->mAllTypes.size(); ct++) {
219        if (stc->mAllTypes[ct] == st) {
220            stc->mAllTypes.removeAt(ct);
221            break;
222        }
223    }
224    delete st;
225}
226
227}
228}
229
230