Type.java revision 20fbd01335f3a41ab78e0bb9f70124665afb1e3b
1/*
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
19
20import java.lang.reflect.Field;
21import android.util.Log;
22
23/**
24 * <p>Type is an allocation template. It consists of an Element and one or more
25 * dimensions. It describes only the layout of memory but does not allocate any
26 * storage for the data that is described.</p>
27 *
28 * <p>A Type consists of several dimensions. Those are X, Y, Z, LOD (level of
29 * detail), Faces (faces of a cube map).  The X,Y,Z dimensions can be assigned
30 * any positive integral value within the constraints of available memory.  A
31 * single dimension allocation would have an X dimension of greater than zero
32 * while the Y and Z dimensions would be zero to indicate not present.  In this
33 * regard an allocation of x=10, y=1 would be considered 2 dimensionsal while
34 * x=10, y=0 would be considered 1 dimensional.</p>
35 *
36 * <p>The LOD and Faces dimensions are booleans to indicate present or not present.</p>
37 *
38 **/
39public class Type extends BaseObj {
40    int mDimX;
41    int mDimY;
42    int mDimZ;
43    boolean mDimMipmaps;
44    boolean mDimFaces;
45    int mElementCount;
46    Element mElement;
47
48    public enum CubemapFace {
49        POSITIVE_X (0),
50        NEGATIVE_X (1),
51        POSITIVE_Y (2),
52        NEGATIVE_Y (3),
53        POSITIVE_Z (4),
54        NEGATIVE_Z (5),
55        @Deprecated
56        POSITVE_X (0),
57        @Deprecated
58        POSITVE_Y (2),
59        @Deprecated
60        POSITVE_Z (4);
61
62        int mID;
63        CubemapFace(int id) {
64            mID = id;
65        }
66    }
67
68    /**
69     * Return the element associated with this Type.
70     *
71     * @return Element
72     */
73    public Element getElement() {
74        return mElement;
75    }
76
77    /**
78     * Return the value of the X dimension.
79     *
80     * @return int
81     */
82    public int getX() {
83        return mDimX;
84    }
85
86    /**
87     * Return the value of the Y dimension or 0 for a 1D allocation.
88     *
89     * @return int
90     */
91    public int getY() {
92        return mDimY;
93    }
94
95    /**
96     * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
97     *
98     * @return int
99     */
100    public int getZ() {
101        return mDimZ;
102    }
103
104    /**
105     * Return if the Type has a mipmap chain.
106     *
107     * @return boolean
108     */
109    public boolean hasMipmaps() {
110        return mDimMipmaps;
111    }
112
113    /**
114     * Return if the Type is a cube map.
115     *
116     * @return boolean
117     */
118    public boolean hasFaces() {
119        return mDimFaces;
120    }
121
122    /**
123     * Return the total number of accessable cells in the Type.
124     *
125     * @return int
126     */
127    public int getCount() {
128        return mElementCount;
129    }
130
131    void calcElementCount() {
132        boolean hasLod = hasMipmaps();
133        int x = getX();
134        int y = getY();
135        int z = getZ();
136        int faces = 1;
137        if (hasFaces()) {
138            faces = 6;
139        }
140        if (x == 0) {
141            x = 1;
142        }
143        if (y == 0) {
144            y = 1;
145        }
146        if (z == 0) {
147            z = 1;
148        }
149
150        int count = x * y * z * faces;
151
152        while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
153            if(x > 1) {
154                x >>= 1;
155            }
156            if(y > 1) {
157                y >>= 1;
158            }
159            if(z > 1) {
160                z >>= 1;
161            }
162
163            count += x * y * z * faces;
164        }
165        mElementCount = count;
166    }
167
168
169    Type(int id, RenderScript rs) {
170        super(id, rs);
171    }
172
173    @Override
174    void updateFromNative() {
175        // We have 6 integer to obtain mDimX; mDimY; mDimZ;
176        // mDimLOD; mDimFaces; mElement;
177        int[] dataBuffer = new int[6];
178        mRS.nTypeGetNativeData(getID(), dataBuffer);
179
180        mDimX = dataBuffer[0];
181        mDimY = dataBuffer[1];
182        mDimZ = dataBuffer[2];
183        mDimMipmaps = dataBuffer[3] == 1 ? true : false;
184        mDimFaces = dataBuffer[4] == 1 ? true : false;
185
186        int elementID = dataBuffer[5];
187        if(elementID != 0) {
188            mElement = new Element(elementID, mRS);
189            mElement.updateFromNative();
190        }
191        calcElementCount();
192    }
193
194    /**
195     * Builder class for Type.
196     *
197     */
198    public static class Builder {
199        RenderScript mRS;
200        int mDimX = 1;
201        int mDimY;
202        int mDimZ;
203        boolean mDimMipmaps;
204        boolean mDimFaces;
205
206        Element mElement;
207
208        /**
209         * Create a new builder object.
210         *
211         * @param rs
212         * @param e The element for the type to be created.
213         */
214        public Builder(RenderScript rs, Element e) {
215            e.checkValid();
216            mRS = rs;
217            mElement = e;
218        }
219
220        /**
221         * Add a dimension to the Type.
222         *
223         *
224         * @param value
225         */
226        public Builder setX(int value) {
227            if(value < 1) {
228                throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid.");
229            }
230            mDimX = value;
231            return this;
232        }
233
234        public Builder setY(int value) {
235            if(value < 1) {
236                throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid.");
237            }
238            mDimY = value;
239            return this;
240        }
241
242        public Builder setMipmaps(boolean value) {
243            mDimMipmaps = value;
244            return this;
245        }
246
247        public Builder setFaces(boolean value) {
248            mDimFaces = value;
249            return this;
250        }
251
252
253        /**
254         * Validate structure and create a new type.
255         *
256         * @return Type
257         */
258        public Type create() {
259            if (mDimZ > 0) {
260                if ((mDimX < 1) || (mDimY < 1)) {
261                    throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
262                }
263                if (mDimFaces) {
264                    throw new RSInvalidStateException("Cube maps not supported with 3D types.");
265                }
266            }
267            if (mDimY > 0) {
268                if (mDimX < 1) {
269                    throw new RSInvalidStateException("X dimension required when Y is present.");
270                }
271            }
272            if (mDimFaces) {
273                if (mDimY < 1) {
274                    throw new RSInvalidStateException("Cube maps require 2D Types.");
275                }
276            }
277
278            int id = mRS.nTypeCreate(mElement.getID(), mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces);
279            Type t = new Type(id, mRS);
280            t.mElement = mElement;
281            t.mDimX = mDimX;
282            t.mDimY = mDimY;
283            t.mDimZ = mDimZ;
284            t.mDimMipmaps = mDimMipmaps;
285            t.mDimFaces = mDimFaces;
286
287            t.calcElementCount();
288            return t;
289        }
290    }
291
292}
293