blob: d7b5f1204361b22a5fc87f72ae48017d0c91a9d5 [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
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080028Type::Type(Context *rsc) : ObjectBase(rsc) {
Jason Sams326e0dd2009-05-22 14:03:28 -070029 mLODs = 0;
30 mLODCount = 0;
31 clear();
32}
33
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080034void Type::preDestroy() {
Jason Sams81549542010-02-17 15:38:10 -080035 for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
36 if (mRSC->mStateType.mTypes[ct] == this) {
37 mRSC->mStateType.mTypes.removeAt(ct);
38 break;
39 }
40 }
Jason Sams225afd32010-10-21 14:06:55 -070041}
42
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080043Type::~Type() {
Jason Sams326e0dd2009-05-22 14:03:28 -070044 if (mLODs) {
45 delete [] mLODs;
Alex Sakhartchouk700ba382010-10-08 15:00:05 -070046 mLODs = NULL;
47 }
Jason Sams326e0dd2009-05-22 14:03:28 -070048}
49
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080050void Type::clear() {
Jason Sams326e0dd2009-05-22 14:03:28 -070051 if (mLODs) {
52 delete [] mLODs;
53 mLODs = NULL;
54 }
55 mDimX = 0;
56 mDimY = 0;
57 mDimZ = 0;
58 mDimLOD = 0;
59 mFaces = false;
60 mElement.clear();
61}
62
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080063TypeState::TypeState() {
Jason Sams326e0dd2009-05-22 14:03:28 -070064}
65
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080066TypeState::~TypeState() {
Jason Sams326e0dd2009-05-22 14:03:28 -070067}
68
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080069size_t Type::getOffsetForFace(uint32_t face) const {
Jason Sams326e0dd2009-05-22 14:03:28 -070070 rsAssert(mFaces);
71 return 0;
72}
73
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080074void Type::compute() {
Jason Sams326e0dd2009-05-22 14:03:28 -070075 uint32_t oldLODCount = mLODCount;
76 if (mDimLOD) {
77 uint32_t l2x = rsFindHighBit(mDimX) + 1;
78 uint32_t l2y = rsFindHighBit(mDimY) + 1;
79 uint32_t l2z = rsFindHighBit(mDimZ) + 1;
80
81 mLODCount = rsMax(l2x, l2y);
82 mLODCount = rsMax(mLODCount, l2z);
83 } else {
84 mLODCount = 1;
85 }
86 if (mLODCount != oldLODCount) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080087 if (mLODs){
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -070088 delete [] mLODs;
Alex Sakhartchouk417e6a42010-07-15 11:33:03 -070089 }
Jason Sams326e0dd2009-05-22 14:03:28 -070090 mLODs = new LOD[mLODCount];
91 }
92
Jason Sams326e0dd2009-05-22 14:03:28 -070093 uint32_t tx = mDimX;
94 uint32_t ty = mDimY;
95 uint32_t tz = mDimZ;
96 size_t offset = 0;
97 for (uint32_t lod=0; lod < mLODCount; lod++) {
98 mLODs[lod].mX = tx;
99 mLODs[lod].mY = ty;
100 mLODs[lod].mZ = tz;
101 mLODs[lod].mOffset = offset;
Jason Sams326e0dd2009-05-22 14:03:28 -0700102 offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
Jason Sams7c528982010-01-07 16:25:08 -0800103 if (tx > 1) tx >>= 1;
104 if (ty > 1) ty >>= 1;
105 if (tz > 1) tz >>= 1;
Jason Sams326e0dd2009-05-22 14:03:28 -0700106 }
107
Jason Sams326e0dd2009-05-22 14:03:28 -0700108 // At this point the offset is the size of a mipmap chain;
109 mMipChainSizeBytes = offset;
110
111 if (mFaces) {
112 offset *= 6;
113 }
114 mTotalSizeBytes = offset;
Jason Sams326e0dd2009-05-22 14:03:28 -0700115}
116
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800117uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const {
Jason Sams326e0dd2009-05-22 14:03:28 -0700118 uint32_t offset = mLODs[lod].mOffset;
119 offset += x * mElement->getSizeBytes();
120 return offset;
121}
122
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800123uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const {
Jason Sams326e0dd2009-05-22 14:03:28 -0700124 uint32_t offset = mLODs[lod].mOffset;
125 offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
126 return offset;
127}
128
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800129uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const {
Jason Sams326e0dd2009-05-22 14:03:28 -0700130 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
Jason Samsbcac9342011-01-13 17:38:18 -0800135uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint32_t x, uint32_t y) const {
136 uint32_t offset = mLODs[lod].mOffset;
137 offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
138
139 if (face != 0) {
140 uint32_t faceOffset = getSizeBytes() / 6;
141 offset += faceOffset * face;
142 }
143 return offset;
144}
145
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800146void Type::dumpLOGV(const char *prefix) const {
Jason Samse12c1c52009-09-27 17:50:38 -0700147 char buf[1024];
148 ObjectBase::dumpLOGV(prefix);
149 LOGV("%s Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
Jason Sams87319de2010-11-22 16:20:16 -0800150 snprintf(buf, sizeof(buf), "%s element: ", prefix);
Jason Samse12c1c52009-09-27 17:50:38 -0700151 mElement->dumpLOGV(buf);
152}
153
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800154void Type::serialize(OStream *stream) const {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700155 // Need to identify ourselves
156 stream->addU32((uint32_t)getClassId());
157
158 String8 name(getName());
159 stream->addString(&name);
160
161 mElement->serialize(stream);
162
163 stream->addU32(mDimX);
164 stream->addU32(mDimY);
165 stream->addU32(mDimZ);
166
167 stream->addU8((uint8_t)(mDimLOD ? 1 : 0));
168 stream->addU8((uint8_t)(mFaces ? 1 : 0));
169}
170
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800171Type *Type::createFromStream(Context *rsc, IStream *stream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700172 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700173 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800174 if (classID != RS_A3D_CLASS_ID_TYPE) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700175 LOGE("type loading skipped due to invalid class id\n");
176 return NULL;
177 }
178
179 String8 name;
180 stream->loadString(&name);
181
182 Element *elem = Element::createFromStream(rsc, stream);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800183 if (!elem) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700184 return NULL;
185 }
186
Jason Samsf0c1df42010-10-26 13:09:17 -0700187 uint32_t x = stream->loadU32();
188 uint32_t y = stream->loadU32();
189 uint32_t z = stream->loadU32();
190 uint8_t lod = stream->loadU8();
191 uint8_t faces = stream->loadU8();
192 return Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 );
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700193}
194
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800195bool Type::getIsNp2() const {
Jason Samsef21edc2010-02-22 15:37:51 -0800196 uint32_t x = getDimX();
197 uint32_t y = getDimY();
198 uint32_t z = getDimZ();
199
200 if (x && (x & (x-1))) {
201 return true;
202 }
203 if (y && (y & (y-1))) {
204 return true;
205 }
206 if (z && (z & (z-1))) {
207 return true;
208 }
209 return false;
210}
211
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700212bool Type::isEqual(const Type *other) const {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800213 if (other == NULL) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700214 return false;
215 }
216 if (other->getElement()->isEqual(getElement()) &&
217 other->getDimX() == mDimX &&
218 other->getDimY() == mDimY &&
219 other->getDimZ() == mDimZ &&
220 other->getDimLOD() == mDimLOD &&
221 other->getDimFaces() == mFaces) {
222 return true;
223 }
224 return false;
225}
Jason Samse12c1c52009-09-27 17:50:38 -0700226
Jason Samsf0c1df42010-10-26 13:09:17 -0700227Type * Type::getType(Context *rsc, const Element *e,
228 uint32_t dimX, uint32_t dimY, uint32_t dimZ,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800229 bool dimLOD, bool dimFaces) {
Jason Sams96abf812010-10-05 13:32:49 -0700230 TypeState * stc = &rsc->mStateType;
Jason Samsf0c1df42010-10-26 13:09:17 -0700231
232 ObjectBase::asyncLock();
Jason Sams96abf812010-10-05 13:32:49 -0700233 for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
234 Type *t = stc->mTypes[ct];
Jason Samsf0c1df42010-10-26 13:09:17 -0700235 if (t->getElement() != e) continue;
Jason Sams96abf812010-10-05 13:32:49 -0700236 if (t->getDimX() != dimX) continue;
Jason Samsf0c1df42010-10-26 13:09:17 -0700237 if (t->getDimY() != dimY) continue;
238 if (t->getDimZ() != dimZ) continue;
239 if (t->getDimLOD() != dimLOD) continue;
240 if (t->getDimFaces() != dimFaces) continue;
Jason Sams96abf812010-10-05 13:32:49 -0700241 t->incUserRef();
Jason Samsf0c1df42010-10-26 13:09:17 -0700242 ObjectBase::asyncUnlock();
Jason Sams96abf812010-10-05 13:32:49 -0700243 return t;
244 }
Jason Samsf0c1df42010-10-26 13:09:17 -0700245 ObjectBase::asyncUnlock();
246
Jason Sams96abf812010-10-05 13:32:49 -0700247
248 Type *nt = new Type(rsc);
Jason Samsf0c1df42010-10-26 13:09:17 -0700249 nt->mElement.set(e);
Jason Sams96abf812010-10-05 13:32:49 -0700250 nt->mDimX = dimX;
Jason Samsf0c1df42010-10-26 13:09:17 -0700251 nt->mDimY = dimY;
252 nt->mDimZ = dimZ;
253 nt->mDimLOD = dimLOD;
254 nt->mFaces = dimFaces;
Jason Sams96abf812010-10-05 13:32:49 -0700255 nt->compute();
Jason Samsf0c1df42010-10-26 13:09:17 -0700256 nt->incUserRef();
257
258 ObjectBase::asyncLock();
259 stc->mTypes.push(nt);
260 ObjectBase::asyncUnlock();
261
Jason Sams96abf812010-10-05 13:32:49 -0700262 return nt;
263}
264
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800265Type * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
Jason Samsf0c1df42010-10-26 13:09:17 -0700266 return getType(rsc, mElement.get(), dimX,
267 mDimY, mDimZ, mDimLOD, mFaces);
268}
269
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800270Type * Type::cloneAndResize2D(Context *rsc,
271 uint32_t dimX,
272 uint32_t dimY) const {
Jason Samsf0c1df42010-10-26 13:09:17 -0700273 return getType(rsc, mElement.get(), dimX, dimY,
274 mDimZ, mDimLOD, mFaces);
Jason Sams96abf812010-10-05 13:32:49 -0700275}
276
277
Jason Sams326e0dd2009-05-22 14:03:28 -0700278//////////////////////////////////////////////////
Jason Samse5ffb872009-08-09 17:01:55 -0700279//
Jason Sams326e0dd2009-05-22 14:03:28 -0700280namespace android {
281namespace renderscript {
282
Jason Sams326e0dd2009-05-22 14:03:28 -0700283}
284}
285
Jason Sams25413ec2010-12-06 15:59:59 -0800286RsType rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimX,
287 uint32_t dimY, uint32_t dimZ, bool mips, bool faces) {
Jason Sams2353ae32010-10-14 17:48:46 -0700288 Context *rsc = static_cast<Context *>(con);
289 Element *e = static_cast<Element *>(_e);
Jason Sams2353ae32010-10-14 17:48:46 -0700290
Jason Sams25413ec2010-12-06 15:59:59 -0800291 return Type::getType(rsc, e, dimX, dimY, dimZ, mips, faces);
Jason Sams2353ae32010-10-14 17:48:46 -0700292}
293
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800294void rsaTypeGetNativeData(RsContext con, RsType type, uint32_t *typeData, uint32_t typeDataSize) {
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700295 rsAssert(typeDataSize == 6);
296 // Pack the data in the follofing way mDimX; mDimY; mDimZ;
297 // mDimLOD; mDimFaces; mElement; into typeData
298 Type *t = static_cast<Type *>(type);
299
300 (*typeData++) = t->getDimX();
301 (*typeData++) = t->getDimY();
302 (*typeData++) = t->getDimZ();
303 (*typeData++) = t->getDimLOD();
304 (*typeData++) = t->getDimFaces() ? 1 : 0;
305 (*typeData++) = (uint32_t)t->getElement();
306 t->getElement()->incUserRef();
307}