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