blob: bbe972023d674b84de7f2232e5c152d001e711ca [file] [log] [blame]
Jason Sams326e0dd2009-05-22 14:03:28 -07001/*
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{
Jason Sams326e0dd2009-05-22 14:03:28 -070066 uint32_t oldLODCount = mLODCount;
67 if (mDimLOD) {
68 uint32_t l2x = rsFindHighBit(mDimX) + 1;
69 uint32_t l2y = rsFindHighBit(mDimY) + 1;
70 uint32_t l2z = rsFindHighBit(mDimZ) + 1;
71
72 mLODCount = rsMax(l2x, l2y);
73 mLODCount = rsMax(mLODCount, l2z);
74 } else {
75 mLODCount = 1;
76 }
77 if (mLODCount != oldLODCount) {
78 delete [] mLODs;
79 mLODs = new LOD[mLODCount];
80 }
81
Jason Sams326e0dd2009-05-22 14:03:28 -070082 uint32_t tx = mDimX;
83 uint32_t ty = mDimY;
84 uint32_t tz = mDimZ;
85 size_t offset = 0;
86 for (uint32_t lod=0; lod < mLODCount; lod++) {
87 mLODs[lod].mX = tx;
88 mLODs[lod].mY = ty;
89 mLODs[lod].mZ = tz;
90 mLODs[lod].mOffset = offset;
Jason Sams326e0dd2009-05-22 14:03:28 -070091 offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
Jason Samsa2fdbbb2009-06-22 18:13:36 -070092 tx = (tx + 1) >> 1;
93 ty = (ty + 1) >> 1;
94 tz = (tz + 1) >> 1;
Jason Sams326e0dd2009-05-22 14:03:28 -070095 }
96
Jason Sams326e0dd2009-05-22 14:03:28 -070097 // At this point the offset is the size of a mipmap chain;
98 mMipChainSizeBytes = offset;
99
100 if (mFaces) {
101 offset *= 6;
102 }
103 mTotalSizeBytes = offset;
104
105}
106
107uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const
108{
109 uint32_t offset = mLODs[lod].mOffset;
110 offset += x * mElement->getSizeBytes();
111 return offset;
112}
113
114uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const
115{
116 uint32_t offset = mLODs[lod].mOffset;
117 offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
118 return offset;
119}
120
121uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const
122{
123 uint32_t offset = mLODs[lod].mOffset;
124 offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
125 return offset;
126}
127
128
129//////////////////////////////////////////////////
130//
131namespace android {
132namespace renderscript {
133
134void rsi_TypeBegin(Context *rsc, RsElement vse)
135{
136 TypeState * stc = &rsc->mStateType;
137
138 stc->mX = 0;
139 stc->mY = 0;
140 stc->mZ = 0;
141 stc->mLOD = false;
142 stc->mFaces = false;
143 stc->mElement.set(static_cast<const Element *>(vse));
144}
145
146void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value)
147{
148 TypeState * stc = &rsc->mStateType;
149
150 if (dim < 0) {
151 //error
152 return;
153 }
154
155
156 switch (dim) {
157 case RS_DIMENSION_X:
158 stc->mX = value;
159 return;
160 case RS_DIMENSION_Y:
161 stc->mY = value;
162 return;
163 case RS_DIMENSION_Z:
164 stc->mZ = value;
165 return;
166 case RS_DIMENSION_FACE:
167 stc->mFaces = (value != 0);
168 return;
169 case RS_DIMENSION_LOD:
170 stc->mLOD = (value != 0);
171 return;
172 default:
173 break;
174 }
175
176
177 int32_t arrayNum = dim - RS_DIMENSION_ARRAY_0;
178 if ((dim < 0) || (dim > RS_DIMENSION_MAX)) {
179 LOGE("rsTypeAdd: Bad dimension");
180 //error
181 return;
182 }
183
184 // todo: implement array support
185
186}
187
188RsType rsi_TypeCreate(Context *rsc)
189{
190 TypeState * stc = &rsc->mStateType;
191
192 Type * st = new Type();
193 st->setDimX(stc->mX);
194 st->setDimY(stc->mY);
195 st->setDimZ(stc->mZ);
196 st->setElement(stc->mElement.get());
197 st->setDimLOD(stc->mLOD);
198 st->setDimFaces(stc->mFaces);
199 st->compute();
200
201 stc->mAllTypes.add(st);
202
203 return st;
204}
205
206void rsi_TypeDestroy(Context *rsc, RsType vst)
207{
208 TypeState * stc = &rsc->mStateType;
209 Type * st = static_cast<Type *>(vst);
210
211 for (size_t ct = 0; ct < stc->mAllTypes.size(); ct++) {
212 if (stc->mAllTypes[ct] == st) {
213 stc->mAllTypes.removeAt(ct);
214 break;
215 }
216 }
217 delete st;
218}
219
220}
221}
222