blob: 670ea33a111ff12453e31f0bf490c19f797e5d48 [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
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800135void Type::dumpLOGV(const char *prefix) const {
Jason Samse12c1c52009-09-27 17:50:38 -0700136 char buf[1024];
137 ObjectBase::dumpLOGV(prefix);
138 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 -0800139 snprintf(buf, sizeof(buf), "%s element: ", prefix);
Jason Samse12c1c52009-09-27 17:50:38 -0700140 mElement->dumpLOGV(buf);
141}
142
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800143void Type::serialize(OStream *stream) const {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700144 // Need to identify ourselves
145 stream->addU32((uint32_t)getClassId());
146
147 String8 name(getName());
148 stream->addString(&name);
149
150 mElement->serialize(stream);
151
152 stream->addU32(mDimX);
153 stream->addU32(mDimY);
154 stream->addU32(mDimZ);
155
156 stream->addU8((uint8_t)(mDimLOD ? 1 : 0));
157 stream->addU8((uint8_t)(mFaces ? 1 : 0));
158}
159
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800160Type *Type::createFromStream(Context *rsc, IStream *stream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700161 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700162 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800163 if (classID != RS_A3D_CLASS_ID_TYPE) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700164 LOGE("type loading skipped due to invalid class id\n");
165 return NULL;
166 }
167
168 String8 name;
169 stream->loadString(&name);
170
171 Element *elem = Element::createFromStream(rsc, stream);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800172 if (!elem) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700173 return NULL;
174 }
175
Jason Samsf0c1df42010-10-26 13:09:17 -0700176 uint32_t x = stream->loadU32();
177 uint32_t y = stream->loadU32();
178 uint32_t z = stream->loadU32();
179 uint8_t lod = stream->loadU8();
180 uint8_t faces = stream->loadU8();
181 return Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 );
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700182}
183
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800184bool Type::getIsNp2() const {
Jason Samsef21edc2010-02-22 15:37:51 -0800185 uint32_t x = getDimX();
186 uint32_t y = getDimY();
187 uint32_t z = getDimZ();
188
189 if (x && (x & (x-1))) {
190 return true;
191 }
192 if (y && (y & (y-1))) {
193 return true;
194 }
195 if (z && (z & (z-1))) {
196 return true;
197 }
198 return false;
199}
200
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700201bool Type::isEqual(const Type *other) const {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800202 if (other == NULL) {
Alex Sakhartchouk383e5b12010-09-23 16:16:33 -0700203 return false;
204 }
205 if (other->getElement()->isEqual(getElement()) &&
206 other->getDimX() == mDimX &&
207 other->getDimY() == mDimY &&
208 other->getDimZ() == mDimZ &&
209 other->getDimLOD() == mDimLOD &&
210 other->getDimFaces() == mFaces) {
211 return true;
212 }
213 return false;
214}
Jason Samse12c1c52009-09-27 17:50:38 -0700215
Jason Samsf0c1df42010-10-26 13:09:17 -0700216Type * Type::getType(Context *rsc, const Element *e,
217 uint32_t dimX, uint32_t dimY, uint32_t dimZ,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800218 bool dimLOD, bool dimFaces) {
Jason Sams96abf812010-10-05 13:32:49 -0700219 TypeState * stc = &rsc->mStateType;
Jason Samsf0c1df42010-10-26 13:09:17 -0700220
221 ObjectBase::asyncLock();
Jason Sams96abf812010-10-05 13:32:49 -0700222 for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
223 Type *t = stc->mTypes[ct];
Jason Samsf0c1df42010-10-26 13:09:17 -0700224 if (t->getElement() != e) continue;
Jason Sams96abf812010-10-05 13:32:49 -0700225 if (t->getDimX() != dimX) continue;
Jason Samsf0c1df42010-10-26 13:09:17 -0700226 if (t->getDimY() != dimY) continue;
227 if (t->getDimZ() != dimZ) continue;
228 if (t->getDimLOD() != dimLOD) continue;
229 if (t->getDimFaces() != dimFaces) continue;
Jason Sams96abf812010-10-05 13:32:49 -0700230 t->incUserRef();
Jason Samsf0c1df42010-10-26 13:09:17 -0700231 ObjectBase::asyncUnlock();
Jason Sams96abf812010-10-05 13:32:49 -0700232 return t;
233 }
Jason Samsf0c1df42010-10-26 13:09:17 -0700234 ObjectBase::asyncUnlock();
235
Jason Sams96abf812010-10-05 13:32:49 -0700236
237 Type *nt = new Type(rsc);
Jason Samsf0c1df42010-10-26 13:09:17 -0700238 nt->mElement.set(e);
Jason Sams96abf812010-10-05 13:32:49 -0700239 nt->mDimX = dimX;
Jason Samsf0c1df42010-10-26 13:09:17 -0700240 nt->mDimY = dimY;
241 nt->mDimZ = dimZ;
242 nt->mDimLOD = dimLOD;
243 nt->mFaces = dimFaces;
Jason Sams96abf812010-10-05 13:32:49 -0700244 nt->compute();
Jason Samsf0c1df42010-10-26 13:09:17 -0700245 nt->incUserRef();
246
247 ObjectBase::asyncLock();
248 stc->mTypes.push(nt);
249 ObjectBase::asyncUnlock();
250
Jason Sams96abf812010-10-05 13:32:49 -0700251 return nt;
252}
253
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800254Type * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
Jason Samsf0c1df42010-10-26 13:09:17 -0700255 return getType(rsc, mElement.get(), dimX,
256 mDimY, mDimZ, mDimLOD, mFaces);
257}
258
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800259Type * Type::cloneAndResize2D(Context *rsc,
260 uint32_t dimX,
261 uint32_t dimY) const {
Jason Samsf0c1df42010-10-26 13:09:17 -0700262 return getType(rsc, mElement.get(), dimX, dimY,
263 mDimZ, mDimLOD, mFaces);
Jason Sams96abf812010-10-05 13:32:49 -0700264}
265
266
Jason Sams326e0dd2009-05-22 14:03:28 -0700267//////////////////////////////////////////////////
Jason Samse5ffb872009-08-09 17:01:55 -0700268//
Jason Sams326e0dd2009-05-22 14:03:28 -0700269namespace android {
270namespace renderscript {
271
Jason Sams326e0dd2009-05-22 14:03:28 -0700272}
273}
274
Jason Sams25413ec2010-12-06 15:59:59 -0800275RsType rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimX,
276 uint32_t dimY, uint32_t dimZ, bool mips, bool faces) {
Jason Sams2353ae32010-10-14 17:48:46 -0700277 Context *rsc = static_cast<Context *>(con);
278 Element *e = static_cast<Element *>(_e);
Jason Sams2353ae32010-10-14 17:48:46 -0700279
Jason Sams25413ec2010-12-06 15:59:59 -0800280 return Type::getType(rsc, e, dimX, dimY, dimZ, mips, faces);
Jason Sams2353ae32010-10-14 17:48:46 -0700281}
282
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800283void rsaTypeGetNativeData(RsContext con, RsType type, uint32_t *typeData, uint32_t typeDataSize) {
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700284 rsAssert(typeDataSize == 6);
285 // Pack the data in the follofing way mDimX; mDimY; mDimZ;
286 // mDimLOD; mDimFaces; mElement; into typeData
287 Type *t = static_cast<Type *>(type);
288
289 (*typeData++) = t->getDimX();
290 (*typeData++) = t->getDimY();
291 (*typeData++) = t->getDimZ();
292 (*typeData++) = t->getDimLOD();
293 (*typeData++) = t->getDimFaces() ? 1 : 0;
294 (*typeData++) = (uint32_t)t->getElement();
295 t->getElement()->incUserRef();
296}