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 androidx.renderscript;
18 
19 
20 import java.lang.reflect.Field;
21 
22 import android.graphics.ImageFormat;
23 import android.util.Log;
24 
25 /**
26  * <p>A Type describes the {@link androidx.renderscript.Element} and
27  * dimensions used for an {@link androidx.renderscript.Allocation} or
28  * a parallel operation. Types are created through
29  * {@link androidx.renderscript.Type.Builder}.</p>
30  *
31  * <p>A Type always includes an {@link androidx.renderscript.Element}
32  * and an X dimension. A Type may be multidimensional, up to three dimensions.
33  * A nonzero value in the Y or Z dimensions indicates that the dimension is
34  * present. Note that a Type with only a given X dimension and a Type with the
35  * same X dimension but Y = 1 are not equivalent.</p>
36  *
37  * <p>A Type also supports inclusion of level of detail (LOD) or cube map
38  * faces. LOD and cube map faces are booleans to indicate present or not
39  * present. </p>
40  *
41  * <p>A Type also supports YUV format information to support an {@link
42  * androidx.renderscript.Allocation} in a YUV format. The YUV formats
43  * supported are {@link android.graphics.ImageFormat#YV12} and {@link
44  * android.graphics.ImageFormat#NV21}.</p>
45  *
46  * <div class="special reference">
47  * <h3>Developer Guides</h3>
48  * <p>For more information about creating an application that uses RenderScript,
49  * read the
50  * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
51  * developer guide.</p>
52  * </div>
53  *
54  * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
55  * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
56  * guide</a> for the proposed alternatives.
57  **/
58 @Deprecated
59 public class Type extends BaseObj {
60     int mDimX;
61     int mDimY;
62     int mDimZ;
63     boolean mDimMipmaps;
64     boolean mDimFaces;
65     int mDimYuv;
66     int mElementCount;
67     Element mElement;
68 
69     public enum CubemapFace {
70         POSITIVE_X (0),
71         NEGATIVE_X (1),
72         POSITIVE_Y (2),
73         NEGATIVE_Y (3),
74         POSITIVE_Z (4),
75         NEGATIVE_Z (5);
76 
77         int mID;
CubemapFace(int id)78         CubemapFace(int id) {
79             mID = id;
80         }
81     }
82 
83     /**
84      * Return the element associated with this Type.
85      *
86      * @return Element
87      */
getElement()88     public Element getElement() {
89         return mElement;
90     }
91 
92     /**
93      * Return the value of the X dimension.
94      *
95      * @return int
96      */
getX()97     public int getX() {
98         return mDimX;
99     }
100 
101     /**
102      * Return the value of the Y dimension or 0 for a 1D allocation.
103      *
104      * @return int
105      */
getY()106     public int getY() {
107         return mDimY;
108     }
109 
110     /**
111      * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
112      *
113      * @return int
114      */
getZ()115     public int getZ() {
116         return mDimZ;
117     }
118 
119     /**
120      * Get the YUV format
121      *
122      * @return int
123      */
getYuv()124     public int getYuv() {
125         return mDimYuv;
126     }
127 
128     /**
129      * Return if the Type has a mipmap chain.
130      *
131      * @return boolean
132      */
hasMipmaps()133     public boolean hasMipmaps() {
134         return mDimMipmaps;
135     }
136 
137     /**
138      * Return if the Type is a cube map.
139      *
140      * @return boolean
141      */
hasFaces()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      */
getCount()151     public int getCount() {
152         return mElementCount;
153     }
154 
calcElementCount()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 
Type(long id, RenderScript rs)193     Type(long id, RenderScript rs) {
194         super(id, rs);
195     }
196 
197     /*
198      * Get an identical placeholder Type for Compat Context
199      *
200      */
getDummyType(RenderScript mRS, long eid)201     public long getDummyType(RenderScript mRS, long eid) {
202         return mRS.nIncTypeCreate(eid, mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mDimYuv);
203     }
204 
205     /**
206      * Utility function for creating basic 1D types. The type is
207      * created without mipmaps enabled.
208      *
209      * @param rs The RenderScript context
210      * @param e The Element for the Type
211      * @param dimX The X dimension, must be > 0
212      *
213      * @return Type
214      */
createX(RenderScript rs, Element e, int dimX)215     static public Type createX(RenderScript rs, Element e, int dimX) {
216         if (dimX < 1) {
217             throw new RSInvalidStateException("Dimension must be >= 1.");
218         }
219 
220         long id = rs.nTypeCreate(e.getID(rs), dimX, 0, 0, false, false, 0);
221         Type t = new Type(id, rs);
222         t.mElement = e;
223         t.mDimX = dimX;
224         t.calcElementCount();
225         return t;
226     }
227 
228     /**
229      * Utility function for creating basic 2D types. The type is
230      * created without mipmaps or cubemaps.
231      *
232      * @param rs The RenderScript context
233      * @param e The Element for the Type
234      * @param dimX The X dimension, must be > 0
235      * @param dimY The Y dimension, must be > 0
236      *
237      * @return Type
238      */
createXY(RenderScript rs, Element e, int dimX, int dimY)239     static public Type createXY(RenderScript rs, Element e, int dimX, int dimY) {
240         if ((dimX < 1) || (dimY < 1)) {
241             throw new RSInvalidStateException("Dimension must be >= 1.");
242         }
243 
244         long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, 0, false, false, 0);
245         Type t = new Type(id, rs);
246         t.mElement = e;
247         t.mDimX = dimX;
248         t.mDimY = dimY;
249         t.calcElementCount();
250         return t;
251     }
252 
253     /**
254      * Utility function for creating basic 3D types. The type is
255      * created without mipmaps.
256      *
257      * @param rs The RenderScript context
258      * @param e The Element for the Type
259      * @param dimX The X dimension, must be > 0
260      * @param dimY The Y dimension, must be > 0
261      * @param dimZ The Z dimension, must be > 0
262      *
263      * @return Type
264      */
createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ)265     static public Type createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ) {
266         if ((dimX < 1) || (dimY < 1) || (dimZ < 1)) {
267             throw new RSInvalidStateException("Dimension must be >= 1.");
268         }
269 
270         long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, dimZ, false, false, 0);
271         Type t = new Type(id, rs);
272         t.mElement = e;
273         t.mDimX = dimX;
274         t.mDimY = dimY;
275         t.mDimZ = dimZ;
276         t.calcElementCount();
277         return t;
278     }
279 
280     /**
281      * Builder class for Type.
282      *
283      */
284     public static class Builder {
285         RenderScript mRS;
286         int mDimX = 1;
287         int mDimY;
288         int mDimZ;
289         boolean mDimMipmaps;
290         boolean mDimFaces;
291         int mYuv;
292 
293         Element mElement;
294 
295         /**
296          * Create a new builder object.
297          *
298          * @param rs
299          * @param e The element for the type to be created.
300          */
Builder(RenderScript rs, Element e)301         public Builder(RenderScript rs, Element e) {
302             e.checkValid();
303             mRS = rs;
304             mElement = e;
305         }
306 
307         /**
308          * Add a dimension to the Type.
309          *
310          *
311          * @param value
312          */
setX(int value)313         public Builder setX(int value) {
314             if(value < 1) {
315                 throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid.");
316             }
317             mDimX = value;
318             return this;
319         }
320 
setY(int value)321         public Builder setY(int value) {
322             if(value < 1) {
323                 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid.");
324             }
325             mDimY = value;
326             return this;
327         }
328 
setZ(int value)329         public Builder setZ(int value) {
330             if(value < 1) {
331                 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Z are not valid.");
332             }
333             mDimZ = value;
334             return this;
335         }
336 
setMipmaps(boolean value)337         public Builder setMipmaps(boolean value) {
338             mDimMipmaps = value;
339             return this;
340         }
341 
setFaces(boolean value)342         public Builder setFaces(boolean value) {
343             mDimFaces = value;
344             return this;
345         }
346 
347         /**
348          * Set the YUV layout for a Type.
349          *
350          * @param yuvFormat {@link android.graphics.ImageFormat#YV12} or {@link android.graphics.ImageFormat#NV21}
351          */
setYuvFormat(int yuvFormat)352         public Builder setYuvFormat(int yuvFormat) {
353             switch (yuvFormat) {
354             case android.graphics.ImageFormat.NV21:
355             case android.graphics.ImageFormat.YV12:
356                 break;
357 
358             default:
359                 throw new RSIllegalArgumentException("Only NV21 and YV12 are supported..");
360             }
361 
362             mYuv = yuvFormat;
363             return this;
364         }
365 
366 
367         /**
368          * Validate structure and create a new Type.
369          *
370          * @return Type
371          */
create()372         public Type create() {
373             if (mDimZ > 0) {
374                 if ((mDimX < 1) || (mDimY < 1)) {
375                     throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
376                 }
377                 if (mDimFaces) {
378                     throw new RSInvalidStateException("Cube maps not supported with 3D types.");
379                 }
380             }
381             if (mDimY > 0) {
382                 if (mDimX < 1) {
383                     throw new RSInvalidStateException("X dimension required when Y is present.");
384                 }
385             }
386             if (mDimFaces) {
387                 if (mDimY < 1) {
388                     throw new RSInvalidStateException("Cube maps require 2D Types.");
389                 }
390             }
391 
392             if (mYuv != 0) {
393                 if ((mDimZ != 0) || mDimFaces || mDimMipmaps) {
394                     throw new RSInvalidStateException("YUV only supports basic 2D.");
395                 }
396             }
397 
398             Type t;
399             long id = mRS.nTypeCreate(mElement.getID(mRS),
400                                      mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv);
401             t = new Type(id, mRS);
402 
403             t.mElement = mElement;
404             t.mDimX = mDimX;
405             t.mDimY = mDimY;
406             t.mDimZ = mDimZ;
407             t.mDimMipmaps = mDimMipmaps;
408             t.mDimFaces = mDimFaces;
409             t.mDimYuv = mYuv;
410 
411             t.calcElementCount();
412             return t;
413         }
414     }
415 
416 }
417