blob: cc07412c0ed8c22ef0752b1a483159ac359f1b4c [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
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070017#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Sams326e0dd2009-05-22 14:03:28 -070018#include "rsContext.h"
Jason Samse5ffb872009-08-09 17:01:55 -070019#include <GLES/gl.h>
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070020#else
21#include "rsContextHostStub.h"
22#include <OpenGL/gl.h>
23#endif
Jason Sams326e0dd2009-05-22 14:03:28 -070024
25using namespace android;
26using namespace android::renderscript;
27
Jason Samse514b452009-09-25 14:51:22 -070028Type::Type(Context *rsc) : ObjectBase(rsc)
Jason Sams326e0dd2009-05-22 14:03:28 -070029{
30 mLODs = 0;
31 mLODCount = 0;
32 clear();
33}
34
Jason Sams225afd32010-10-21 14:06:55 -070035void Type::preDestroy()
Jason Sams326e0dd2009-05-22 14:03:28 -070036{
Jason Sams81549542010-02-17 15:38:10 -080037 for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
38 if (mRSC->mStateType.mTypes[ct] == this) {
39 mRSC->mStateType.mTypes.removeAt(ct);
40 break;
41 }
42 }
Jason Sams225afd32010-10-21 14:06:55 -070043}
44
45Type::~Type()
46{
Jason Sams326e0dd2009-05-22 14:03:28 -070047 if (mLODs) {
48 delete [] mLODs;
Alex Sakhartchouk700ba382010-10-08 15:00:05 -070049 mLODs = NULL;
50 }
Jason Sams326e0dd2009-05-22 14:03:28 -070051}
52
53void Type::clear()
54{
55 if (mLODs) {
56 delete [] mLODs;
57 mLODs = NULL;
58 }
59 mDimX = 0;
60 mDimY = 0;
61 mDimZ = 0;
62 mDimLOD = 0;
63 mFaces = false;
64 mElement.clear();
65}
66
67TypeState::TypeState()
68{
69}
70
71TypeState::~TypeState()
72{
73}
74
75size_t Type::getOffsetForFace(uint32_t face) const
76{
77 rsAssert(mFaces);
78 return 0;
79}
80
81void Type::compute()
82{
Jason Sams326e0dd2009-05-22 14:03:28 -070083 uint32_t oldLODCount = mLODCount;
84 if (mDimLOD) {
85 uint32_t l2x = rsFindHighBit(mDimX) + 1;
86 uint32_t l2y = rsFindHighBit(mDimY) + 1;
87 uint32_t l2z = rsFindHighBit(mDimZ) + 1;
88
89 mLODCount = rsMax(l2x, l2y);
90 mLODCount = rsMax(mLODCount, l2z);
91 } else {
92 mLODCount = 1;
93 }
94 if (mLODCount != oldLODCount) {
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -070095 if(mLODs){
96 delete [] mLODs;
Alex Sakhartchouk417e6a42010-07-15 11:33:03 -070097 }
Jason Sams326e0dd2009-05-22 14:03:28 -070098 mLODs = new LOD[mLODCount];
99 }
100
Jason Sams326e0dd2009-05-22 14:03:28 -0700101 uint32_t tx = mDimX;
102 uint32_t ty = mDimY;
103 uint32_t tz = mDimZ;
104 size_t offset = 0;
105 for (uint32_t lod=0; lod < mLODCount; lod++) {
106 mLODs[lod].mX = tx;
107 mLODs[lod].mY = ty;
108 mLODs[lod].mZ = tz;
109 mLODs[lod].mOffset = offset;
Jason Sams326e0dd2009-05-22 14:03:28 -0700110 offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
Jason Sams7c528982010-01-07 16:25:08 -0800111 if (tx > 1) tx >>= 1;
112 if (ty > 1) ty >>= 1;
113 if (tz > 1) tz >>= 1;
Jason Sams326e0dd2009-05-22 14:03:28 -0700114 }
115
Jason Sams326e0dd2009-05-22 14:03:28 -0700116 // At this point the offset is the size of a mipmap chain;
117 mMipChainSizeBytes = offset;
118
119 if (mFaces) {
120 offset *= 6;
121 }
122 mTotalSizeBytes = offset;
Jason Sams326e0dd2009-05-22 14:03:28 -0700123}
124
125uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const
126{
127 uint32_t offset = mLODs[lod].mOffset;
128 offset += x * mElement->getSizeBytes();
129 return offset;
130}
131
132uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const
133{
134 uint32_t offset = mLODs[lod].mOffset;
135 offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
136 return offset;
137}
138
139uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const
140{
141 uint32_t offset = mLODs[lod].mOffset;
142 offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
143 return offset;
144}
145
Jason Samse12c1c52009-09-27 17:50:38 -0700146void Type::dumpLOGV(const char *prefix) const
147{
148 char buf[1024];
149 ObjectBase::dumpLOGV(prefix);
150 LOGV("%s Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
151 sprintf(buf, "%s element: ", prefix);
152 mElement->dumpLOGV(buf);
153}
154
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700155void Type::serialize(OStream *stream) const
156{
157 // Need to identify ourselves
158 stream->addU32((uint32_t)getClassId());
159
160 String8 name(getName());
161 stream->addString(&name);
162
163 mElement->serialize(stream);
164
165 stream->addU32(mDimX);
166 stream->addU32(mDimY);
167 stream->addU32(mDimZ);
168
169 stream->addU8((uint8_t)(mDimLOD ? 1 : 0));
170 stream->addU8((uint8_t)(mFaces ? 1 : 0));
171}
172
173Type *Type::createFromStream(Context *rsc, IStream *stream)
174{
175 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700176 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
177 if(classID != RS_A3D_CLASS_ID_TYPE) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700178 LOGE("type loading skipped due to invalid class id\n");
179 return NULL;
180 }
181
182 String8 name;
183 stream->loadString(&name);
184
185 Element *elem = Element::createFromStream(rsc, stream);
186 if(!elem) {
187 return NULL;
188 }
189
Jason Samsf0c1df42010-10-26 13:09:17 -0700190 uint32_t x = stream->loadU32();
191 uint32_t y = stream->loadU32();
192 uint32_t z = stream->loadU32();
193 uint8_t lod = stream->loadU8();
194 uint8_t faces = stream->loadU8();
195 return Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 );
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700196}
197
Jason Samsef21edc2010-02-22 15:37:51 -0800198bool Type::getIsNp2() const
199{
200 uint32_t x = getDimX();
201 uint32_t y = getDimY();
202 uint32_t z = getDimZ();
203
204 if (x && (x & (x-1))) {
205 return true;
206 }
207 if (y && (y & (y-1))) {
208 return true;
209 }
210 if (z && (z & (z-1))) {
211 return true;
212 }
213 return false;
214}
215
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700216bool Type::isEqual(const Type *other) const {
217 if(other == NULL) {
218 return false;
219 }
220 if (other->getElement()->isEqual(getElement()) &&
221 other->getDimX() == mDimX &&
222 other->getDimY() == mDimY &&
223 other->getDimZ() == mDimZ &&
224 other->getDimLOD() == mDimLOD &&
225 other->getDimFaces() == mFaces) {
226 return true;
227 }
228 return false;
229}
Jason Samse12c1c52009-09-27 17:50:38 -0700230
Jason Samsf0c1df42010-10-26 13:09:17 -0700231Type * Type::getType(Context *rsc, const Element *e,
232 uint32_t dimX, uint32_t dimY, uint32_t dimZ,
233 bool dimLOD, bool dimFaces)
Jason Sams96abf812010-10-05 13:32:49 -0700234{
235 TypeState * stc = &rsc->mStateType;
Jason Samsf0c1df42010-10-26 13:09:17 -0700236
237 ObjectBase::asyncLock();
Jason Sams96abf812010-10-05 13:32:49 -0700238 for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
239 Type *t = stc->mTypes[ct];
Jason Samsf0c1df42010-10-26 13:09:17 -0700240 if (t->getElement() != e) continue;
Jason Sams96abf812010-10-05 13:32:49 -0700241 if (t->getDimX() != dimX) continue;
Jason Samsf0c1df42010-10-26 13:09:17 -0700242 if (t->getDimY() != dimY) continue;
243 if (t->getDimZ() != dimZ) continue;
244 if (t->getDimLOD() != dimLOD) continue;
245 if (t->getDimFaces() != dimFaces) continue;
Jason Sams96abf812010-10-05 13:32:49 -0700246 t->incUserRef();
Jason Samsf0c1df42010-10-26 13:09:17 -0700247 ObjectBase::asyncUnlock();
Jason Sams96abf812010-10-05 13:32:49 -0700248 return t;
249 }
Jason Samsf0c1df42010-10-26 13:09:17 -0700250 ObjectBase::asyncUnlock();
251
Jason Sams96abf812010-10-05 13:32:49 -0700252
253 Type *nt = new Type(rsc);
Jason Samsf0c1df42010-10-26 13:09:17 -0700254 nt->mElement.set(e);
Jason Sams96abf812010-10-05 13:32:49 -0700255 nt->mDimX = dimX;
Jason Samsf0c1df42010-10-26 13:09:17 -0700256 nt->mDimY = dimY;
257 nt->mDimZ = dimZ;
258 nt->mDimLOD = dimLOD;
259 nt->mFaces = dimFaces;
Jason Sams96abf812010-10-05 13:32:49 -0700260 nt->compute();
Jason Samsf0c1df42010-10-26 13:09:17 -0700261 nt->incUserRef();
262
263 ObjectBase::asyncLock();
264 stc->mTypes.push(nt);
265 ObjectBase::asyncUnlock();
266
Jason Sams96abf812010-10-05 13:32:49 -0700267 return nt;
268}
269
Jason Samsf0c1df42010-10-26 13:09:17 -0700270Type * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const
271{
272 return getType(rsc, mElement.get(), dimX,
273 mDimY, mDimZ, mDimLOD, mFaces);
274}
275
Jason Sams96abf812010-10-05 13:32:49 -0700276Type * Type::cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const
277{
Jason Samsf0c1df42010-10-26 13:09:17 -0700278 return getType(rsc, mElement.get(), dimX, dimY,
279 mDimZ, mDimLOD, mFaces);
Jason Sams96abf812010-10-05 13:32:49 -0700280}
281
282
Jason Sams326e0dd2009-05-22 14:03:28 -0700283//////////////////////////////////////////////////
Jason Samse5ffb872009-08-09 17:01:55 -0700284//
Jason Sams326e0dd2009-05-22 14:03:28 -0700285namespace android {
286namespace renderscript {
287
Jason Sams326e0dd2009-05-22 14:03:28 -0700288}
289}
290
Jason Sams225afd32010-10-21 14:06:55 -0700291RsType rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimCount,
Jason Sams2353ae32010-10-14 17:48:46 -0700292 const RsDimension *dims, const uint32_t *vals)
293{
294 Context *rsc = static_cast<Context *>(con);
295 Element *e = static_cast<Element *>(_e);
296 TypeState * stc = &rsc->mStateType;
297
298 uint32_t dimX = 0;
299 uint32_t dimY = 0;
300 uint32_t dimZ = 0;
301 uint32_t dimLOD = 0;
302 uint32_t dimFaces = 0;
303
304 for (uint32_t ct=0; ct < dimCount; ct++) {
305 switch(dims[ct]) {
306 case RS_DIMENSION_X: dimX = vals[ct]; break;
307 case RS_DIMENSION_Y: dimY = vals[ct]; break;
308 case RS_DIMENSION_Z: dimZ = vals[ct]; break;
309 case RS_DIMENSION_LOD: dimLOD = vals[ct]; break;
310 case RS_DIMENSION_FACE: dimFaces = vals[ct]; break;
311
312 default:
313 LOGE("rsaTypeCreate: Bad dimension");
314 rsAssert(0);
315 }
316 }
317
Jason Samsf0c1df42010-10-26 13:09:17 -0700318 return Type::getType(rsc, e, dimX, dimY, dimZ, dimLOD, dimFaces);
Jason Sams2353ae32010-10-14 17:48:46 -0700319}
320
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700321void rsaTypeGetNativeData(RsContext con, RsType type, uint32_t *typeData, uint32_t typeDataSize)
322{
323 rsAssert(typeDataSize == 6);
324 // Pack the data in the follofing way mDimX; mDimY; mDimZ;
325 // mDimLOD; mDimFaces; mElement; into typeData
326 Type *t = static_cast<Type *>(type);
327
328 (*typeData++) = t->getDimX();
329 (*typeData++) = t->getDimY();
330 (*typeData++) = t->getDimZ();
331 (*typeData++) = t->getDimLOD();
332 (*typeData++) = t->getDimFaces() ? 1 : 0;
333 (*typeData++) = (uint32_t)t->getElement();
334 t->getElement()->incUserRef();
335}