Type.java revision d138029d92e1d4657815747f30004323061d34de
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>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
41 * {@link android.renderscript.Allocation} in a YUV format. The YUV formats
42 * supported are {@link android.graphics.ImageFormat#YV12},
43 * {@link android.graphics.ImageFormat#NV21}, and
44 * {@link android.graphics.ImageFormat#YUV_420_888}</p>
45 *
46 * <div class="special reference">
47 * <h3>Developer Guides</h3>
48 * <p>For more information about creating an application that uses RenderScript, read the
49 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
50 * </div>
51 **/
52public class Type extends BaseObj {
53    int mDimX;
54    int mDimY;
55    int mDimZ;
56    boolean mDimMipmaps;
57    boolean mDimFaces;
58    int mDimYuv;
59    int mElementCount;
60    Element mElement;
61
62    public enum CubemapFace {
63        POSITIVE_X (0),
64        NEGATIVE_X (1),
65        POSITIVE_Y (2),
66        NEGATIVE_Y (3),
67        POSITIVE_Z (4),
68        NEGATIVE_Z (5),
69        @Deprecated
70        POSITVE_X (0),
71        @Deprecated
72        POSITVE_Y (2),
73        @Deprecated
74        POSITVE_Z (4);
75
76        int mID;
77        CubemapFace(int id) {
78            mID = id;
79        }
80    }
81
82    /**
83     * Return the element associated with this Type.
84     *
85     * @return Element
86     */
87    public Element getElement() {
88        return mElement;
89    }
90
91    /**
92     * Return the value of the X dimension.
93     *
94     * @return int
95     */
96    public int getX() {
97        return mDimX;
98    }
99
100    /**
101     * Return the value of the Y dimension or 0 for a 1D allocation.
102     *
103     * @return int
104     */
105    public int getY() {
106        return mDimY;
107    }
108
109    /**
110     * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
111     *
112     * @return int
113     */
114    public int getZ() {
115        return mDimZ;
116    }
117
118    /**
119     * Get the YUV format
120     *
121     *
122     * @return int
123     */
124    public int getYuv() {
125        return mDimYuv;
126    }
127
128    /**
129     * Return if the Type has a mipmap chain.
130     *
131     * @return boolean
132     */
133    public boolean hasMipmaps() {
134        return mDimMipmaps;
135    }
136
137    /**
138     * Return if the Type is a cube map.
139     *
140     * @return boolean
141     */
142    public boolean hasFaces() {
143        return mDimFaces;
144    }
145
146    /**
147     * Return the total number of accessable cells in the Type.
148     *
149     * @return int
150     */
151    public int getCount() {
152        return mElementCount;
153    }
154
155    void calcElementCount() {
156        boolean hasLod = hasMipmaps();
157        int x = getX();
158        int y = getY();
159        int z = getZ();
160        int faces = 1;
161        if (hasFaces()) {
162            faces = 6;
163        }
164        if (x == 0) {
165            x = 1;
166        }
167        if (y == 0) {
168            y = 1;
169        }
170        if (z == 0) {
171            z = 1;
172        }
173
174        int count = x * y * z * faces;
175
176        while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
177            if(x > 1) {
178                x >>= 1;
179            }
180            if(y > 1) {
181                y >>= 1;
182            }
183            if(z > 1) {
184                z >>= 1;
185            }
186
187            count += x * y * z * faces;
188        }
189        mElementCount = count;
190    }
191
192
193    Type(long id, RenderScript rs) {
194        super(id, rs);
195    }
196
197    @Override
198    void updateFromNative() {
199        // We have 6 integer/long to obtain mDimX; mDimY; mDimZ;
200        // mDimLOD; mDimFaces; mElement;
201        long[] dataBuffer = new long[6];
202        mRS.nTypeGetNativeData(getID(mRS), dataBuffer);
203
204        mDimX = (int)dataBuffer[0];
205        mDimY = (int)dataBuffer[1];
206        mDimZ = (int)dataBuffer[2];
207        mDimMipmaps = dataBuffer[3] == 1 ? true : false;
208        mDimFaces = dataBuffer[4] == 1 ? true : false;
209
210        long elementID = dataBuffer[5];
211        if(elementID != 0) {
212            mElement = new Element(elementID, mRS);
213            mElement.updateFromNative();
214        }
215        calcElementCount();
216    }
217
218    /**
219     * Utility function for creating basic 1D types. The type is
220     * created without mipmaps enabled.
221     *
222     * @param rs The RenderScript context
223     * @param e The Element for the Type
224     * @param dimX The X dimension, must be > 0
225     *
226     * @return Type
227     */
228    static public Type createX(RenderScript rs, Element e, int dimX) {
229        if (dimX < 1) {
230            throw new RSInvalidStateException("Dimension must be >= 1.");
231        }
232
233        long id = rs.nTypeCreate(e.getID(rs), dimX, 0, 0, false, false, 0);
234        Type t = new Type(id, rs);
235        t.mElement = e;
236        t.mDimX = dimX;
237        t.calcElementCount();
238        return t;
239    }
240
241    /**
242     * Utility function for creating basic 2D types. The type is
243     * created without mipmaps or cubemaps.
244     *
245     * @param rs The RenderScript context
246     * @param e The Element for the Type
247     * @param dimX The X dimension, must be > 0
248     * @param dimY The Y dimension, must be > 0
249     *
250     * @return Type
251     */
252    static public Type createXY(RenderScript rs, Element e, int dimX, int dimY) {
253        if ((dimX < 1) || (dimY < 1)) {
254            throw new RSInvalidStateException("Dimension must be >= 1.");
255        }
256
257        long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, 0, false, false, 0);
258        Type t = new Type(id, rs);
259        t.mElement = e;
260        t.mDimX = dimX;
261        t.mDimY = dimY;
262        t.calcElementCount();
263        return t;
264    }
265
266    /**
267     * Utility function for creating basic 3D types. The type is
268     * created without mipmaps.
269     *
270     * @param rs The RenderScript context
271     * @param e The Element for the Type
272     * @param dimX The X dimension, must be > 0
273     * @param dimY The Y dimension, must be > 0
274     * @param dimZ The Z dimension, must be > 0
275     *
276     * @return Type
277     */
278    static public Type createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ) {
279        if ((dimX < 1) || (dimY < 1) || (dimZ < 1)) {
280            throw new RSInvalidStateException("Dimension must be >= 1.");
281        }
282
283        long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, dimZ, false, false, 0);
284        Type t = new Type(id, rs);
285        t.mElement = e;
286        t.mDimX = dimX;
287        t.mDimY = dimY;
288        t.mDimZ = dimZ;
289        t.calcElementCount();
290        return t;
291    }
292
293    /**
294     * Builder class for Type.
295     *
296     */
297    public static class Builder {
298        RenderScript mRS;
299        int mDimX = 1;
300        int mDimY;
301        int mDimZ;
302        boolean mDimMipmaps;
303        boolean mDimFaces;
304        int mYuv;
305
306        Element mElement;
307
308        /**
309         * Create a new builder object.
310         *
311         * @param rs
312         * @param e The element for the type to be created.
313         */
314        public Builder(RenderScript rs, Element e) {
315            e.checkValid();
316            mRS = rs;
317            mElement = e;
318        }
319
320        /**
321         * Add a dimension to the Type.
322         *
323         *
324         * @param value
325         */
326        public Builder setX(int value) {
327            if(value < 1) {
328                throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid.");
329            }
330            mDimX = value;
331            return this;
332        }
333
334        public Builder setY(int value) {
335            if(value < 1) {
336                throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid.");
337            }
338            mDimY = value;
339            return this;
340        }
341
342        public Builder setZ(int value) {
343            if(value < 1) {
344                throw new RSIllegalArgumentException("Values of less than 1 for Dimension Z are not valid.");
345            }
346            mDimZ = value;
347            return this;
348        }
349
350        public Builder setMipmaps(boolean value) {
351            mDimMipmaps = value;
352            return this;
353        }
354
355        public Builder setFaces(boolean value) {
356            mDimFaces = value;
357            return this;
358        }
359
360        /**
361         * Set the YUV layout for a Type.
362         *
363         * @param yuvFormat {@link android.graphics.ImageFormat#YV12}, {@link android.graphics.ImageFormat#NV21}, or
364         * {@link android.graphics.ImageFormat#YUV_420_888}.
365         */
366        public Builder setYuvFormat(int yuvFormat) {
367            switch (yuvFormat) {
368            case android.graphics.ImageFormat.NV21:
369            case android.graphics.ImageFormat.YV12:
370            case android.graphics.ImageFormat.YUV_420_888:
371                break;
372
373            default:
374                throw new RSIllegalArgumentException(
375                    "Only ImageFormat.NV21, .YV12, and .YUV_420_888 are supported..");
376            }
377
378            mYuv = yuvFormat;
379            return this;
380        }
381
382
383        /**
384         * Validate structure and create a new Type.
385         *
386         * @return Type
387         */
388        public Type create() {
389            if (mDimZ > 0) {
390                if ((mDimX < 1) || (mDimY < 1)) {
391                    throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
392                }
393                if (mDimFaces) {
394                    throw new RSInvalidStateException("Cube maps not supported with 3D types.");
395                }
396            }
397            if (mDimY > 0) {
398                if (mDimX < 1) {
399                    throw new RSInvalidStateException("X dimension required when Y is present.");
400                }
401            }
402            if (mDimFaces) {
403                if (mDimY < 1) {
404                    throw new RSInvalidStateException("Cube maps require 2D Types.");
405                }
406            }
407
408            if (mYuv != 0) {
409                if ((mDimZ != 0) || mDimFaces || mDimMipmaps) {
410                    throw new RSInvalidStateException("YUV only supports basic 2D.");
411                }
412            }
413
414            long id = mRS.nTypeCreate(mElement.getID(mRS),
415                                     mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv);
416            Type t = new Type(id, mRS);
417            t.mElement = mElement;
418            t.mDimX = mDimX;
419            t.mDimY = mDimY;
420            t.mDimZ = mDimZ;
421            t.mDimMipmaps = mDimMipmaps;
422            t.mDimFaces = mDimFaces;
423            t.mDimYuv = mYuv;
424
425            t.calcElementCount();
426            return t;
427        }
428    }
429
430}
431