• 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 androidx.renderscript;
18 
19 import java.lang.reflect.Field;
20 
21 import android.util.Log;
22 
23 /**
24  * <p>An Element represents one item within an {@link
25  * androidx.renderscript.Allocation}.  An Element is roughly
26  * equivalent to a C type in a RenderScript kernel. Elements may be basic or
27  * complex. Some basic elements are</p> <ul> <li>A single float value
28  * (equivalent to a float in a kernel)</li> <li>A four-element float vector
29  * (equivalent to a float4 in a kernel)</li> <li>An unsigned 32-bit integer
30  * (equivalent to an unsigned int in a kernel)</li> <li>A single signed 8-bit
31  * integer (equivalent to a char in a kernel)</li> </ul> <p>A complex element is
32  * roughly equivalent to a C struct and contains a number of basic or complex
33  * Elements. From Java code, a complex element contains a list of sub-elements
34  * and names that represents a particular data structure. Structs used in RS
35  * scripts are available to Java code by using the
36  * {@code ScriptField_structname} class that is reflected from a particular
37  * script.</p>
38  *
39  * <p>Basic Elements are comprised of a {@link
40  * androidx.renderscript.Element.DataType} and a {@link
41  * androidx.renderscript.Element.DataKind}. The DataType encodes C
42  * type information of an Element, while the DataKind encodes how that Element
43  * should be interpreted by a {@link androidx.renderscript.Sampler}.
44  * Note that {@link androidx.renderscript.Allocation} objects with
45  * DataKind {@link androidx.renderscript.Element.DataKind#USER} cannot
46  * be used as input for a {@link androidx.renderscript.Sampler}. In
47  * general, {@link androidx.renderscript.Allocation} objects that are
48  * intended for use with a {@link androidx.renderscript.Sampler}
49  * should use bitmap-derived Elements such as
50  * {@link androidx.renderscript.Element#RGBA_8888} or {@link
51  * androidx.renderscript#Element.A_8}.</p>
52  *
53  * <div class="special reference">
54  * <h3>Developer Guides</h3>
55  * <p>For more information about creating an application that uses RenderScript,
56  * read the
57  * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
58  * developer guide.</p>
59  * </div>
60  *
61  * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
62  * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
63  * guide</a> for the proposed alternatives.
64  **/
65 @Deprecated
66 public class Element extends BaseObj {
67     int mSize;
68     Element[] mElements;
69     String[] mElementNames;
70     int[] mArraySizes;
71     int[] mOffsetInBytes;
72     int[] mVisibleElementMap;
73 
74     DataType mType;
75     DataKind mKind;
76     boolean mNormalized;
77     int mVectorSize;
78 
updateVisibleSubElements()79     private void updateVisibleSubElements() {
80         if (mElements == null) {
81             return;
82         }
83 
84         int noPaddingFieldCount = 0;
85         int fieldCount = mElementNames.length;
86         // Find out how many elements are not padding
87         for (int ct = 0; ct < fieldCount; ct ++) {
88             if (mElementNames[ct].charAt(0) != '#') {
89                 noPaddingFieldCount ++;
90             }
91         }
92         mVisibleElementMap = new int[noPaddingFieldCount];
93 
94         // Make a map that points us at non-padding elements
95         for (int ct = 0, ctNoPadding = 0; ct < fieldCount; ct ++) {
96             if (mElementNames[ct].charAt(0) != '#') {
97                 mVisibleElementMap[ctNoPadding ++] = ct;
98             }
99         }
100     }
101 
102     /**
103     * @return element size in bytes
104     */
getBytesSize()105     public int getBytesSize() {
106         return mSize;
107     }
108 
109     /**
110     * Returns the number of vector components. 2 for float2, 4 for
111     * float4, etc.
112     * @return element vector size
113     */
getVectorSize()114     public int getVectorSize() {
115         return mVectorSize;
116     }
117 
118 
119     /**
120      * DataType represents the basic type information for a basic element.  The
121      * naming convention follows.  For numeric types it is FLOAT,
122      * SIGNED, or UNSIGNED followed by the _BITS where BITS is the
123      * size of the data.  BOOLEAN is a true / false (1,0)
124      * represented in an 8 bit container.  The UNSIGNED variants
125      * with multiple bit definitions are for packed graphical data
126      * formats and represent vectors with per vector member sizes
127      * which are treated as a single unit for packing and alignment
128      * purposes.
129      *
130      * MATRIX the three matrix types contain FLOAT_32 elements and are treated
131      * as 32 bits for alignment purposes.
132      *
133      * RS_* objects.  32 bit opaque handles.
134      */
135     public enum DataType {
136         NONE (0, 0),
137         //FLOAT_16 (1, 2),
138         FLOAT_32 (2, 4),
139         FLOAT_64 (3, 8),
140         SIGNED_8 (4, 1),
141         SIGNED_16 (5, 2),
142         SIGNED_32 (6, 4),
143         SIGNED_64 (7, 8),
144         UNSIGNED_8 (8, 1),
145         UNSIGNED_16 (9, 2),
146         UNSIGNED_32 (10, 4),
147         UNSIGNED_64 (11, 8),
148 
149         BOOLEAN(12, 1),
150 
151         UNSIGNED_5_6_5 (13, 2),
152         UNSIGNED_5_5_5_1 (14, 2),
153         UNSIGNED_4_4_4_4 (15, 2),
154 
155         MATRIX_4X4 (16, 64),
156         MATRIX_3X3 (17, 36),
157         MATRIX_2X2 (18, 16),
158 
159         RS_ELEMENT (1000),
160         RS_TYPE (1001),
161         RS_ALLOCATION (1002),
162         RS_SAMPLER (1003),
163         RS_SCRIPT (1004);
164 
165         int mID;
166         int mSize;
DataType(int id, int size)167         DataType(int id, int size) {
168             mID = id;
169             mSize = size;
170         }
171 
DataType(int id)172         DataType(int id) {
173             mID = id;
174             mSize = 4;
175             if (RenderScript.sPointerSize == 8) {
176                 mSize = 32;
177             }
178         }
179     }
180 
181     /**
182      * The special interpretation of the data if required.  This is primarly
183      * useful for graphical data.  USER indicates no special interpretation is
184      * expected.  PIXEL is used in conjunction with the standard data types for
185      * representing texture formats.
186      */
187     public enum DataKind {
188         USER (0),
189 
190         PIXEL_L (7),
191         PIXEL_A (8),
192         PIXEL_LA (9),
193         PIXEL_RGB (10),
194         PIXEL_RGBA (11),
195         PIXEL_DEPTH (12),
196         PIXEL_YUV(13);
197 
198         int mID;
DataKind(int id)199         DataKind(int id) {
200             mID = id;
201         }
202     }
203 
204     /**
205      * Return if a element is too complex for use as a data source for a Mesh or
206      * a Program.
207      *
208      * @return boolean
209      */
isComplex()210     public boolean isComplex() {
211         if (mElements == null) {
212             return false;
213         }
214         for (int ct=0; ct < mElements.length; ct++) {
215             if (mElements[ct].mElements != null) {
216                 return true;
217             }
218         }
219         return false;
220     }
221 
222     /**
223     * Elements could be simple, such as an int or a float, or a
224     * structure with multiple sub elements, such as a collection of
225     * floats, float2, float4. This function returns zero for simple
226     * elements or the number of sub-elements otherwise.
227     * @return number of sub-elements in this element
228     */
getSubElementCount()229     public int getSubElementCount() {
230         if (mVisibleElementMap == null) {
231             return 0;
232         }
233         return mVisibleElementMap.length;
234     }
235 
236     /**
237     * For complex elements, this function will return the
238     * sub-element at index
239     * @param index index of the sub-element to return
240     * @return sub-element in this element at given index
241     */
getSubElement(int index)242     public Element getSubElement(int index) {
243         if (mVisibleElementMap == null) {
244             throw new RSIllegalArgumentException("Element contains no sub-elements");
245         }
246         if (index < 0 || index >= mVisibleElementMap.length) {
247             throw new RSIllegalArgumentException("Illegal sub-element index");
248         }
249         return mElements[mVisibleElementMap[index]];
250     }
251 
252     /**
253     * For complex elements, this function will return the
254     * sub-element name at index
255     * @param index index of the sub-element
256     * @return sub-element in this element at given index
257     */
getSubElementName(int index)258     public String getSubElementName(int index) {
259         if (mVisibleElementMap == null) {
260             throw new RSIllegalArgumentException("Element contains no sub-elements");
261         }
262         if (index < 0 || index >= mVisibleElementMap.length) {
263             throw new RSIllegalArgumentException("Illegal sub-element index");
264         }
265         return mElementNames[mVisibleElementMap[index]];
266     }
267 
268     /**
269     * For complex elements, some sub-elements could be statically
270     * sized arrays. This function will return the array size for
271     * sub-element at index
272     * @param index index of the sub-element
273     * @return array size of sub-element in this element at given index
274     */
getSubElementArraySize(int index)275     public int getSubElementArraySize(int index) {
276         if (mVisibleElementMap == null) {
277             throw new RSIllegalArgumentException("Element contains no sub-elements");
278         }
279         if (index < 0 || index >= mVisibleElementMap.length) {
280             throw new RSIllegalArgumentException("Illegal sub-element index");
281         }
282         return mArraySizes[mVisibleElementMap[index]];
283     }
284 
285     /**
286     * This function specifies the location of a sub-element within
287     * the element
288     * @param index index of the sub-element
289     * @return offset in bytes of sub-element in this element at given index
290     */
getSubElementOffsetBytes(int index)291     public int getSubElementOffsetBytes(int index) {
292         if (mVisibleElementMap == null) {
293             throw new RSIllegalArgumentException("Element contains no sub-elements");
294         }
295         if (index < 0 || index >= mVisibleElementMap.length) {
296             throw new RSIllegalArgumentException("Illegal sub-element index");
297         }
298         return mOffsetInBytes[mVisibleElementMap[index]];
299     }
300 
301     /**
302     * @return element data type
303     */
getDataType()304     public DataType getDataType() {
305         return mType;
306     }
307 
308     /**
309     * @return element data kind
310     */
getDataKind()311     public DataKind getDataKind() {
312         return mKind;
313     }
314 
315     /**
316      * Utility function for returning an Element containing a single Boolean.
317      *
318      * @param rs Context to which the element will belong.
319      *
320      * @return Element
321      */
BOOLEAN(RenderScript rs)322     public static Element BOOLEAN(RenderScript rs) {
323         if(rs.mElement_BOOLEAN == null) {
324             rs.mElement_BOOLEAN = createUser(rs, DataType.BOOLEAN);
325         }
326         return rs.mElement_BOOLEAN;
327     }
328 
329     /**
330      * Utility function for returning an Element containing a single UNSIGNED_8.
331      *
332      * @param rs Context to which the element will belong.
333      *
334      * @return Element
335      */
U8(RenderScript rs)336     public static Element U8(RenderScript rs) {
337         if(rs.mElement_U8 == null) {
338             rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8);
339         }
340         return rs.mElement_U8;
341     }
342 
343     /**
344      * Utility function for returning an Element containing a single SIGNED_8.
345      *
346      * @param rs Context to which the element will belong.
347      *
348      * @return Element
349      */
I8(RenderScript rs)350     public static Element I8(RenderScript rs) {
351         if(rs.mElement_I8 == null) {
352             rs.mElement_I8 = createUser(rs, DataType.SIGNED_8);
353         }
354         return rs.mElement_I8;
355     }
356 
U16(RenderScript rs)357     public static Element U16(RenderScript rs) {
358         if(rs.mElement_U16 == null) {
359             rs.mElement_U16 = createUser(rs, DataType.UNSIGNED_16);
360         }
361         return rs.mElement_U16;
362     }
363 
I16(RenderScript rs)364     public static Element I16(RenderScript rs) {
365         if(rs.mElement_I16 == null) {
366             rs.mElement_I16 = createUser(rs, DataType.SIGNED_16);
367         }
368         return rs.mElement_I16;
369     }
370 
U32(RenderScript rs)371     public static Element U32(RenderScript rs) {
372         if(rs.mElement_U32 == null) {
373             rs.mElement_U32 = createUser(rs, DataType.UNSIGNED_32);
374         }
375         return rs.mElement_U32;
376     }
377 
I32(RenderScript rs)378     public static Element I32(RenderScript rs) {
379         if(rs.mElement_I32 == null) {
380             rs.mElement_I32 = createUser(rs, DataType.SIGNED_32);
381         }
382         return rs.mElement_I32;
383     }
384 
U64(RenderScript rs)385     public static Element U64(RenderScript rs) {
386         if(rs.mElement_U64 == null) {
387             rs.mElement_U64 = createUser(rs, DataType.UNSIGNED_64);
388         }
389         return rs.mElement_U64;
390     }
391 
I64(RenderScript rs)392     public static Element I64(RenderScript rs) {
393         if(rs.mElement_I64 == null) {
394             rs.mElement_I64 = createUser(rs, DataType.SIGNED_64);
395         }
396         return rs.mElement_I64;
397     }
398 
F32(RenderScript rs)399     public static Element F32(RenderScript rs) {
400         if(rs.mElement_F32 == null) {
401             rs.mElement_F32 = createUser(rs, DataType.FLOAT_32);
402         }
403         return rs.mElement_F32;
404     }
405 
F64(RenderScript rs)406     public static Element F64(RenderScript rs) {
407         if(rs.mElement_F64 == null) {
408             rs.mElement_F64 = createUser(rs, DataType.FLOAT_64);
409         }
410         return rs.mElement_F64;
411     }
412 
ELEMENT(RenderScript rs)413     public static Element ELEMENT(RenderScript rs) {
414         if(rs.mElement_ELEMENT == null) {
415             rs.mElement_ELEMENT = createUser(rs, DataType.RS_ELEMENT);
416         }
417         return rs.mElement_ELEMENT;
418     }
419 
TYPE(RenderScript rs)420     public static Element TYPE(RenderScript rs) {
421         if(rs.mElement_TYPE == null) {
422             rs.mElement_TYPE = createUser(rs, DataType.RS_TYPE);
423         }
424         return rs.mElement_TYPE;
425     }
426 
ALLOCATION(RenderScript rs)427     public static Element ALLOCATION(RenderScript rs) {
428         if(rs.mElement_ALLOCATION == null) {
429             rs.mElement_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION);
430         }
431         return rs.mElement_ALLOCATION;
432     }
433 
SAMPLER(RenderScript rs)434     public static Element SAMPLER(RenderScript rs) {
435         if(rs.mElement_SAMPLER == null) {
436             rs.mElement_SAMPLER = createUser(rs, DataType.RS_SAMPLER);
437         }
438         return rs.mElement_SAMPLER;
439     }
440 
SCRIPT(RenderScript rs)441     public static Element SCRIPT(RenderScript rs) {
442         if(rs.mElement_SCRIPT == null) {
443             rs.mElement_SCRIPT = createUser(rs, DataType.RS_SCRIPT);
444         }
445         return rs.mElement_SCRIPT;
446     }
447 
448 
A_8(RenderScript rs)449     public static Element A_8(RenderScript rs) {
450         if(rs.mElement_A_8 == null) {
451             rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A);
452         }
453         return rs.mElement_A_8;
454     }
455 
RGB_565(RenderScript rs)456     public static Element RGB_565(RenderScript rs) {
457         if(rs.mElement_RGB_565 == null) {
458             rs.mElement_RGB_565 = createPixel(rs, DataType.UNSIGNED_5_6_5, DataKind.PIXEL_RGB);
459         }
460         return rs.mElement_RGB_565;
461     }
462 
RGB_888(RenderScript rs)463     public static Element RGB_888(RenderScript rs) {
464         if(rs.mElement_RGB_888 == null) {
465             rs.mElement_RGB_888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGB);
466         }
467         return rs.mElement_RGB_888;
468     }
469 
RGBA_5551(RenderScript rs)470     public static Element RGBA_5551(RenderScript rs) {
471         if(rs.mElement_RGBA_5551 == null) {
472             rs.mElement_RGBA_5551 = createPixel(rs, DataType.UNSIGNED_5_5_5_1, DataKind.PIXEL_RGBA);
473         }
474         return rs.mElement_RGBA_5551;
475     }
476 
RGBA_4444(RenderScript rs)477     public static Element RGBA_4444(RenderScript rs) {
478         if(rs.mElement_RGBA_4444 == null) {
479             rs.mElement_RGBA_4444 = createPixel(rs, DataType.UNSIGNED_4_4_4_4, DataKind.PIXEL_RGBA);
480         }
481         return rs.mElement_RGBA_4444;
482     }
483 
RGBA_8888(RenderScript rs)484     public static Element RGBA_8888(RenderScript rs) {
485         if(rs.mElement_RGBA_8888 == null) {
486             rs.mElement_RGBA_8888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGBA);
487         }
488         return rs.mElement_RGBA_8888;
489     }
490 
F32_2(RenderScript rs)491     public static Element F32_2(RenderScript rs) {
492         if(rs.mElement_FLOAT_2 == null) {
493             rs.mElement_FLOAT_2 = createVector(rs, DataType.FLOAT_32, 2);
494         }
495         return rs.mElement_FLOAT_2;
496     }
497 
F32_3(RenderScript rs)498     public static Element F32_3(RenderScript rs) {
499         if(rs.mElement_FLOAT_3 == null) {
500             rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3);
501         }
502         return rs.mElement_FLOAT_3;
503     }
504 
F32_4(RenderScript rs)505     public static Element F32_4(RenderScript rs) {
506         if(rs.mElement_FLOAT_4 == null) {
507             rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4);
508         }
509         return rs.mElement_FLOAT_4;
510     }
511 
F64_2(RenderScript rs)512     public static Element F64_2(RenderScript rs) {
513         if(rs.mElement_DOUBLE_2 == null) {
514             rs.mElement_DOUBLE_2 = createVector(rs, DataType.FLOAT_64, 2);
515         }
516         return rs.mElement_DOUBLE_2;
517     }
518 
F64_3(RenderScript rs)519     public static Element F64_3(RenderScript rs) {
520         if(rs.mElement_DOUBLE_3 == null) {
521             rs.mElement_DOUBLE_3 = createVector(rs, DataType.FLOAT_64, 3);
522         }
523         return rs.mElement_DOUBLE_3;
524     }
525 
F64_4(RenderScript rs)526     public static Element F64_4(RenderScript rs) {
527         if(rs.mElement_DOUBLE_4 == null) {
528             rs.mElement_DOUBLE_4 = createVector(rs, DataType.FLOAT_64, 4);
529         }
530         return rs.mElement_DOUBLE_4;
531     }
532 
U8_2(RenderScript rs)533     public static Element U8_2(RenderScript rs) {
534         if(rs.mElement_UCHAR_2 == null) {
535             rs.mElement_UCHAR_2 = createVector(rs, DataType.UNSIGNED_8, 2);
536         }
537         return rs.mElement_UCHAR_2;
538     }
539 
U8_3(RenderScript rs)540     public static Element U8_3(RenderScript rs) {
541         if(rs.mElement_UCHAR_3 == null) {
542             rs.mElement_UCHAR_3 = createVector(rs, DataType.UNSIGNED_8, 3);
543         }
544         return rs.mElement_UCHAR_3;
545     }
546 
U8_4(RenderScript rs)547     public static Element U8_4(RenderScript rs) {
548         if(rs.mElement_UCHAR_4 == null) {
549             rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4);
550         }
551         return rs.mElement_UCHAR_4;
552     }
553 
I8_2(RenderScript rs)554     public static Element I8_2(RenderScript rs) {
555         if(rs.mElement_CHAR_2 == null) {
556             rs.mElement_CHAR_2 = createVector(rs, DataType.SIGNED_8, 2);
557         }
558         return rs.mElement_CHAR_2;
559     }
560 
I8_3(RenderScript rs)561     public static Element I8_3(RenderScript rs) {
562         if(rs.mElement_CHAR_3 == null) {
563             rs.mElement_CHAR_3 = createVector(rs, DataType.SIGNED_8, 3);
564         }
565         return rs.mElement_CHAR_3;
566     }
567 
I8_4(RenderScript rs)568     public static Element I8_4(RenderScript rs) {
569         if(rs.mElement_CHAR_4 == null) {
570             rs.mElement_CHAR_4 = createVector(rs, DataType.SIGNED_8, 4);
571         }
572         return rs.mElement_CHAR_4;
573     }
574 
U16_2(RenderScript rs)575     public static Element U16_2(RenderScript rs) {
576         if(rs.mElement_USHORT_2 == null) {
577             rs.mElement_USHORT_2 = createVector(rs, DataType.UNSIGNED_16, 2);
578         }
579         return rs.mElement_USHORT_2;
580     }
581 
U16_3(RenderScript rs)582     public static Element U16_3(RenderScript rs) {
583         if(rs.mElement_USHORT_3 == null) {
584             rs.mElement_USHORT_3 = createVector(rs, DataType.UNSIGNED_16, 3);
585         }
586         return rs.mElement_USHORT_3;
587     }
588 
U16_4(RenderScript rs)589     public static Element U16_4(RenderScript rs) {
590         if(rs.mElement_USHORT_4 == null) {
591             rs.mElement_USHORT_4 = createVector(rs, DataType.UNSIGNED_16, 4);
592         }
593         return rs.mElement_USHORT_4;
594     }
595 
I16_2(RenderScript rs)596     public static Element I16_2(RenderScript rs) {
597         if(rs.mElement_SHORT_2 == null) {
598             rs.mElement_SHORT_2 = createVector(rs, DataType.SIGNED_16, 2);
599         }
600         return rs.mElement_SHORT_2;
601     }
602 
I16_3(RenderScript rs)603     public static Element I16_3(RenderScript rs) {
604         if(rs.mElement_SHORT_3 == null) {
605             rs.mElement_SHORT_3 = createVector(rs, DataType.SIGNED_16, 3);
606         }
607         return rs.mElement_SHORT_3;
608     }
609 
I16_4(RenderScript rs)610     public static Element I16_4(RenderScript rs) {
611         if(rs.mElement_SHORT_4 == null) {
612             rs.mElement_SHORT_4 = createVector(rs, DataType.SIGNED_16, 4);
613         }
614         return rs.mElement_SHORT_4;
615     }
616 
U32_2(RenderScript rs)617     public static Element U32_2(RenderScript rs) {
618         if(rs.mElement_UINT_2 == null) {
619             rs.mElement_UINT_2 = createVector(rs, DataType.UNSIGNED_32, 2);
620         }
621         return rs.mElement_UINT_2;
622     }
623 
U32_3(RenderScript rs)624     public static Element U32_3(RenderScript rs) {
625         if(rs.mElement_UINT_3 == null) {
626             rs.mElement_UINT_3 = createVector(rs, DataType.UNSIGNED_32, 3);
627         }
628         return rs.mElement_UINT_3;
629     }
630 
U32_4(RenderScript rs)631     public static Element U32_4(RenderScript rs) {
632         if(rs.mElement_UINT_4 == null) {
633             rs.mElement_UINT_4 = createVector(rs, DataType.UNSIGNED_32, 4);
634         }
635         return rs.mElement_UINT_4;
636     }
637 
I32_2(RenderScript rs)638     public static Element I32_2(RenderScript rs) {
639         if(rs.mElement_INT_2 == null) {
640             rs.mElement_INT_2 = createVector(rs, DataType.SIGNED_32, 2);
641         }
642         return rs.mElement_INT_2;
643     }
644 
I32_3(RenderScript rs)645     public static Element I32_3(RenderScript rs) {
646         if(rs.mElement_INT_3 == null) {
647             rs.mElement_INT_3 = createVector(rs, DataType.SIGNED_32, 3);
648         }
649         return rs.mElement_INT_3;
650     }
651 
I32_4(RenderScript rs)652     public static Element I32_4(RenderScript rs) {
653         if(rs.mElement_INT_4 == null) {
654             rs.mElement_INT_4 = createVector(rs, DataType.SIGNED_32, 4);
655         }
656         return rs.mElement_INT_4;
657     }
658 
U64_2(RenderScript rs)659     public static Element U64_2(RenderScript rs) {
660         if(rs.mElement_ULONG_2 == null) {
661             rs.mElement_ULONG_2 = createVector(rs, DataType.UNSIGNED_64, 2);
662         }
663         return rs.mElement_ULONG_2;
664     }
665 
U64_3(RenderScript rs)666     public static Element U64_3(RenderScript rs) {
667         if(rs.mElement_ULONG_3 == null) {
668             rs.mElement_ULONG_3 = createVector(rs, DataType.UNSIGNED_64, 3);
669         }
670         return rs.mElement_ULONG_3;
671     }
672 
U64_4(RenderScript rs)673     public static Element U64_4(RenderScript rs) {
674         if(rs.mElement_ULONG_4 == null) {
675             rs.mElement_ULONG_4 = createVector(rs, DataType.UNSIGNED_64, 4);
676         }
677         return rs.mElement_ULONG_4;
678     }
679 
I64_2(RenderScript rs)680     public static Element I64_2(RenderScript rs) {
681         if(rs.mElement_LONG_2 == null) {
682             rs.mElement_LONG_2 = createVector(rs, DataType.SIGNED_64, 2);
683         }
684         return rs.mElement_LONG_2;
685     }
686 
I64_3(RenderScript rs)687     public static Element I64_3(RenderScript rs) {
688         if(rs.mElement_LONG_3 == null) {
689             rs.mElement_LONG_3 = createVector(rs, DataType.SIGNED_64, 3);
690         }
691         return rs.mElement_LONG_3;
692     }
693 
I64_4(RenderScript rs)694     public static Element I64_4(RenderScript rs) {
695         if(rs.mElement_LONG_4 == null) {
696             rs.mElement_LONG_4 = createVector(rs, DataType.SIGNED_64, 4);
697         }
698         return rs.mElement_LONG_4;
699     }
700 
MATRIX_4X4(RenderScript rs)701     public static Element MATRIX_4X4(RenderScript rs) {
702         if(rs.mElement_MATRIX_4X4 == null) {
703             rs.mElement_MATRIX_4X4 = createUser(rs, DataType.MATRIX_4X4);
704         }
705         return rs.mElement_MATRIX_4X4;
706     }
707 
MATRIX_3X3(RenderScript rs)708     public static Element MATRIX_3X3(RenderScript rs) {
709         if(rs.mElement_MATRIX_3X3 == null) {
710             rs.mElement_MATRIX_3X3 = createUser(rs, DataType.MATRIX_3X3);
711         }
712         return rs.mElement_MATRIX_3X3;
713     }
714 
MATRIX_2X2(RenderScript rs)715     public static Element MATRIX_2X2(RenderScript rs) {
716         if(rs.mElement_MATRIX_2X2 == null) {
717             rs.mElement_MATRIX_2X2 = createUser(rs, DataType.MATRIX_2X2);
718         }
719         return rs.mElement_MATRIX_2X2;
720     }
721 
Element(long id, RenderScript rs, Element[] e, String[] n, int[] as)722     Element(long id, RenderScript rs, Element[] e, String[] n, int[] as) {
723         super(id, rs);
724         mSize = 0;
725         mVectorSize = 1;
726         mElements = e;
727         mElementNames = n;
728         mArraySizes = as;
729         mType = DataType.NONE;
730         mKind = DataKind.USER;
731         mOffsetInBytes = new int[mElements.length];
732         for (int ct = 0; ct < mElements.length; ct++ ) {
733             mOffsetInBytes[ct] = mSize;
734             mSize += mElements[ct].mSize * mArraySizes[ct];
735         }
736         updateVisibleSubElements();
737     }
738 
Element(long id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size)739     Element(long id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
740         super(id, rs);
741         if ((dt != DataType.UNSIGNED_5_6_5) &&
742             (dt != DataType.UNSIGNED_4_4_4_4) &&
743             (dt != DataType.UNSIGNED_5_5_5_1)) {
744             if (size == 3) {
745                 mSize = dt.mSize * 4;
746             } else {
747                 mSize = dt.mSize * size;
748             }
749         } else {
750             mSize = dt.mSize;
751         }
752         mType = dt;
753         mKind = dk;
754         mNormalized = norm;
755         mVectorSize = size;
756     }
757 
Element(long id, RenderScript rs)758     Element(long id, RenderScript rs) {
759         super(id, rs);
760     }
761 
762     /*
763      * Get an identical placeholder Element for Compat Context
764      *
765      */
getDummyElement(RenderScript mRS)766     public long getDummyElement(RenderScript mRS) {
767         return mRS.nIncElementCreate(mType.mID, mKind.mID, mNormalized, mVectorSize);
768     }
769     /**
770      * Create a custom Element of the specified DataType.  The DataKind will be
771      * set to USER and the vector size to 1 indicating non-vector.
772      *
773      * @param rs The context associated with the new Element.
774      * @param dt The DataType for the new element.
775      * @return Element
776      */
createUser(RenderScript rs, DataType dt)777     static Element createUser(RenderScript rs, DataType dt) {
778         DataKind dk = DataKind.USER;
779         boolean norm = false;
780         int vecSize = 1;
781         long id = rs.nElementCreate(dt.mID, dk.mID, norm, vecSize);
782         return new Element(id, rs, dt, dk, norm, vecSize);
783     }
784 
785     /**
786      * Create a custom vector element of the specified DataType and vector size.
787      * DataKind will be set to USER. Only primitive types (FLOAT_32, FLOAT_64,
788      * SIGNED_8, SIGNED_16, SIGNED_32, SIGNED_64, UNSIGNED_8, UNSIGNED_16,
789      * UNSIGNED_32, UNSIGNED_64, BOOLEAN) are supported.
790      *
791      * @param rs The context associated with the new Element.
792      * @param dt The DataType for the new Element.
793      * @param size Vector size for the new Element.  Range 2-4 inclusive
794      *             supported.
795      *
796      * @return Element
797      */
createVector(RenderScript rs, DataType dt, int size)798     public static Element createVector(RenderScript rs, DataType dt, int size) {
799         if (size < 2 || size > 4) {
800             throw new RSIllegalArgumentException("Vector size out of range 2-4.");
801         }
802 
803         switch (dt) {
804         // Support only primitive integer/float/boolean types as vectors.
805         case FLOAT_32:
806         case FLOAT_64:
807         case SIGNED_8:
808         case SIGNED_16:
809         case SIGNED_32:
810         case SIGNED_64:
811         case UNSIGNED_8:
812         case UNSIGNED_16:
813         case UNSIGNED_32:
814         case UNSIGNED_64:
815         case BOOLEAN: {
816             DataKind dk = DataKind.USER;
817             boolean norm = false;
818             long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
819             return new Element(id, rs, dt, dk, norm, size);
820         }
821 
822         default: {
823             throw new RSIllegalArgumentException("Cannot create vector of " +
824                 "non-primitive type.");
825         }
826         }
827     }
828 
829     /**
830      * Create a new pixel Element type.  A matching DataType and DataKind must
831      * be provided.  The DataType and DataKind must contain the same number of
832      * components.  Vector size will be set to 1.
833      *
834      * @param rs The context associated with the new Element.
835      * @param dt The DataType for the new element.
836      * @param dk The DataKind to specify the mapping of each component in the
837      *           DataType.
838      *
839      * @return Element
840      */
createPixel(RenderScript rs, DataType dt, DataKind dk)841     public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
842         if (!(dk == DataKind.PIXEL_L ||
843               dk == DataKind.PIXEL_A ||
844               dk == DataKind.PIXEL_LA ||
845               dk == DataKind.PIXEL_RGB ||
846               dk == DataKind.PIXEL_RGBA ||
847               dk == DataKind.PIXEL_DEPTH ||
848               dk == DataKind.PIXEL_YUV)) {
849             throw new RSIllegalArgumentException("Unsupported DataKind");
850         }
851         if (!(dt == DataType.UNSIGNED_8 ||
852               dt == DataType.UNSIGNED_16 ||
853               dt == DataType.UNSIGNED_5_6_5 ||
854               dt == DataType.UNSIGNED_4_4_4_4 ||
855               dt == DataType.UNSIGNED_5_5_5_1)) {
856             throw new RSIllegalArgumentException("Unsupported DataType");
857         }
858         if (dt == DataType.UNSIGNED_5_6_5 && dk != DataKind.PIXEL_RGB) {
859             throw new RSIllegalArgumentException("Bad kind and type combo");
860         }
861         if (dt == DataType.UNSIGNED_5_5_5_1 && dk != DataKind.PIXEL_RGBA) {
862             throw new RSIllegalArgumentException("Bad kind and type combo");
863         }
864         if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) {
865             throw new RSIllegalArgumentException("Bad kind and type combo");
866         }
867         if (dt == DataType.UNSIGNED_16 &&
868             dk != DataKind.PIXEL_DEPTH) {
869             throw new RSIllegalArgumentException("Bad kind and type combo");
870         }
871 
872         int size = 1;
873         switch (dk) {
874         case PIXEL_LA:
875             size = 2;
876             break;
877         case PIXEL_RGB:
878             size = 3;
879             break;
880         case PIXEL_RGBA:
881             size = 4;
882             break;
883         }
884 
885         boolean norm = true;
886         long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
887         return new Element(id, rs, dt, dk, norm, size);
888     }
889 
890     /**
891      * Check if the current Element is compatible with another Element.
892      * Primitive Elements are compatible if they share the same underlying
893      * size and type (i.e. U8 is compatible with A_8). User-defined Elements
894      * must be equal in order to be compatible. This requires strict name
895      * equivalence for all sub-Elements (in addition to structural equivalence).
896      *
897      * @param e The Element to check compatibility with.
898      *
899      * @return boolean true if the Elements are compatible, otherwise false.
900      */
isCompatible(Element e)901     public boolean isCompatible(Element e) {
902         // Try strict BaseObj equality to start with.
903         if (this.equals(e)) {
904             return true;
905         }
906 
907         // Ignore mKind because it is allowed to be different (user vs. pixel).
908         // We also ignore mNormalized because it can be different. The mType
909         // field must not be NONE since we require name equivalence for
910         // all user-created Elements.
911         return ((mSize == e.mSize) &&
912                 (mType != DataType.NONE) &&
913                 (mType == e.mType) &&
914                 (mVectorSize == e.mVectorSize));
915     }
916 
917     /**
918      * Builder class for producing complex elements with matching field and name
919      * pairs.  The builder starts empty.  The order in which elements are added
920      * is retained for the layout in memory.
921      *
922      */
923     public static class Builder {
924 
925         RenderScript mRS;
926         Element[] mElements;
927         String[] mElementNames;
928         int[] mArraySizes;
929         int mCount;
930         int mSkipPadding;
931 
932         /**
933          * Create a builder object.
934          *
935          * @param rs
936          */
Builder(RenderScript rs)937         public Builder(RenderScript rs) {
938             mRS = rs;
939             mCount = 0;
940             mElements = new Element[8];
941             mElementNames = new String[8];
942             mArraySizes = new int[8];
943         }
944 
945         /**
946          * Add an array of elements to this element.
947          *
948          * @param element
949          * @param name
950          * @param arraySize
951          */
add(Element element, String name, int arraySize)952         public Builder add(Element element, String name, int arraySize) {
953             if (arraySize < 1) {
954                 throw new RSIllegalArgumentException("Array size cannot be less than 1.");
955             }
956 
957             // Skip padding fields after a vector 3 type.
958             if (mSkipPadding != 0) {
959                 if (name.startsWith("#padding_")) {
960                     mSkipPadding = 0;
961                     return this;
962                 }
963             }
964 
965             if (element.mVectorSize == 3) {
966                 mSkipPadding = 1;
967             } else {
968                 mSkipPadding = 0;
969             }
970 
971             if(mCount == mElements.length) {
972                 Element[] e = new Element[mCount + 8];
973                 String[] s = new String[mCount + 8];
974                 int[] as = new int[mCount + 8];
975                 System.arraycopy(mElements, 0, e, 0, mCount);
976                 System.arraycopy(mElementNames, 0, s, 0, mCount);
977                 System.arraycopy(mArraySizes, 0, as, 0, mCount);
978                 mElements = e;
979                 mElementNames = s;
980                 mArraySizes = as;
981             }
982             mElements[mCount] = element;
983             mElementNames[mCount] = name;
984             mArraySizes[mCount] = arraySize;
985             mCount++;
986 
987             return this;
988         }
989 
990         /**
991          * Add a single element to this Element.
992          *
993          * @param element
994          * @param name
995          */
add(Element element, String name)996         public Builder add(Element element, String name) {
997             return add(element, name, 1);
998         }
999 
1000         /**
1001          * Create the element from this builder.
1002          *
1003          *
1004          * @return Element
1005          */
create()1006         public Element create() {
1007             mRS.validate();
1008             Element[] ein = new Element[mCount];
1009             String[] sin = new String[mCount];
1010             int[] asin = new int[mCount];
1011             java.lang.System.arraycopy(mElements, 0, ein, 0, mCount);
1012             java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
1013             java.lang.System.arraycopy(mArraySizes, 0, asin, 0, mCount);
1014 
1015             long[] ids = new long[ein.length];
1016             for (int ct = 0; ct < ein.length; ct++ ) {
1017                 ids[ct] = ein[ct].getID(mRS);
1018             }
1019 
1020             long id = mRS.nElementCreate2(ids, sin, asin);
1021             return new Element(id, mRS, ein, sin, asin);
1022         }
1023     }
1024 }
1025 
1026