Type.java revision 032b2c2c8a3cf2c55f6f08557f2648d799766c4e
1/*
2 * Copyright (C) 2013 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.support.v8.renderscript;
18
19
20import java.lang.reflect.Field;
21
22import android.graphics.ImageFormat;
23import android.util.Log;
24
25/**
26 * <p>A Type describes the {@link android.renderscript.Element} and dimensions used for an {@link
27 * android.renderscript.Allocation} or a parallel operation. Types are created through {@link
28 * android.renderscript.Type.Builder}.</p>
29 *
30 * <p>A Type always includes an {@link android.renderscript.Element} and an X
31 * dimension. A Type may be multidimensional, up to three dimensions. A nonzero
32 * value in the Y or Z dimensions indicates that the dimension is present. Note
33 * that a Type with only a given X dimension and a Type with the same X
34 * dimension but Y = 1 are not equivalent.</p>
35 *
36 * <p>A Type also supports inclusion of level of detail (LOD) or cube map
37 * faces. LOD and cube map faces are booleans to indicate present or not
38 * present. </p>
39 *
40 * <p>A Type also supports YUV format information to support an {@link
41 * android.renderscript.Allocation} in a YUV format. The YUV formats supported
42 * are {@link android.graphics.ImageFormat#YV12} and {@link
43 * android.graphics.ImageFormat#NV21}.</p>
44 *
45 * <div class="special reference">
46 * <h3>Developer Guides</h3>
47 * <p>For more information about creating an application that uses RenderScript, read the
48 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
49 * </div>
50 **/
51public class Type extends BaseObj {
52    int mDimX;
53    int mDimY;
54    int mDimZ;
55    boolean mDimMipmaps;
56    boolean mDimFaces;
57    int mDimYuv;
58    int mElementCount;
59    Element mElement;
60
61    public enum CubemapFace {
62        POSITIVE_X (0),
63        NEGATIVE_X (1),
64        POSITIVE_Y (2),
65        NEGATIVE_Y (3),
66        POSITIVE_Z (4),
67        NEGATIVE_Z (5);
68
69        int mID;
70        CubemapFace(int id) {
71            mID = id;
72        }
73    }
74
75    /**
76     * Return the element associated with this Type.
77     *
78     * @return Element
79     */
80    public Element getElement() {
81        return mElement;
82    }
83
84    /**
85     * Return the value of the X dimension.
86     *
87     * @return int
88     */
89    public int getX() {
90        return mDimX;
91    }
92
93    /**
94     * Return the value of the Y dimension or 0 for a 1D allocation.
95     *
96     * @return int
97     */
98    public int getY() {
99        return mDimY;
100    }
101
102    /**
103     * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
104     *
105     * @return int
106     */
107    public int getZ() {
108        return mDimZ;
109    }
110
111    /**
112     * Get the YUV format
113     *
114     * @hide
115     *
116     * @return int
117     */
118    public int getYuv() {
119        return mDimYuv;
120    }
121
122    /**
123     * Return if the Type has a mipmap chain.
124     *
125     * @return boolean
126     */
127    public boolean hasMipmaps() {
128        return mDimMipmaps;
129    }
130
131    /**
132     * Return if the Type is a cube map.
133     *
134     * @return boolean
135     */
136    public boolean hasFaces() {
137        return mDimFaces;
138    }
139
140    /**
141     * Return the total number of accessable cells in the Type.
142     *
143     * @return int
144     */
145    public int getCount() {
146        return mElementCount;
147    }
148
149    void calcElementCount() {
150        boolean hasLod = hasMipmaps();
151        int x = getX();
152        int y = getY();
153        int z = getZ();
154        int faces = 1;
155        if (hasFaces()) {
156            faces = 6;
157        }
158        if (x == 0) {
159            x = 1;
160        }
161        if (y == 0) {
162            y = 1;
163        }
164        if (z == 0) {
165            z = 1;
166        }
167
168        int count = x * y * z * faces;
169
170        while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
171            if(x > 1) {
172                x >>= 1;
173            }
174            if(y > 1) {
175                y >>= 1;
176            }
177            if(z > 1) {
178                z >>= 1;
179            }
180
181            count += x * y * z * faces;
182        }
183        mElementCount = count;
184    }
185
186
187    Type(int id, RenderScript rs) {
188        super(id, rs);
189    }
190
191    /**
192     * Builder class for Type.
193     *
194     */
195    public static class Builder {
196        RenderScript mRS;
197        int mDimX = 1;
198        int mDimY;
199        int mDimZ;
200        boolean mDimMipmaps;
201        boolean mDimFaces;
202        int mYuv;
203
204        Element mElement;
205
206        /**
207         * Create a new builder object.
208         *
209         * @param rs
210         * @param e The element for the type to be created.
211         */
212        public Builder(RenderScript rs, Element e) {
213            e.checkValid();
214            mRS = rs;
215            mElement = e;
216        }
217
218        /**
219         * Add a dimension to the Type.
220         *
221         *
222         * @param value
223         */
224        public Builder setX(int value) {
225            if(value < 1) {
226                throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid.");
227            }
228            mDimX = value;
229            return this;
230        }
231
232        public Builder setY(int value) {
233            if(value < 1) {
234                throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid.");
235            }
236            mDimY = value;
237            return this;
238        }
239
240        public Builder setZ(int value) {
241            if(value < 1) {
242                throw new RSIllegalArgumentException("Values of less than 1 for Dimension Z are not valid.");
243            }
244            mDimZ = value;
245            return this;
246        }
247
248        public Builder setMipmaps(boolean value) {
249            mDimMipmaps = value;
250            return this;
251        }
252
253        public Builder setFaces(boolean value) {
254            mDimFaces = value;
255            return this;
256        }
257
258        /**
259         * Set the YUV layout for a Type.
260         *
261         * @hide
262         *
263         * @param yuvFormat {@link android.graphics.ImageFormat#YV12} or {@link android.graphics.ImageFormat#NV21}
264         */
265        public Builder setYuvFormat(int yuvFormat) {
266            switch (yuvFormat) {
267            case android.graphics.ImageFormat.NV21:
268            case android.graphics.ImageFormat.YV12:
269                break;
270
271            default:
272                throw new RSIllegalArgumentException("Only NV21 and YV12 are supported..");
273            }
274
275            mYuv = yuvFormat;
276            return this;
277        }
278
279
280        /**
281         * Validate structure and create a new Type.
282         *
283         * @return Type
284         */
285        public Type create() {
286            if (mDimZ > 0) {
287                if ((mDimX < 1) || (mDimY < 1)) {
288                    throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
289                }
290                if (mDimFaces) {
291                    throw new RSInvalidStateException("Cube maps not supported with 3D types.");
292                }
293            }
294            if (mDimY > 0) {
295                if (mDimX < 1) {
296                    throw new RSInvalidStateException("X dimension required when Y is present.");
297                }
298            }
299            if (mDimFaces) {
300                if (mDimY < 1) {
301                    throw new RSInvalidStateException("Cube maps require 2D Types.");
302                }
303            }
304
305            if (mYuv != 0) {
306                if ((mDimZ != 0) || mDimFaces || mDimMipmaps) {
307                    throw new RSInvalidStateException("YUV only supports basic 2D.");
308                }
309            }
310
311            Type t;
312            if (mRS.isNative) {
313                RenderScriptThunker rst = (RenderScriptThunker)mRS;
314                t = TypeThunker.create(rst, mElement, mDimX, mDimY, mDimZ,
315                                       mDimMipmaps, mDimFaces, mYuv);
316            } else {
317                int id = mRS.nTypeCreate(mElement.getID(mRS),
318                                         mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv);
319                t = new Type(id, mRS);
320            }
321            t.mElement = mElement;
322            t.mDimX = mDimX;
323            t.mDimY = mDimY;
324            t.mDimZ = mDimZ;
325            t.mDimMipmaps = mDimMipmaps;
326            t.mDimFaces = mDimFaces;
327            t.mDimYuv = mYuv;
328
329            t.calcElementCount();
330            return t;
331        }
332    }
333
334}
335