blob: cd2be94979a8d524bfd97bb8f6f64ff235676b84 [file] [log] [blame]
Jason Samsd19f10d2009-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
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080022Type::Type(Context *rsc) : ObjectBase(rsc) {
Jason Samsd19f10d2009-05-22 14:03:28 -070023 mLODs = 0;
24 mLODCount = 0;
25 clear();
26}
27
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080028void Type::preDestroy() {
Jason Samse4c487a2010-02-17 15:38:10 -080029 for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
30 if (mRSC->mStateType.mTypes[ct] == this) {
31 mRSC->mStateType.mTypes.removeAt(ct);
32 break;
33 }
34 }
Jason Samsb38d5342010-10-21 14:06:55 -070035}
36
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080037Type::~Type() {
Jason Samsd19f10d2009-05-22 14:03:28 -070038 if (mLODs) {
39 delete [] mLODs;
Alex Sakhartchouk6f91cb62010-10-08 15:00:05 -070040 mLODs = NULL;
41 }
Jason Samsd19f10d2009-05-22 14:03:28 -070042}
43
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080044void Type::clear() {
Jason Samsd19f10d2009-05-22 14:03:28 -070045 if (mLODs) {
46 delete [] mLODs;
47 mLODs = NULL;
48 }
49 mDimX = 0;
50 mDimY = 0;
51 mDimZ = 0;
52 mDimLOD = 0;
53 mFaces = false;
54 mElement.clear();
55}
56
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080057TypeState::TypeState() {
Jason Samsd19f10d2009-05-22 14:03:28 -070058}
59
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080060TypeState::~TypeState() {
Jason Samsd19f10d2009-05-22 14:03:28 -070061}
62
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080063size_t Type::getOffsetForFace(uint32_t face) const {
Jason Samsd19f10d2009-05-22 14:03:28 -070064 rsAssert(mFaces);
65 return 0;
66}
67
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080068void Type::compute() {
Jason Samsd19f10d2009-05-22 14:03:28 -070069 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) {
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080081 if (mLODs){
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -070082 delete [] mLODs;
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -070083 }
Jason Samsd19f10d2009-05-22 14:03:28 -070084 mLODs = new LOD[mLODCount];
85 }
86
Jason Samsd19f10d2009-05-22 14:03:28 -070087 uint32_t tx = mDimX;
88 uint32_t ty = mDimY;
89 uint32_t tz = mDimZ;
90 size_t offset = 0;
91 for (uint32_t lod=0; lod < mLODCount; lod++) {
92 mLODs[lod].mX = tx;
93 mLODs[lod].mY = ty;
94 mLODs[lod].mZ = tz;
95 mLODs[lod].mOffset = offset;
Jason Samsd19f10d2009-05-22 14:03:28 -070096 offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
Jason Sams917cd4f2010-01-07 16:25:08 -080097 if (tx > 1) tx >>= 1;
98 if (ty > 1) ty >>= 1;
99 if (tz > 1) tz >>= 1;
Jason Samsd19f10d2009-05-22 14:03:28 -0700100 }
101
Jason Samsd19f10d2009-05-22 14:03:28 -0700102 // At this point the offset is the size of a mipmap chain;
103 mMipChainSizeBytes = offset;
104
105 if (mFaces) {
106 offset *= 6;
107 }
108 mTotalSizeBytes = offset;
Jason Samsd19f10d2009-05-22 14:03:28 -0700109}
110
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800111uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const {
Jason Samsd19f10d2009-05-22 14:03:28 -0700112 uint32_t offset = mLODs[lod].mOffset;
113 offset += x * mElement->getSizeBytes();
114 return offset;
115}
116
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800117uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const {
Jason Samsd19f10d2009-05-22 14:03:28 -0700118 uint32_t offset = mLODs[lod].mOffset;
119 offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
120 return offset;
121}
122
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800123uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const {
Jason Samsd19f10d2009-05-22 14:03:28 -0700124 uint32_t offset = mLODs[lod].mOffset;
125 offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
126 return offset;
127}
128
Jason Samsef70a202011-01-13 17:38:18 -0800129uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint32_t x, uint32_t y) const {
130 uint32_t offset = mLODs[lod].mOffset;
131 offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
132
133 if (face != 0) {
134 uint32_t faceOffset = getSizeBytes() / 6;
135 offset += faceOffset * face;
136 }
137 return offset;
138}
139
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800140void Type::dumpLOGV(const char *prefix) const {
Jason Sams3c0dfba2009-09-27 17:50:38 -0700141 char buf[1024];
142 ObjectBase::dumpLOGV(prefix);
Alex Sakhartchouka3b59602011-01-28 09:31:47 -0800143 LOGV("%s Type: x=%zu y=%zu z=%zu mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
Jason Samsadd9d962010-11-22 16:20:16 -0800144 snprintf(buf, sizeof(buf), "%s element: ", prefix);
Jason Sams3c0dfba2009-09-27 17:50:38 -0700145 mElement->dumpLOGV(buf);
146}
147
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800148void Type::serialize(OStream *stream) const {
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700149 // Need to identify ourselves
150 stream->addU32((uint32_t)getClassId());
151
152 String8 name(getName());
153 stream->addString(&name);
154
155 mElement->serialize(stream);
156
157 stream->addU32(mDimX);
158 stream->addU32(mDimY);
159 stream->addU32(mDimZ);
160
161 stream->addU8((uint8_t)(mDimLOD ? 1 : 0));
162 stream->addU8((uint8_t)(mFaces ? 1 : 0));
163}
164
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800165Type *Type::createFromStream(Context *rsc, IStream *stream) {
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700166 // First make sure we are reading the correct object
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700167 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800168 if (classID != RS_A3D_CLASS_ID_TYPE) {
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700169 LOGE("type loading skipped due to invalid class id\n");
170 return NULL;
171 }
172
173 String8 name;
174 stream->loadString(&name);
175
176 Element *elem = Element::createFromStream(rsc, stream);
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800177 if (!elem) {
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700178 return NULL;
179 }
180
Jason Sams31a7e422010-10-26 13:09:17 -0700181 uint32_t x = stream->loadU32();
182 uint32_t y = stream->loadU32();
183 uint32_t z = stream->loadU32();
184 uint8_t lod = stream->loadU8();
185 uint8_t faces = stream->loadU8();
186 return Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 );
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700187}
188
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800189bool Type::getIsNp2() const {
Jason Sams2978bfc2010-02-22 15:37:51 -0800190 uint32_t x = getDimX();
191 uint32_t y = getDimY();
192 uint32_t z = getDimZ();
193
194 if (x && (x & (x-1))) {
195 return true;
196 }
197 if (y && (y & (y-1))) {
198 return true;
199 }
200 if (z && (z & (z-1))) {
201 return true;
202 }
203 return false;
204}
205
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700206bool Type::isEqual(const Type *other) const {
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800207 if (other == NULL) {
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -0700208 return false;
209 }
210 if (other->getElement()->isEqual(getElement()) &&
211 other->getDimX() == mDimX &&
212 other->getDimY() == mDimY &&
213 other->getDimZ() == mDimZ &&
214 other->getDimLOD() == mDimLOD &&
215 other->getDimFaces() == mFaces) {
216 return true;
217 }
218 return false;
219}
Jason Sams3c0dfba2009-09-27 17:50:38 -0700220
Jason Sams31a7e422010-10-26 13:09:17 -0700221Type * Type::getType(Context *rsc, const Element *e,
222 uint32_t dimX, uint32_t dimY, uint32_t dimZ,
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800223 bool dimLOD, bool dimFaces) {
Jason Sams5edc6082010-10-05 13:32:49 -0700224 TypeState * stc = &rsc->mStateType;
Jason Sams31a7e422010-10-26 13:09:17 -0700225
226 ObjectBase::asyncLock();
Jason Sams5edc6082010-10-05 13:32:49 -0700227 for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
228 Type *t = stc->mTypes[ct];
Jason Sams31a7e422010-10-26 13:09:17 -0700229 if (t->getElement() != e) continue;
Jason Sams5edc6082010-10-05 13:32:49 -0700230 if (t->getDimX() != dimX) continue;
Jason Sams31a7e422010-10-26 13:09:17 -0700231 if (t->getDimY() != dimY) continue;
232 if (t->getDimZ() != dimZ) continue;
233 if (t->getDimLOD() != dimLOD) continue;
234 if (t->getDimFaces() != dimFaces) continue;
Jason Sams5edc6082010-10-05 13:32:49 -0700235 t->incUserRef();
Jason Sams31a7e422010-10-26 13:09:17 -0700236 ObjectBase::asyncUnlock();
Jason Sams5edc6082010-10-05 13:32:49 -0700237 return t;
238 }
Jason Sams31a7e422010-10-26 13:09:17 -0700239 ObjectBase::asyncUnlock();
240
Jason Sams5edc6082010-10-05 13:32:49 -0700241
242 Type *nt = new Type(rsc);
Jason Sams31a7e422010-10-26 13:09:17 -0700243 nt->mElement.set(e);
Jason Sams5edc6082010-10-05 13:32:49 -0700244 nt->mDimX = dimX;
Jason Sams31a7e422010-10-26 13:09:17 -0700245 nt->mDimY = dimY;
246 nt->mDimZ = dimZ;
247 nt->mDimLOD = dimLOD;
248 nt->mFaces = dimFaces;
Jason Sams5edc6082010-10-05 13:32:49 -0700249 nt->compute();
Jason Sams31a7e422010-10-26 13:09:17 -0700250 nt->incUserRef();
251
252 ObjectBase::asyncLock();
253 stc->mTypes.push(nt);
254 ObjectBase::asyncUnlock();
255
Jason Sams5edc6082010-10-05 13:32:49 -0700256 return nt;
257}
258
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800259Type * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
Jason Sams31a7e422010-10-26 13:09:17 -0700260 return getType(rsc, mElement.get(), dimX,
261 mDimY, mDimZ, mDimLOD, mFaces);
262}
263
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800264Type * Type::cloneAndResize2D(Context *rsc,
265 uint32_t dimX,
266 uint32_t dimY) const {
Jason Sams31a7e422010-10-26 13:09:17 -0700267 return getType(rsc, mElement.get(), dimX, dimY,
268 mDimZ, mDimLOD, mFaces);
Jason Sams5edc6082010-10-05 13:32:49 -0700269}
270
271
Jason Samsd19f10d2009-05-22 14:03:28 -0700272//////////////////////////////////////////////////
Jason Sams1bada8c2009-08-09 17:01:55 -0700273//
Jason Samsd19f10d2009-05-22 14:03:28 -0700274namespace android {
275namespace renderscript {
276
Jason Samsd19f10d2009-05-22 14:03:28 -0700277}
278}
279
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800280RsType rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimX,
281 uint32_t dimY, uint32_t dimZ, bool mips, bool faces) {
Jason Sams3b9c52a2010-10-14 17:48:46 -0700282 Context *rsc = static_cast<Context *>(con);
283 Element *e = static_cast<Element *>(_e);
Jason Sams3b9c52a2010-10-14 17:48:46 -0700284
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800285 return Type::getType(rsc, e, dimX, dimY, dimZ, mips, faces);
Jason Sams3b9c52a2010-10-14 17:48:46 -0700286}
287
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800288void rsaTypeGetNativeData(RsContext con, RsType type, uint32_t *typeData, uint32_t typeDataSize) {
Alex Sakhartchouk581cc642010-10-27 14:10:07 -0700289 rsAssert(typeDataSize == 6);
290 // Pack the data in the follofing way mDimX; mDimY; mDimZ;
291 // mDimLOD; mDimFaces; mElement; into typeData
292 Type *t = static_cast<Type *>(type);
293
294 (*typeData++) = t->getDimX();
295 (*typeData++) = t->getDimY();
296 (*typeData++) = t->getDimZ();
297 (*typeData++) = t->getDimLOD();
298 (*typeData++) = t->getDimFaces() ? 1 : 0;
299 (*typeData++) = (uint32_t)t->getElement();
300 t->getElement()->incUserRef();
301}