blob: 44aee637a0c9e961ff1ec358a259c502b011d8bc [file] [log] [blame]
Jason Samsb8c5a842009-07-31 20:40:47 -07001/*
2 * Copyright (C) 2008 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
17package android.renderscript;
18
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -070019
Jason Sams43ee06852009-08-12 17:54:11 -070020import java.lang.reflect.Field;
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -070021import android.util.Log;
Jason Sams43ee06852009-08-12 17:54:11 -070022
Jason Samsb8c5a842009-07-31 20:40:47 -070023/**
24 * @hide
25 *
Jason Samsa1b13ed2010-11-12 14:58:37 -080026 * Type is an allocation template. It consists of an Element and one or more
27 * dimensions. It describes only the layout of memory but does not allocate and
28 * storage for the data thus described.
29 *
30 * A Type consists of several dimensions. Those are X, Y, Z, LOD (level of
31 * detail), Faces (faces of a cube map). The X,Y,Z dimensions can be assigned
32 * any positive integral value within the constraints of available memory. A
33 * single dimension allocation would have an X dimension of greater than zero
34 * while the Y and Z dimensions would be zero to indicate not present. In this
35 * regard an allocation of x=10, y=1 would be considered 2 dimensionsal while
36 * x=10, y=0 would be considered 1 dimensional.
37 *
38 * The LOD and Faces dimensions are booleans to indicate present or not present.
39 *
Jason Samsb8c5a842009-07-31 20:40:47 -070040 **/
41public class Type extends BaseObj {
Jason Sams768bc022009-09-21 19:41:04 -070042 int mDimX;
43 int mDimY;
44 int mDimZ;
45 boolean mDimLOD;
46 boolean mDimFaces;
47 int mElementCount;
Jason Sams1bada8c2009-08-09 17:01:55 -070048 Element mElement;
Jason Sams768bc022009-09-21 19:41:04 -070049
Jason Samsa1b13ed2010-11-12 14:58:37 -080050 /**
51 * Return the element associated with this Type.
52 *
53 * @return Element
54 */
Jason Samse17964e2010-01-04 16:52:27 -080055 public Element getElement() {
56 return mElement;
57 }
Jason Sams1bada8c2009-08-09 17:01:55 -070058
Jason Samsa1b13ed2010-11-12 14:58:37 -080059 /**
60 * Return the value of the X dimension.
61 *
62 * @return int
63 */
Jason Sams768bc022009-09-21 19:41:04 -070064 public int getX() {
65 return mDimX;
66 }
Jason Samsa1b13ed2010-11-12 14:58:37 -080067
68 /**
69 * Return the value of the Y dimension or 0 for a 1D allocation.
70 *
71 * @return int
72 */
Jason Sams768bc022009-09-21 19:41:04 -070073 public int getY() {
74 return mDimY;
75 }
Jason Samsa1b13ed2010-11-12 14:58:37 -080076
77 /**
78 * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
79 *
80 * @return int
81 */
Jason Sams768bc022009-09-21 19:41:04 -070082 public int getZ() {
83 return mDimZ;
84 }
Jason Samsa1b13ed2010-11-12 14:58:37 -080085
86 /**
87 * Return if the Type has a mipmap chain.
88 *
89 * @return boolean
90 */
Jason Sams768bc022009-09-21 19:41:04 -070091 public boolean getLOD() {
92 return mDimLOD;
93 }
Jason Samsa1b13ed2010-11-12 14:58:37 -080094
95 /**
96 * Return if the Type is a cube map.
97 *
98 * @return boolean
99 */
Jason Sams768bc022009-09-21 19:41:04 -0700100 public boolean getFaces() {
101 return mDimFaces;
102 }
Jason Samsa1b13ed2010-11-12 14:58:37 -0800103
104 /**
105 * Return the total number of accessable cells in the Type.
106 *
107 * @return int
108 */
Jason Sams768bc022009-09-21 19:41:04 -0700109 public int getElementCount() {
110 return mElementCount;
111 }
112
113 void calcElementCount() {
114 boolean hasLod = getLOD();
115 int x = getX();
116 int y = getY();
117 int z = getZ();
118 int faces = 1;
119 if(getFaces()) {
120 faces = 6;
121 }
122 if(x == 0) {
123 x = 1;
124 }
125 if(y == 0) {
126 y = 1;
127 }
128 if(z == 0) {
129 z = 1;
130 }
131
132 int count = x * y * z * faces;
133 if(hasLod && (x > 1) && (y > 1) && (z > 1)) {
134 if(x > 1) {
135 x >>= 1;
136 }
137 if(y > 1) {
138 y >>= 1;
139 }
140 if(z > 1) {
141 z >>= 1;
142 }
143
144 count += x * y * z * faces;
145 }
146 mElementCount = count;
147 }
148
149
Jason Samsb8c5a842009-07-31 20:40:47 -0700150 Type(int id, RenderScript rs) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700151 super(id, rs);
Jason Sams43ee06852009-08-12 17:54:11 -0700152 }
153
154 protected void finalize() throws Throwable {
Jason Sams43ee06852009-08-12 17:54:11 -0700155 super.finalize();
Jason Samsb8c5a842009-07-31 20:40:47 -0700156 }
157
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700158 @Override
159 void updateFromNative() {
160 // We have 6 integer to obtain mDimX; mDimY; mDimZ;
161 // mDimLOD; mDimFaces; mElement;
162 int[] dataBuffer = new int[6];
Jason Sams06d69de2010-11-09 17:11:40 -0800163 mRS.nTypeGetNativeData(getID(), dataBuffer);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700164
165 mDimX = dataBuffer[0];
166 mDimY = dataBuffer[1];
167 mDimZ = dataBuffer[2];
168 mDimLOD = dataBuffer[3] == 1 ? true : false;
169 mDimFaces = dataBuffer[4] == 1 ? true : false;
170
171 int elementID = dataBuffer[5];
172 if(elementID != 0) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700173 mElement = new Element(elementID, mRS);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700174 mElement.updateFromNative();
175 }
176 calcElementCount();
177 }
178
Jason Samsa1b13ed2010-11-12 14:58:37 -0800179 /**
180 * Builder class for Type.
181 *
182 */
Jason Samsb8c5a842009-07-31 20:40:47 -0700183 public static class Builder {
184 RenderScript mRS;
Jason Sams3b9c52a2010-10-14 17:48:46 -0700185 Dimension[] mDimensions;
186 int[] mDimensionValues;
Jason Sams22534172009-08-04 16:58:20 -0700187 int mEntryCount;
188 Element mElement;
Jason Samsb8c5a842009-07-31 20:40:47 -0700189
Jason Sams22534172009-08-04 16:58:20 -0700190 class Entry {
191 Dimension mDim;
192 int mValue;
Jason Samsb8c5a842009-07-31 20:40:47 -0700193 }
194
Jason Samsa1b13ed2010-11-12 14:58:37 -0800195 /**
196 * Create a new builder object.
197 *
198 * @param rs
199 * @param e The element for the type to be created.
200 */
Jason Sams22534172009-08-04 16:58:20 -0700201 public Builder(RenderScript rs, Element e) {
Jason Sams06d69de2010-11-09 17:11:40 -0800202 if(e.getID() == 0) {
Jason Samsc1d62102010-11-04 14:32:19 -0700203 throw new RSIllegalArgumentException("Invalid element.");
Jason Sams3c0dfba2009-09-27 17:50:38 -0700204 }
205
Jason Sams22534172009-08-04 16:58:20 -0700206 mRS = rs;
Jason Sams3b9c52a2010-10-14 17:48:46 -0700207 mDimensions = new Dimension[4];
208 mDimensionValues = new int[4];
Jason Sams22534172009-08-04 16:58:20 -0700209 mElement = e;
Jason Samsb8c5a842009-07-31 20:40:47 -0700210 }
211
Jason Samsa1b13ed2010-11-12 14:58:37 -0800212 /**
213 * Add a dimension to the Type.
214 *
215 *
216 * @param d
217 * @param value
218 */
Jason Samsb8c5a842009-07-31 20:40:47 -0700219 public void add(Dimension d, int value) {
Jason Sams3c0dfba2009-09-27 17:50:38 -0700220 if(value < 1) {
Jason Samsc1d62102010-11-04 14:32:19 -0700221 throw new RSIllegalArgumentException("Values of less than 1 for Dimensions are not valid.");
Jason Sams3c0dfba2009-09-27 17:50:38 -0700222 }
Jason Sams3b9c52a2010-10-14 17:48:46 -0700223 if(mDimensions.length >= mEntryCount) {
224 Dimension[] dn = new Dimension[mEntryCount + 8];
225 System.arraycopy(mDimensions, 0, dn, 0, mEntryCount);
226 mDimensions = dn;
227
228 int[] in = new int[mEntryCount + 8];
229 System.arraycopy(mDimensionValues, 0, in, 0, mEntryCount);
230 mDimensionValues = in;
Jason Sams22534172009-08-04 16:58:20 -0700231 }
Jason Sams3b9c52a2010-10-14 17:48:46 -0700232 mDimensions[mEntryCount] = d;
233 mDimensionValues[mEntryCount] = value;
Jason Sams22534172009-08-04 16:58:20 -0700234 mEntryCount++;
235 }
236
Jason Samsa1b13ed2010-11-12 14:58:37 -0800237 /**
238 * Validate structure and create a new type.
239 *
240 * @return Type
241 */
Jason Samsb8c5a842009-07-31 20:40:47 -0700242 public Type create() {
Jason Sams3b9c52a2010-10-14 17:48:46 -0700243 int dims[] = new int[mEntryCount];
244 for (int ct=0; ct < mEntryCount; ct++) {
245 dims[ct] = mDimensions[ct].mID;
246 }
247
248 int id = mRS.nTypeCreate(mElement.getID(), dims, mDimensionValues);
249 Type t = new Type(id, mRS);
Jason Sams1bada8c2009-08-09 17:01:55 -0700250 t.mElement = mElement;
Jason Sams768bc022009-09-21 19:41:04 -0700251
Jason Sams1bada8c2009-08-09 17:01:55 -0700252 for(int ct=0; ct < mEntryCount; ct++) {
Jason Sams3b9c52a2010-10-14 17:48:46 -0700253 if(mDimensions[ct] == Dimension.X) {
254 t.mDimX = mDimensionValues[ct];
Jason Sams768bc022009-09-21 19:41:04 -0700255 }
Jason Sams3b9c52a2010-10-14 17:48:46 -0700256 if(mDimensions[ct] == Dimension.Y) {
257 t.mDimY = mDimensionValues[ct];
Jason Sams768bc022009-09-21 19:41:04 -0700258 }
Jason Sams3b9c52a2010-10-14 17:48:46 -0700259 if(mDimensions[ct] == Dimension.Z) {
260 t.mDimZ = mDimensionValues[ct];
Jason Sams768bc022009-09-21 19:41:04 -0700261 }
Jason Sams3b9c52a2010-10-14 17:48:46 -0700262 if(mDimensions[ct] == Dimension.LOD) {
263 t.mDimLOD = mDimensionValues[ct] != 0;
Jason Sams768bc022009-09-21 19:41:04 -0700264 }
Jason Sams3b9c52a2010-10-14 17:48:46 -0700265 if(mDimensions[ct] == Dimension.FACE) {
266 t.mDimFaces = mDimensionValues[ct] != 0;
Jason Sams768bc022009-09-21 19:41:04 -0700267 }
Jason Sams1bada8c2009-08-09 17:01:55 -0700268 }
Jason Samsa1b13ed2010-11-12 14:58:37 -0800269
270 if (t.mDimZ > 0) {
271 if ((t.mDimX < 1) || (t.mDimY < 1)) {
272 throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
273 }
274 if (t.mDimFaces) {
275 throw new RSInvalidStateException("Cube maps not supported with 3D types.");
276 }
277 }
278 if (t.mDimY > 0) {
279 if (t.mDimX < 1) {
280 throw new RSInvalidStateException("X dimension required when Y is present.");
281 }
282 }
283 if (t.mDimFaces) {
284 if (t.mDimY < 1) {
285 throw new RSInvalidStateException("Cube maps require 2D Types.");
286 }
287 }
288
Jason Sams768bc022009-09-21 19:41:04 -0700289 t.calcElementCount();
Jason Sams1bada8c2009-08-09 17:01:55 -0700290 return t;
Jason Samsb8c5a842009-07-31 20:40:47 -0700291 }
292 }
293
294}