• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.renderscript;
18 
19 /**
20  * <p>A Type describes the {@link android.renderscript.Element} and dimensions used for an {@link
21  * android.renderscript.Allocation} or a parallel operation. Types are created through {@link
22  * android.renderscript.Type.Builder}.</p>
23  *
24  * <p>A Type always includes an {@link android.renderscript.Element} and an X
25  * dimension. A Type may be multidimensional, up to three dimensions. A nonzero
26  * value in the Y or Z dimensions indicates that the dimension is present. Note
27  * that a Type with only a given X dimension and a Type with the same X
28  * dimension but Y = 1 are not equivalent.</p>
29  *
30  * <p>A Type also supports inclusion of level of detail (LOD) or cube map
31  * faces. LOD and cube map faces are booleans to indicate present or not
32  * present. </p>
33  *
34  * <p>A Type also supports YUV format information to support an
35  * {@link android.renderscript.Allocation} in a YUV format. The YUV formats
36  * supported are {@link android.graphics.ImageFormat#YV12},
37  * {@link android.graphics.ImageFormat#NV21}, and
38  * {@link android.graphics.ImageFormat#YUV_420_888}</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  **/
46 public 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     int mArrays[];
56 
57     static final int mMaxArrays = 4;
58 
59     public enum CubemapFace {
60         POSITIVE_X (0),
61         NEGATIVE_X (1),
62         POSITIVE_Y (2),
63         NEGATIVE_Y (3),
64         POSITIVE_Z (4),
65         NEGATIVE_Z (5),
66         @Deprecated
67         POSITVE_X (0),
68         @Deprecated
69         POSITVE_Y (2),
70         @Deprecated
71         POSITVE_Z (4);
72 
73         int mID;
CubemapFace(int id)74         CubemapFace(int id) {
75             mID = id;
76         }
77     }
78 
79     /**
80      * Return the element associated with this Type.
81      *
82      * @return Element
83      */
getElement()84     public Element getElement() {
85         return mElement;
86     }
87 
88     /**
89      * Return the value of the X dimension.
90      *
91      * @return int
92      */
getX()93     public int getX() {
94         return mDimX;
95     }
96 
97     /**
98      * Return the value of the Y dimension or 0 for a 1D allocation.
99      *
100      * @return int
101      */
getY()102     public int getY() {
103         return mDimY;
104     }
105 
106     /**
107      * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
108      *
109      * @return int
110      */
getZ()111     public int getZ() {
112         return mDimZ;
113     }
114 
115     /**
116      * Get the YUV format
117      *
118      *
119      * @return int
120      */
getYuv()121     public int getYuv() {
122         return mDimYuv;
123     }
124 
125     /**
126      * Return if the Type has a mipmap chain.
127      *
128      * @return boolean
129      */
hasMipmaps()130     public boolean hasMipmaps() {
131         return mDimMipmaps;
132     }
133 
134     /**
135      * Return if the Type is a cube map.
136      *
137      * @return boolean
138      */
hasFaces()139     public boolean hasFaces() {
140         return mDimFaces;
141     }
142 
143     /**
144      * Return the total number of accessable cells in the Type.
145      *
146      * @return int
147      */
getCount()148     public int getCount() {
149         return mElementCount;
150     }
151 
152     /**
153      * @hide
154       * Return the dimension of the specified array.
155       *
156       * @param arrayNum  The array dimension to query
157       * @return int
158       */
getArray(int arrayNum)159     public int getArray(int arrayNum) {
160         if ((arrayNum < 0) || (arrayNum >= mMaxArrays)) {
161             throw new RSIllegalArgumentException("Array dimension out of range.");
162         }
163 
164         if (mArrays == null || arrayNum >= mArrays.length) {
165             // Dimension in range but no array for that dimension allocated
166             return 0;
167         }
168 
169         return mArrays[arrayNum];
170     }
171 
172     /**
173      * @hide
174       * Return the number of array dimensions.
175       *
176       * @return int
177       */
getArrayCount()178     public int getArrayCount() {
179         if (mArrays != null) return mArrays.length;
180         return 0;
181     }
182 
calcElementCount()183     void calcElementCount() {
184         boolean hasLod = hasMipmaps();
185         int x = getX();
186         int y = getY();
187         int z = getZ();
188         int faces = 1;
189         if (hasFaces()) {
190             faces = 6;
191         }
192         if (x == 0) {
193             x = 1;
194         }
195         if (y == 0) {
196             y = 1;
197         }
198         if (z == 0) {
199             z = 1;
200         }
201 
202         int count = x * y * z * faces;
203 
204         while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
205             if(x > 1) {
206                 x >>= 1;
207             }
208             if(y > 1) {
209                 y >>= 1;
210             }
211             if(z > 1) {
212                 z >>= 1;
213             }
214 
215             count += x * y * z * faces;
216         }
217 
218         if (mArrays != null) {
219             for (int ct = 0; ct < mArrays.length; ct++) {
220                 count *= mArrays[ct];
221             }
222         }
223 
224         mElementCount = count;
225     }
226 
227 
Type(long id, RenderScript rs)228     Type(long id, RenderScript rs) {
229         super(id, rs);
230         guard.open("destroy");
231     }
232 
233     @Override
updateFromNative()234     void updateFromNative() {
235         // We have 6 integer/long to obtain mDimX; mDimY; mDimZ;
236         // mDimLOD; mDimFaces; mElement;
237         long[] dataBuffer = new long[6];
238         mRS.nTypeGetNativeData(getID(mRS), dataBuffer);
239 
240         mDimX = (int)dataBuffer[0];
241         mDimY = (int)dataBuffer[1];
242         mDimZ = (int)dataBuffer[2];
243         mDimMipmaps = dataBuffer[3] == 1 ? true : false;
244         mDimFaces = dataBuffer[4] == 1 ? true : false;
245 
246         long elementID = dataBuffer[5];
247         if(elementID != 0) {
248             mElement = new Element(elementID, mRS);
249             mElement.updateFromNative();
250         }
251         calcElementCount();
252     }
253 
254     /**
255      * Utility function for creating basic 1D types. The type is
256      * created without mipmaps enabled.
257      *
258      * @param rs The RenderScript context
259      * @param e The Element for the Type
260      * @param dimX The X dimension, must be > 0
261      *
262      * @return Type
263      */
createX(RenderScript rs, Element e, int dimX)264     static public Type createX(RenderScript rs, Element e, int dimX) {
265         if (dimX < 1) {
266             throw new RSInvalidStateException("Dimension must be >= 1.");
267         }
268 
269         long id = rs.nTypeCreate(e.getID(rs), dimX, 0, 0, false, false, 0);
270         Type t = new Type(id, rs);
271         t.mElement = e;
272         t.mDimX = dimX;
273         t.calcElementCount();
274         return t;
275     }
276 
277     /**
278      * Utility function for creating basic 2D types. The type is
279      * created without mipmaps or cubemaps.
280      *
281      * @param rs The RenderScript context
282      * @param e The Element for the Type
283      * @param dimX The X dimension, must be > 0
284      * @param dimY The Y dimension, must be > 0
285      *
286      * @return Type
287      */
createXY(RenderScript rs, Element e, int dimX, int dimY)288     static public Type createXY(RenderScript rs, Element e, int dimX, int dimY) {
289         if ((dimX < 1) || (dimY < 1)) {
290             throw new RSInvalidStateException("Dimension must be >= 1.");
291         }
292 
293         long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, 0, false, false, 0);
294         Type t = new Type(id, rs);
295         t.mElement = e;
296         t.mDimX = dimX;
297         t.mDimY = dimY;
298         t.calcElementCount();
299         return t;
300     }
301 
302     /**
303      * Utility function for creating basic 3D types. The type is
304      * created without mipmaps.
305      *
306      * @param rs The RenderScript context
307      * @param e The Element for the Type
308      * @param dimX The X dimension, must be > 0
309      * @param dimY The Y dimension, must be > 0
310      * @param dimZ The Z dimension, must be > 0
311      *
312      * @return Type
313      */
createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ)314     static public Type createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ) {
315         if ((dimX < 1) || (dimY < 1) || (dimZ < 1)) {
316             throw new RSInvalidStateException("Dimension must be >= 1.");
317         }
318 
319         long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, dimZ, false, false, 0);
320         Type t = new Type(id, rs);
321         t.mElement = e;
322         t.mDimX = dimX;
323         t.mDimY = dimY;
324         t.mDimZ = dimZ;
325         t.calcElementCount();
326         return t;
327     }
328 
329     /**
330      * Builder class for Type.
331      *
332      */
333     public static class Builder {
334         RenderScript mRS;
335         int mDimX = 1;
336         int mDimY;
337         int mDimZ;
338         boolean mDimMipmaps;
339         boolean mDimFaces;
340         int mYuv;
341         int[] mArray = new int[mMaxArrays];
342 
343         Element mElement;
344 
345         /**
346          * Create a new builder object.
347          *
348          * @param rs
349          * @param e The element for the type to be created.
350          */
Builder(RenderScript rs, Element e)351         public Builder(RenderScript rs, Element e) {
352             e.checkValid();
353             mRS = rs;
354             mElement = e;
355         }
356 
357         /**
358          * Add a dimension to the Type.
359          *
360          *
361          * @param value
362          */
setX(int value)363         public Builder setX(int value) {
364             if(value < 1) {
365                 throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid.");
366             }
367             mDimX = value;
368             return this;
369         }
370 
setY(int value)371         public Builder setY(int value) {
372             if(value < 1) {
373                 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid.");
374             }
375             mDimY = value;
376             return this;
377         }
378 
setZ(int value)379         public Builder setZ(int value) {
380             if(value < 1) {
381                 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Z are not valid.");
382             }
383             mDimZ = value;
384             return this;
385         }
386 
387         /**
388          * @hide
389          * Adds an array dimension to the builder
390          *
391          * @param dim
392          * @param value
393          *
394          * @return Builder
395          */
setArray(int dim, int value)396         public Builder setArray(int dim, int value) {
397             if(dim < 0 || dim >= mMaxArrays) {
398                 throw new RSIllegalArgumentException("Array dimension out of range.");
399             }
400             mArray[dim] = value;
401             return this;
402         }
403 
setMipmaps(boolean value)404         public Builder setMipmaps(boolean value) {
405             mDimMipmaps = value;
406             return this;
407         }
408 
setFaces(boolean value)409         public Builder setFaces(boolean value) {
410             mDimFaces = value;
411             return this;
412         }
413 
414         /**
415          * Set the YUV layout for a Type.
416          *
417          * @param yuvFormat {@link android.graphics.ImageFormat#YV12}, {@link android.graphics.ImageFormat#NV21}, or
418          * {@link android.graphics.ImageFormat#YUV_420_888}.
419          */
setYuvFormat(int yuvFormat)420         public Builder setYuvFormat(int yuvFormat) {
421             switch (yuvFormat) {
422             case android.graphics.ImageFormat.NV21:
423             case android.graphics.ImageFormat.YV12:
424             case android.graphics.ImageFormat.YUV_420_888:
425                 break;
426 
427             default:
428                 throw new RSIllegalArgumentException(
429                     "Only ImageFormat.NV21, .YV12, and .YUV_420_888 are supported..");
430             }
431 
432             mYuv = yuvFormat;
433             return this;
434         }
435 
436 
437         /**
438          * Validate structure and create a new Type.
439          *
440          * @return Type
441          */
create()442         public Type create() {
443             if (mDimZ > 0) {
444                 if ((mDimX < 1) || (mDimY < 1)) {
445                     throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
446                 }
447                 if (mDimFaces) {
448                     throw new RSInvalidStateException("Cube maps not supported with 3D types.");
449                 }
450             }
451             if (mDimY > 0) {
452                 if (mDimX < 1) {
453                     throw new RSInvalidStateException("X dimension required when Y is present.");
454                 }
455             }
456             if (mDimFaces) {
457                 if (mDimY < 1) {
458                     throw new RSInvalidStateException("Cube maps require 2D Types.");
459                 }
460             }
461 
462             if (mYuv != 0) {
463                 if ((mDimZ != 0) || mDimFaces || mDimMipmaps) {
464                     throw new RSInvalidStateException("YUV only supports basic 2D.");
465                 }
466             }
467 
468             int[] arrays = null;
469             for (int ct = mMaxArrays - 1; ct >= 0; ct--) {
470                 if (mArray[ct] != 0 && arrays == null) {
471                     arrays = new int[ct];
472                 }
473                 if ((mArray[ct] == 0) && (arrays != null)) {
474                     throw new RSInvalidStateException("Array dimensions must be contigous from 0.");
475                 }
476             }
477 
478             long id = mRS.nTypeCreate(mElement.getID(mRS),
479                                      mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv);
480             Type t = new Type(id, mRS);
481             t.mElement = mElement;
482             t.mDimX = mDimX;
483             t.mDimY = mDimY;
484             t.mDimZ = mDimZ;
485             t.mDimMipmaps = mDimMipmaps;
486             t.mDimFaces = mDimFaces;
487             t.mDimYuv = mYuv;
488             t.mArrays = arrays;
489 
490             t.calcElementCount();
491             return t;
492         }
493     }
494 
495 }
496