• 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>An Element represents one item within an {@link
21  * android.renderscript.Allocation}.  An Element is roughly equivalent to a C
22  * type in a RenderScript kernel. Elements may be basic or complex. Some basic
23  * elements are</p> <ul> <li>A single float value (equivalent to a float in a
24  * kernel)</li> <li>A four-element float vector (equivalent to a float4 in a
25  * kernel)</li> <li>An unsigned 32-bit integer (equivalent to an unsigned int in
26  * a kernel)</li> <li>A single signed 8-bit integer (equivalent to a char in a
27  * kernel)</li> </ul> <p>A complex element is roughly equivalent to a C struct
28  * and contains a number of basic or complex Elements. From Java code, a complex
29  * element contains a list of sub-elements and names that represents a
30  * particular data structure. Structs used in RS scripts are available to Java
31  * code by using the {@code ScriptField_structname} class that is reflected from
32  * a particular script.</p>
33  *
34  * <p>Basic Elements are comprised of a {@link
35  * android.renderscript.Element.DataType} and a {@link
36  * android.renderscript.Element.DataKind}. The DataType encodes C type
37  * information of an Element, while the DataKind encodes how that Element should
38  * be interpreted by a {@link android.renderscript.Sampler}. Note that {@link
39  * android.renderscript.Allocation} objects with DataKind {@link
40  * android.renderscript.Element.DataKind#USER} cannot be used as input for a
41  * {@link android.renderscript.Sampler}. In general, {@link
42  * android.renderscript.Allocation} objects that are intended for use with a
43  * {@link android.renderscript.Sampler} should use bitmap-derived Elements such
44  * as {@link android.renderscript.Element#RGBA_8888} or {@link
45  * android.renderscript#Element.A_8}.</p>
46  *
47  * <div class="special reference">
48  * <h3>Developer Guides</h3>
49  * <p>For more information about creating an application that uses RenderScript, read the
50  * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
51  * </div>
52  **/
53 public class Element extends BaseObj {
54     int mSize;
55     Element[] mElements;
56     String[] mElementNames;
57     int[] mArraySizes;
58     int[] mOffsetInBytes;
59 
60     int[] mVisibleElementMap;
61 
62     DataType mType;
63     DataKind mKind;
64     boolean mNormalized;
65     int mVectorSize;
66 
updateVisibleSubElements()67     private void updateVisibleSubElements() {
68         if (mElements == null) {
69             return;
70         }
71 
72         int noPaddingFieldCount = 0;
73         int fieldCount = mElementNames.length;
74         // Find out how many elements are not padding
75         for (int ct = 0; ct < fieldCount; ct ++) {
76             if (mElementNames[ct].charAt(0) != '#') {
77                 noPaddingFieldCount ++;
78             }
79         }
80         mVisibleElementMap = new int[noPaddingFieldCount];
81 
82         // Make a map that points us at non-padding elements
83         for (int ct = 0, ctNoPadding = 0; ct < fieldCount; ct ++) {
84             if (mElementNames[ct].charAt(0) != '#') {
85                 mVisibleElementMap[ctNoPadding ++] = ct;
86             }
87         }
88     }
89 
90     /**
91     * @return element size in bytes
92     */
getBytesSize()93     public int getBytesSize() {return mSize;}
94 
95     /**
96     * Returns the number of vector components. 2 for float2, 4 for
97     * float4, etc.
98     * @return element vector size
99     */
getVectorSize()100     public int getVectorSize() {return mVectorSize;}
101 
102 
103     /**
104      * DataType represents the basic type information for a basic element.  The
105      * naming convention follows.  For numeric types it is FLOAT,
106      * SIGNED, or UNSIGNED followed by the _BITS where BITS is the
107      * size of the data.  BOOLEAN is a true / false (1,0)
108      * represented in an 8 bit container.  The UNSIGNED variants
109      * with multiple bit definitions are for packed graphical data
110      * formats and represent vectors with per vector member sizes
111      * which are treated as a single unit for packing and alignment
112      * purposes.
113      *
114      * MATRIX the three matrix types contain FLOAT_32 elements and are treated
115      * as 32 bits for alignment purposes.
116      *
117      * RS_* objects:  opaque handles with implementation dependent
118      * sizes.
119      */
120     public enum DataType {
121         NONE (0, 0),
122         FLOAT_16 (1, 2),
123         FLOAT_32 (2, 4),
124         FLOAT_64 (3, 8),
125         SIGNED_8 (4, 1),
126         SIGNED_16 (5, 2),
127         SIGNED_32 (6, 4),
128         SIGNED_64 (7, 8),
129         UNSIGNED_8 (8, 1),
130         UNSIGNED_16 (9, 2),
131         UNSIGNED_32 (10, 4),
132         UNSIGNED_64 (11, 8),
133 
134         BOOLEAN(12, 1),
135 
136         UNSIGNED_5_6_5 (13, 2),
137         UNSIGNED_5_5_5_1 (14, 2),
138         UNSIGNED_4_4_4_4 (15, 2),
139 
140         MATRIX_4X4 (16, 64),
141         MATRIX_3X3 (17, 36),
142         MATRIX_2X2 (18, 16),
143 
144         RS_ELEMENT (1000),
145         RS_TYPE (1001),
146         RS_ALLOCATION (1002),
147         RS_SAMPLER (1003),
148         RS_SCRIPT (1004),
149         RS_MESH (1005),
150         RS_PROGRAM_FRAGMENT (1006),
151         RS_PROGRAM_VERTEX (1007),
152         RS_PROGRAM_RASTER (1008),
153         RS_PROGRAM_STORE (1009),
154         RS_FONT (1010);
155 
156         int mID;
157         int mSize;
DataType(int id, int size)158         DataType(int id, int size) {
159             mID = id;
160             mSize = size;
161         }
162 
DataType(int id)163         DataType(int id) {
164             mID = id;
165             mSize = 4;
166             if (RenderScript.sPointerSize == 8) {
167                 mSize = 32;
168             }
169         }
170     }
171 
172     /**
173      * The special interpretation of the data if required.  This is primarly
174      * useful for graphical data.  USER indicates no special interpretation is
175      * expected.  PIXEL is used in conjunction with the standard data types for
176      * representing texture formats.
177      */
178     public enum DataKind {
179         USER (0),
180 
181         PIXEL_L (7),
182         PIXEL_A (8),
183         PIXEL_LA (9),
184         PIXEL_RGB (10),
185         PIXEL_RGBA (11),
186         PIXEL_DEPTH (12),
187         PIXEL_YUV(13);
188 
189         int mID;
DataKind(int id)190         DataKind(int id) {
191             mID = id;
192         }
193     }
194 
195     /**
196      * Return if a element is too complex for use as a data source for a Mesh or
197      * a Program.
198      *
199      * @return boolean
200      */
isComplex()201     public boolean isComplex() {
202         if (mElements == null) {
203             return false;
204         }
205         for (int ct=0; ct < mElements.length; ct++) {
206             if (mElements[ct].mElements != null) {
207                 return true;
208             }
209         }
210         return false;
211     }
212 
213     /**
214     * Elements could be simple, such as an int or a float, or a
215     * structure with multiple sub elements, such as a collection of
216     * floats, float2, float4. This function returns zero for simple
217     * elements or the number of sub-elements otherwise.
218     * @return number of sub-elements in this element
219     */
getSubElementCount()220     public int getSubElementCount() {
221         if (mVisibleElementMap == null) {
222             return 0;
223         }
224         return mVisibleElementMap.length;
225     }
226 
227     /**
228     * For complex elements, this function will return the
229     * sub-element at index
230     * @param index index of the sub-element to return
231     * @return sub-element in this element at given index
232     */
getSubElement(int index)233     public Element getSubElement(int index) {
234         if (mVisibleElementMap == null) {
235             throw new RSIllegalArgumentException("Element contains no sub-elements");
236         }
237         if (index < 0 || index >= mVisibleElementMap.length) {
238             throw new RSIllegalArgumentException("Illegal sub-element index");
239         }
240         return mElements[mVisibleElementMap[index]];
241     }
242 
243     /**
244     * For complex elements, this function will return the
245     * sub-element name at index
246     * @param index index of the sub-element
247     * @return sub-element in this element at given index
248     */
getSubElementName(int index)249     public String getSubElementName(int index) {
250         if (mVisibleElementMap == null) {
251             throw new RSIllegalArgumentException("Element contains no sub-elements");
252         }
253         if (index < 0 || index >= mVisibleElementMap.length) {
254             throw new RSIllegalArgumentException("Illegal sub-element index");
255         }
256         return mElementNames[mVisibleElementMap[index]];
257     }
258 
259     /**
260     * For complex elements, some sub-elements could be statically
261     * sized arrays. This function will return the array size for
262     * sub-element at index
263     * @param index index of the sub-element
264     * @return array size of sub-element in this element at given index
265     */
getSubElementArraySize(int index)266     public int getSubElementArraySize(int index) {
267         if (mVisibleElementMap == null) {
268             throw new RSIllegalArgumentException("Element contains no sub-elements");
269         }
270         if (index < 0 || index >= mVisibleElementMap.length) {
271             throw new RSIllegalArgumentException("Illegal sub-element index");
272         }
273         return mArraySizes[mVisibleElementMap[index]];
274     }
275 
276     /**
277     * This function specifies the location of a sub-element within
278     * the element
279     * @param index index of the sub-element
280     * @return offset in bytes of sub-element in this element at given index
281     */
getSubElementOffsetBytes(int index)282     public int getSubElementOffsetBytes(int index) {
283         if (mVisibleElementMap == null) {
284             throw new RSIllegalArgumentException("Element contains no sub-elements");
285         }
286         if (index < 0 || index >= mVisibleElementMap.length) {
287             throw new RSIllegalArgumentException("Illegal sub-element index");
288         }
289         return mOffsetInBytes[mVisibleElementMap[index]];
290     }
291 
292     /**
293     * @return element data type
294     */
getDataType()295     public DataType getDataType() {
296         return mType;
297     }
298 
299     /**
300     * @return element data kind
301     */
getDataKind()302     public DataKind getDataKind() {
303         return mKind;
304     }
305 
306     /**
307      * Utility function for returning an Element containing a single Boolean.
308      *
309      * @param rs Context to which the element will belong.
310      *
311      * @return Element
312      */
BOOLEAN(RenderScript rs)313     public static Element BOOLEAN(RenderScript rs) {
314         if (rs.mElement_BOOLEAN == null) {
315             synchronized (rs) {
316                 if (rs.mElement_BOOLEAN == null) {
317                     rs.mElement_BOOLEAN = createUser(rs, DataType.BOOLEAN);
318                 }
319             }
320         }
321         return rs.mElement_BOOLEAN;
322     }
323 
324     /**
325      * Utility function for returning an Element containing a single UNSIGNED_8.
326      *
327      * @param rs Context to which the element will belong.
328      *
329      * @return Element
330      */
U8(RenderScript rs)331     public static Element U8(RenderScript rs) {
332         if (rs.mElement_U8 == null) {
333             synchronized (rs) {
334                 if (rs.mElement_U8 == null) {
335                     rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8);
336                 }
337             }
338         }
339         return rs.mElement_U8;
340     }
341 
342     /**
343      * Utility function for returning an Element containing a single SIGNED_8.
344      *
345      * @param rs Context to which the element will belong.
346      *
347      * @return Element
348      */
I8(RenderScript rs)349     public static Element I8(RenderScript rs) {
350         if (rs.mElement_I8 == null) {
351             synchronized (rs) {
352                 if (rs.mElement_I8 == null) {
353                     rs.mElement_I8 = createUser(rs, DataType.SIGNED_8);
354                 }
355             }
356         }
357         return rs.mElement_I8;
358     }
359 
U16(RenderScript rs)360     public static Element U16(RenderScript rs) {
361         if (rs.mElement_U16 == null) {
362             synchronized (rs) {
363                 if (rs.mElement_U16 == null) {
364                     rs.mElement_U16 = createUser(rs, DataType.UNSIGNED_16);
365                 }
366             }
367         }
368         return rs.mElement_U16;
369     }
370 
I16(RenderScript rs)371     public static Element I16(RenderScript rs) {
372         if (rs.mElement_I16 == null) {
373             synchronized (rs) {
374                 if (rs.mElement_I16 == null) {
375                     rs.mElement_I16 = createUser(rs, DataType.SIGNED_16);
376                 }
377             }
378         }
379         return rs.mElement_I16;
380     }
381 
U32(RenderScript rs)382     public static Element U32(RenderScript rs) {
383         if (rs.mElement_U32 == null) {
384             synchronized (rs) {
385                 if (rs.mElement_U32 == null) {
386                     rs.mElement_U32 = createUser(rs, DataType.UNSIGNED_32);
387                 }
388             }
389         }
390         return rs.mElement_U32;
391     }
392 
I32(RenderScript rs)393     public static Element I32(RenderScript rs) {
394         if (rs.mElement_I32 == null) {
395             synchronized (rs) {
396                 if (rs.mElement_I32 == null) {
397                     rs.mElement_I32 = createUser(rs, DataType.SIGNED_32);
398                 }
399             }
400         }
401         return rs.mElement_I32;
402     }
403 
U64(RenderScript rs)404     public static Element U64(RenderScript rs) {
405         if (rs.mElement_U64 == null) {
406             synchronized (rs) {
407                 if (rs.mElement_U64 == null) {
408                     rs.mElement_U64 = createUser(rs, DataType.UNSIGNED_64);
409                 }
410             }
411         }
412         return rs.mElement_U64;
413     }
414 
I64(RenderScript rs)415     public static Element I64(RenderScript rs) {
416         if (rs.mElement_I64 == null) {
417             synchronized (rs) {
418                 if (rs.mElement_I64 == null) {
419                     rs.mElement_I64 = createUser(rs, DataType.SIGNED_64);
420                 }
421             }
422         }
423         return rs.mElement_I64;
424     }
425 
F16(RenderScript rs)426     public static Element F16(RenderScript rs) {
427         if (rs.mElement_F16 == null) {
428             synchronized (rs) {
429                 if (rs.mElement_F16 == null) {
430                     rs.mElement_F16 = createUser(rs, DataType.FLOAT_16);
431                 }
432             }
433         }
434         return rs.mElement_F16;
435     }
436 
F32(RenderScript rs)437     public static Element F32(RenderScript rs) {
438         if (rs.mElement_F32 == null) {
439             synchronized (rs) {
440                 if (rs.mElement_F32 == null) {
441                     rs.mElement_F32 = createUser(rs, DataType.FLOAT_32);
442                 }
443             }
444         }
445         return rs.mElement_F32;
446     }
447 
F64(RenderScript rs)448     public static Element F64(RenderScript rs) {
449         if (rs.mElement_F64 == null) {
450             synchronized (rs) {
451                 if (rs.mElement_F64 == null) {
452                     rs.mElement_F64 = createUser(rs, DataType.FLOAT_64);
453                 }
454             }
455         }
456         return rs.mElement_F64;
457     }
458 
ELEMENT(RenderScript rs)459     public static Element ELEMENT(RenderScript rs) {
460         if (rs.mElement_ELEMENT == null) {
461             synchronized (rs) {
462                 if (rs.mElement_ELEMENT == null) {
463                     rs.mElement_ELEMENT = createUser(rs, DataType.RS_ELEMENT);
464                 }
465             }
466         }
467         return rs.mElement_ELEMENT;
468     }
469 
TYPE(RenderScript rs)470     public static Element TYPE(RenderScript rs) {
471         if (rs.mElement_TYPE == null) {
472             synchronized (rs) {
473                 if (rs.mElement_TYPE == null) {
474                     rs.mElement_TYPE = createUser(rs, DataType.RS_TYPE);
475                 }
476             }
477         }
478         return rs.mElement_TYPE;
479     }
480 
ALLOCATION(RenderScript rs)481     public static Element ALLOCATION(RenderScript rs) {
482         if (rs.mElement_ALLOCATION == null) {
483             synchronized (rs) {
484                 if (rs.mElement_ALLOCATION == null) {
485                     rs.mElement_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION);
486                 }
487             }
488         }
489         return rs.mElement_ALLOCATION;
490     }
491 
SAMPLER(RenderScript rs)492     public static Element SAMPLER(RenderScript rs) {
493         if (rs.mElement_SAMPLER == null) {
494             synchronized (rs) {
495                 if (rs.mElement_SAMPLER == null) {
496                     rs.mElement_SAMPLER = createUser(rs, DataType.RS_SAMPLER);
497                 }
498             }
499         }
500         return rs.mElement_SAMPLER;
501     }
502 
SCRIPT(RenderScript rs)503     public static Element SCRIPT(RenderScript rs) {
504         if (rs.mElement_SCRIPT == null) {
505             synchronized (rs) {
506                 if (rs.mElement_SCRIPT == null) {
507                     rs.mElement_SCRIPT = createUser(rs, DataType.RS_SCRIPT);
508                 }
509             }
510         }
511         return rs.mElement_SCRIPT;
512     }
513 
MESH(RenderScript rs)514     public static Element MESH(RenderScript rs) {
515         if (rs.mElement_MESH == null) {
516             synchronized (rs) {
517                 if (rs.mElement_MESH == null) {
518                     rs.mElement_MESH = createUser(rs, DataType.RS_MESH);
519                 }
520             }
521         }
522         return rs.mElement_MESH;
523     }
524 
PROGRAM_FRAGMENT(RenderScript rs)525     public static Element PROGRAM_FRAGMENT(RenderScript rs) {
526         if (rs.mElement_PROGRAM_FRAGMENT == null) {
527             synchronized (rs) {
528                 if (rs.mElement_PROGRAM_FRAGMENT == null) {
529                     rs.mElement_PROGRAM_FRAGMENT = createUser(rs, DataType.RS_PROGRAM_FRAGMENT);
530                 }
531             }
532         }
533         return rs.mElement_PROGRAM_FRAGMENT;
534     }
535 
PROGRAM_VERTEX(RenderScript rs)536     public static Element PROGRAM_VERTEX(RenderScript rs) {
537         if (rs.mElement_PROGRAM_VERTEX == null) {
538             synchronized (rs) {
539                 if (rs.mElement_PROGRAM_VERTEX == null) {
540                     rs.mElement_PROGRAM_VERTEX = createUser(rs, DataType.RS_PROGRAM_VERTEX);
541                 }
542             }
543         }
544         return rs.mElement_PROGRAM_VERTEX;
545     }
546 
PROGRAM_RASTER(RenderScript rs)547     public static Element PROGRAM_RASTER(RenderScript rs) {
548         if (rs.mElement_PROGRAM_RASTER == null) {
549             synchronized (rs) {
550                 if (rs.mElement_PROGRAM_RASTER == null) {
551                     rs.mElement_PROGRAM_RASTER = createUser(rs, DataType.RS_PROGRAM_RASTER);
552                 }
553             }
554         }
555         return rs.mElement_PROGRAM_RASTER;
556     }
557 
PROGRAM_STORE(RenderScript rs)558     public static Element PROGRAM_STORE(RenderScript rs) {
559         if (rs.mElement_PROGRAM_STORE == null) {
560             synchronized (rs) {
561                 if (rs.mElement_PROGRAM_STORE == null) {
562                     rs.mElement_PROGRAM_STORE = createUser(rs, DataType.RS_PROGRAM_STORE);
563                 }
564             }
565         }
566         return rs.mElement_PROGRAM_STORE;
567     }
568 
FONT(RenderScript rs)569     public static Element FONT(RenderScript rs) {
570         if (rs.mElement_FONT == null) {
571             synchronized (rs) {
572                 if (rs.mElement_FONT == null) {
573                     rs.mElement_FONT = createUser(rs, DataType.RS_FONT);
574                 }
575             }
576         }
577         return rs.mElement_FONT;
578     }
579 
A_8(RenderScript rs)580     public static Element A_8(RenderScript rs) {
581         if (rs.mElement_A_8 == null) {
582             synchronized (rs) {
583                 if (rs.mElement_A_8 == null) {
584                     rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A);
585                 }
586             }
587         }
588         return rs.mElement_A_8;
589     }
590 
RGB_565(RenderScript rs)591     public static Element RGB_565(RenderScript rs) {
592         if (rs.mElement_RGB_565 == null) {
593             synchronized (rs) {
594                 if (rs.mElement_RGB_565 == null) {
595                     rs.mElement_RGB_565 = createPixel(rs, DataType.UNSIGNED_5_6_5, DataKind.PIXEL_RGB);
596                 }
597             }
598         }
599         return rs.mElement_RGB_565;
600     }
601 
RGB_888(RenderScript rs)602     public static Element RGB_888(RenderScript rs) {
603         if (rs.mElement_RGB_888 == null) {
604             synchronized (rs) {
605                 if (rs.mElement_RGB_888 == null) {
606                     rs.mElement_RGB_888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGB);
607                 }
608             }
609         }
610         return rs.mElement_RGB_888;
611     }
612 
RGBA_5551(RenderScript rs)613     public static Element RGBA_5551(RenderScript rs) {
614         if (rs.mElement_RGBA_5551 == null) {
615             synchronized (rs) {
616                 if (rs.mElement_RGBA_5551 == null) {
617                     rs.mElement_RGBA_5551 = createPixel(rs, DataType.UNSIGNED_5_5_5_1, DataKind.PIXEL_RGBA);
618                 }
619             }
620         }
621         return rs.mElement_RGBA_5551;
622     }
623 
RGBA_4444(RenderScript rs)624     public static Element RGBA_4444(RenderScript rs) {
625         if (rs.mElement_RGBA_4444 == null) {
626             synchronized (rs) {
627                 if (rs.mElement_RGBA_4444 == null) {
628                     rs.mElement_RGBA_4444 = createPixel(rs, DataType.UNSIGNED_4_4_4_4, DataKind.PIXEL_RGBA);
629                 }
630             }
631         }
632         return rs.mElement_RGBA_4444;
633     }
634 
RGBA_8888(RenderScript rs)635     public static Element RGBA_8888(RenderScript rs) {
636         if (rs.mElement_RGBA_8888 == null) {
637             synchronized (rs) {
638                 if (rs.mElement_RGBA_8888 == null) {
639                     rs.mElement_RGBA_8888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGBA);
640                 }
641             }
642         }
643         return rs.mElement_RGBA_8888;
644     }
645 
F16_2(RenderScript rs)646     public static Element F16_2(RenderScript rs) {
647         if (rs.mElement_HALF_2 == null) {
648             synchronized (rs) {
649                 if (rs.mElement_HALF_2 == null) {
650                     rs.mElement_HALF_2 = createVector(rs, DataType.FLOAT_16, 2);
651                 }
652             }
653         }
654         return rs.mElement_HALF_2;
655     }
656 
F16_3(RenderScript rs)657     public static Element F16_3(RenderScript rs) {
658         if (rs.mElement_HALF_3 == null) {
659             synchronized (rs) {
660                 if (rs.mElement_HALF_3 == null) {
661                     rs.mElement_HALF_3 = createVector(rs, DataType.FLOAT_16, 3);
662                 }
663             }
664         }
665         return rs.mElement_HALF_3;
666     }
667 
F16_4(RenderScript rs)668     public static Element F16_4(RenderScript rs) {
669         if (rs.mElement_HALF_4 == null) {
670             synchronized (rs) {
671                 if (rs.mElement_HALF_4 == null) {
672                     rs.mElement_HALF_4 = createVector(rs, DataType.FLOAT_16, 4);
673                 }
674             }
675         }
676         return rs.mElement_HALF_4;
677     }
678 
F32_2(RenderScript rs)679     public static Element F32_2(RenderScript rs) {
680         if (rs.mElement_FLOAT_2 == null) {
681             synchronized (rs) {
682                 if (rs.mElement_FLOAT_2 == null) {
683                     rs.mElement_FLOAT_2 = createVector(rs, DataType.FLOAT_32, 2);
684                 }
685             }
686         }
687         return rs.mElement_FLOAT_2;
688     }
689 
F32_3(RenderScript rs)690     public static Element F32_3(RenderScript rs) {
691         if (rs.mElement_FLOAT_3 == null) {
692             synchronized (rs) {
693                 if (rs.mElement_FLOAT_3 == null) {
694                     rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3);
695                 }
696             }
697         }
698         return rs.mElement_FLOAT_3;
699     }
700 
F32_4(RenderScript rs)701     public static Element F32_4(RenderScript rs) {
702         if (rs.mElement_FLOAT_4 == null) {
703             synchronized (rs) {
704                 if (rs.mElement_FLOAT_4 == null) {
705                     rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4);
706                 }
707             }
708         }
709         return rs.mElement_FLOAT_4;
710     }
711 
F64_2(RenderScript rs)712     public static Element F64_2(RenderScript rs) {
713         if (rs.mElement_DOUBLE_2 == null) {
714             synchronized (rs) {
715                 if (rs.mElement_DOUBLE_2 == null) {
716                     rs.mElement_DOUBLE_2 = createVector(rs, DataType.FLOAT_64, 2);
717                 }
718             }
719         }
720         return rs.mElement_DOUBLE_2;
721     }
722 
F64_3(RenderScript rs)723     public static Element F64_3(RenderScript rs) {
724         if (rs.mElement_DOUBLE_3 == null) {
725             synchronized (rs) {
726                 if (rs.mElement_DOUBLE_3 == null) {
727                     rs.mElement_DOUBLE_3 = createVector(rs, DataType.FLOAT_64, 3);
728                 }
729             }
730         }
731         return rs.mElement_DOUBLE_3;
732     }
733 
F64_4(RenderScript rs)734     public static Element F64_4(RenderScript rs) {
735         if (rs.mElement_DOUBLE_4 == null) {
736             synchronized (rs) {
737                 if (rs.mElement_DOUBLE_4 == null) {
738                     rs.mElement_DOUBLE_4 = createVector(rs, DataType.FLOAT_64, 4);
739                 }
740             }
741         }
742         return rs.mElement_DOUBLE_4;
743     }
744 
U8_2(RenderScript rs)745     public static Element U8_2(RenderScript rs) {
746         if (rs.mElement_UCHAR_2 == null) {
747             synchronized (rs) {
748                 if (rs.mElement_UCHAR_2 == null) {
749                     rs.mElement_UCHAR_2 = createVector(rs, DataType.UNSIGNED_8, 2);
750                 }
751             }
752         }
753         return rs.mElement_UCHAR_2;
754     }
755 
U8_3(RenderScript rs)756     public static Element U8_3(RenderScript rs) {
757         if (rs.mElement_UCHAR_3 == null) {
758             synchronized (rs) {
759                 if (rs.mElement_UCHAR_3 == null) {
760                     rs.mElement_UCHAR_3 = createVector(rs, DataType.UNSIGNED_8, 3);
761                 }
762             }
763         }
764         return rs.mElement_UCHAR_3;
765     }
766 
U8_4(RenderScript rs)767     public static Element U8_4(RenderScript rs) {
768         if (rs.mElement_UCHAR_4 == null) {
769             synchronized (rs) {
770                 if (rs.mElement_UCHAR_4 == null) {
771                     rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4);
772                 }
773             }
774         }
775         return rs.mElement_UCHAR_4;
776     }
777 
I8_2(RenderScript rs)778     public static Element I8_2(RenderScript rs) {
779         if (rs.mElement_CHAR_2 == null) {
780             synchronized (rs) {
781                 if (rs.mElement_CHAR_2 == null) {
782                     rs.mElement_CHAR_2 = createVector(rs, DataType.SIGNED_8, 2);
783                 }
784             }
785         }
786         return rs.mElement_CHAR_2;
787     }
788 
I8_3(RenderScript rs)789     public static Element I8_3(RenderScript rs) {
790         if (rs.mElement_CHAR_3 == null) {
791             synchronized (rs) {
792                 if (rs.mElement_CHAR_3 == null) {
793                     rs.mElement_CHAR_3 = createVector(rs, DataType.SIGNED_8, 3);
794                 }
795             }
796         }
797         return rs.mElement_CHAR_3;
798     }
799 
I8_4(RenderScript rs)800     public static Element I8_4(RenderScript rs) {
801         if (rs.mElement_CHAR_4 == null) {
802             synchronized (rs) {
803                 if (rs.mElement_CHAR_4 == null) {
804                     rs.mElement_CHAR_4 = createVector(rs, DataType.SIGNED_8, 4);
805                 }
806             }
807         }
808         return rs.mElement_CHAR_4;
809     }
810 
U16_2(RenderScript rs)811     public static Element U16_2(RenderScript rs) {
812         if (rs.mElement_USHORT_2 == null) {
813             synchronized (rs) {
814                 if (rs.mElement_USHORT_2 == null) {
815                     rs.mElement_USHORT_2 = createVector(rs, DataType.UNSIGNED_16, 2);
816                 }
817             }
818         }
819         return rs.mElement_USHORT_2;
820     }
821 
U16_3(RenderScript rs)822     public static Element U16_3(RenderScript rs) {
823         if (rs.mElement_USHORT_3 == null) {
824             synchronized (rs) {
825                 if (rs.mElement_USHORT_3 == null) {
826                     rs.mElement_USHORT_3 = createVector(rs, DataType.UNSIGNED_16, 3);
827                 }
828             }
829         }
830         return rs.mElement_USHORT_3;
831     }
832 
U16_4(RenderScript rs)833     public static Element U16_4(RenderScript rs) {
834         if (rs.mElement_USHORT_4 == null) {
835             synchronized (rs) {
836                 if (rs.mElement_USHORT_4 == null) {
837                     rs.mElement_USHORT_4 = createVector(rs, DataType.UNSIGNED_16, 4);
838                 }
839             }
840         }
841         return rs.mElement_USHORT_4;
842     }
843 
I16_2(RenderScript rs)844     public static Element I16_2(RenderScript rs) {
845         if (rs.mElement_SHORT_2 == null) {
846             synchronized (rs) {
847                 if (rs.mElement_SHORT_2 == null) {
848                     rs.mElement_SHORT_2 = createVector(rs, DataType.SIGNED_16, 2);
849                 }
850             }
851         }
852         return rs.mElement_SHORT_2;
853     }
854 
I16_3(RenderScript rs)855     public static Element I16_3(RenderScript rs) {
856         if (rs.mElement_SHORT_3 == null) {
857             synchronized (rs) {
858                 if (rs.mElement_SHORT_3 == null) {
859                     rs.mElement_SHORT_3 = createVector(rs, DataType.SIGNED_16, 3);
860                 }
861             }
862         }
863         return rs.mElement_SHORT_3;
864     }
865 
I16_4(RenderScript rs)866     public static Element I16_4(RenderScript rs) {
867         if (rs.mElement_SHORT_4 == null) {
868             synchronized (rs) {
869                 if (rs.mElement_SHORT_4 == null) {
870                     rs.mElement_SHORT_4 = createVector(rs, DataType.SIGNED_16, 4);
871                 }
872             }
873         }
874         return rs.mElement_SHORT_4;
875     }
876 
U32_2(RenderScript rs)877     public static Element U32_2(RenderScript rs) {
878         if (rs.mElement_UINT_2 == null) {
879             synchronized (rs) {
880                 if (rs.mElement_UINT_2 == null) {
881                     rs.mElement_UINT_2 = createVector(rs, DataType.UNSIGNED_32, 2);
882                 }
883             }
884         }
885         return rs.mElement_UINT_2;
886     }
887 
U32_3(RenderScript rs)888     public static Element U32_3(RenderScript rs) {
889         if (rs.mElement_UINT_3 == null) {
890             synchronized (rs) {
891                 if (rs.mElement_UINT_3 == null) {
892                     rs.mElement_UINT_3 = createVector(rs, DataType.UNSIGNED_32, 3);
893                 }
894             }
895         }
896         return rs.mElement_UINT_3;
897     }
898 
U32_4(RenderScript rs)899     public static Element U32_4(RenderScript rs) {
900         if (rs.mElement_UINT_4 == null) {
901             synchronized (rs) {
902                 if (rs.mElement_UINT_4 == null) {
903                     rs.mElement_UINT_4 = createVector(rs, DataType.UNSIGNED_32, 4);
904                 }
905             }
906         }
907         return rs.mElement_UINT_4;
908     }
909 
I32_2(RenderScript rs)910     public static Element I32_2(RenderScript rs) {
911         if (rs.mElement_INT_2 == null) {
912             synchronized (rs) {
913                 if (rs.mElement_INT_2 == null) {
914                     rs.mElement_INT_2 = createVector(rs, DataType.SIGNED_32, 2);
915                 }
916             }
917         }
918         return rs.mElement_INT_2;
919     }
920 
I32_3(RenderScript rs)921     public static Element I32_3(RenderScript rs) {
922         if (rs.mElement_INT_3 == null) {
923             synchronized (rs) {
924                 if (rs.mElement_INT_3 == null) {
925                     rs.mElement_INT_3 = createVector(rs, DataType.SIGNED_32, 3);
926                 }
927             }
928         }
929         return rs.mElement_INT_3;
930     }
931 
I32_4(RenderScript rs)932     public static Element I32_4(RenderScript rs) {
933         if (rs.mElement_INT_4 == null) {
934             synchronized (rs) {
935                 if (rs.mElement_INT_4 == null) {
936                     rs.mElement_INT_4 = createVector(rs, DataType.SIGNED_32, 4);
937                 }
938             }
939         }
940         return rs.mElement_INT_4;
941     }
942 
U64_2(RenderScript rs)943     public static Element U64_2(RenderScript rs) {
944         if (rs.mElement_ULONG_2 == null) {
945             synchronized (rs) {
946                 if (rs.mElement_ULONG_2 == null) {
947                     rs.mElement_ULONG_2 = createVector(rs, DataType.UNSIGNED_64, 2);
948                 }
949             }
950         }
951         return rs.mElement_ULONG_2;
952     }
953 
U64_3(RenderScript rs)954     public static Element U64_3(RenderScript rs) {
955         if (rs.mElement_ULONG_3 == null) {
956             synchronized (rs) {
957                 if (rs.mElement_ULONG_3 == null) {
958                     rs.mElement_ULONG_3 = createVector(rs, DataType.UNSIGNED_64, 3);
959                 }
960             }
961         }
962         return rs.mElement_ULONG_3;
963     }
964 
U64_4(RenderScript rs)965     public static Element U64_4(RenderScript rs) {
966         if (rs.mElement_ULONG_4 == null) {
967             synchronized (rs) {
968                 if (rs.mElement_ULONG_4 == null) {
969                     rs.mElement_ULONG_4 = createVector(rs, DataType.UNSIGNED_64, 4);
970                 }
971             }
972         }
973         return rs.mElement_ULONG_4;
974     }
975 
I64_2(RenderScript rs)976     public static Element I64_2(RenderScript rs) {
977         if (rs.mElement_LONG_2 == null) {
978             synchronized (rs) {
979                 if (rs.mElement_LONG_2 == null) {
980                     rs.mElement_LONG_2 = createVector(rs, DataType.SIGNED_64, 2);
981                 }
982             }
983         }
984         return rs.mElement_LONG_2;
985     }
986 
I64_3(RenderScript rs)987     public static Element I64_3(RenderScript rs) {
988         if (rs.mElement_LONG_3 == null) {
989             synchronized (rs) {
990                 if (rs.mElement_LONG_3 == null) {
991                     rs.mElement_LONG_3 = createVector(rs, DataType.SIGNED_64, 3);
992                 }
993             }
994         }
995         return rs.mElement_LONG_3;
996     }
997 
I64_4(RenderScript rs)998     public static Element I64_4(RenderScript rs) {
999         if (rs.mElement_LONG_4 == null) {
1000             synchronized (rs) {
1001                 if (rs.mElement_LONG_4 == null) {
1002                     rs.mElement_LONG_4 = createVector(rs, DataType.SIGNED_64, 4);
1003                 }
1004             }
1005         }
1006         return rs.mElement_LONG_4;
1007     }
1008 
YUV(RenderScript rs)1009     public static Element YUV(RenderScript rs) {
1010         if (rs.mElement_YUV == null) {
1011             synchronized (rs) {
1012                 if (rs.mElement_YUV == null) {
1013                     rs.mElement_YUV = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_YUV);
1014                 }
1015             }
1016         }
1017         return rs.mElement_YUV;
1018     }
1019 
MATRIX_4X4(RenderScript rs)1020     public static Element MATRIX_4X4(RenderScript rs) {
1021         if (rs.mElement_MATRIX_4X4 == null) {
1022             synchronized (rs) {
1023                 if (rs.mElement_MATRIX_4X4 == null) {
1024                     rs.mElement_MATRIX_4X4 = createUser(rs, DataType.MATRIX_4X4);
1025                 }
1026             }
1027         }
1028         return rs.mElement_MATRIX_4X4;
1029     }
1030 
1031     /** @deprecated use MATRIX_4X4
1032     */
MATRIX4X4(RenderScript rs)1033     public static Element MATRIX4X4(RenderScript rs) {
1034         return MATRIX_4X4(rs);
1035     }
1036 
MATRIX_3X3(RenderScript rs)1037     public static Element MATRIX_3X3(RenderScript rs) {
1038         if (rs.mElement_MATRIX_3X3 == null) {
1039             synchronized (rs) {
1040                 if (rs.mElement_MATRIX_3X3 == null) {
1041                     rs.mElement_MATRIX_3X3 = createUser(rs, DataType.MATRIX_3X3);
1042                 }
1043             }
1044         }
1045         return rs.mElement_MATRIX_3X3;
1046     }
1047 
MATRIX_2X2(RenderScript rs)1048     public static Element MATRIX_2X2(RenderScript rs) {
1049         if (rs.mElement_MATRIX_2X2 == null) {
1050             synchronized (rs) {
1051                 if (rs.mElement_MATRIX_2X2 == null) {
1052                     rs.mElement_MATRIX_2X2 = createUser(rs, DataType.MATRIX_2X2);
1053                 }
1054             }
1055         }
1056         return rs.mElement_MATRIX_2X2;
1057     }
1058 
Element(long id, RenderScript rs, Element[] e, String[] n, int[] as)1059     Element(long id, RenderScript rs, Element[] e, String[] n, int[] as) {
1060         super(id, rs);
1061         mSize = 0;
1062         mVectorSize = 1;
1063         mElements = e;
1064         mElementNames = n;
1065         mArraySizes = as;
1066         mType = DataType.NONE;
1067         mKind = DataKind.USER;
1068         mOffsetInBytes = new int[mElements.length];
1069         for (int ct = 0; ct < mElements.length; ct++ ) {
1070             mOffsetInBytes[ct] = mSize;
1071             mSize += mElements[ct].mSize * mArraySizes[ct];
1072         }
1073         updateVisibleSubElements();
1074         guard.open("destroy");
1075     }
1076 
Element(long id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size)1077     Element(long id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
1078         super(id, rs);
1079         if ((dt != DataType.UNSIGNED_5_6_5) &&
1080             (dt != DataType.UNSIGNED_4_4_4_4) &&
1081             (dt != DataType.UNSIGNED_5_5_5_1)) {
1082             if (size == 3) {
1083                 mSize = dt.mSize * 4;
1084             } else {
1085                 mSize = dt.mSize * size;
1086             }
1087         } else {
1088             mSize = dt.mSize;
1089         }
1090         mType = dt;
1091         mKind = dk;
1092         mNormalized = norm;
1093         mVectorSize = size;
1094         guard.open("destroy");
1095     }
1096 
Element(long id, RenderScript rs)1097     Element(long id, RenderScript rs) {
1098         super(id, rs);
1099     }
1100 
1101     @Override
updateFromNative()1102     void updateFromNative() {
1103         super.updateFromNative();
1104 
1105         // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
1106         int[] dataBuffer = new int[5];
1107         mRS.nElementGetNativeData(getID(mRS), dataBuffer);
1108 
1109         mNormalized = dataBuffer[2] == 1 ? true : false;
1110         mVectorSize = dataBuffer[3];
1111         mSize = 0;
1112         for (DataType dt: DataType.values()) {
1113             if(dt.mID == dataBuffer[0]){
1114                 mType = dt;
1115                 mSize = mType.mSize * mVectorSize;
1116             }
1117         }
1118         for (DataKind dk: DataKind.values()) {
1119             if(dk.mID == dataBuffer[1]){
1120                 mKind = dk;
1121             }
1122         }
1123 
1124         int numSubElements = dataBuffer[4];
1125         if(numSubElements > 0) {
1126             mElements = new Element[numSubElements];
1127             mElementNames = new String[numSubElements];
1128             mArraySizes = new int[numSubElements];
1129             mOffsetInBytes = new int[numSubElements];
1130 
1131             long[] subElementIds = new long[numSubElements];
1132             mRS.nElementGetSubElements(getID(mRS), subElementIds, mElementNames, mArraySizes);
1133             for(int i = 0; i < numSubElements; i ++) {
1134                 mElements[i] = new Element(subElementIds[i], mRS);
1135                 mElements[i].updateFromNative();
1136                 mOffsetInBytes[i] = mSize;
1137                 mSize += mElements[i].mSize * mArraySizes[i];
1138             }
1139         }
1140         updateVisibleSubElements();
1141     }
1142 
1143     /**
1144      * Create a custom Element of the specified DataType.  The DataKind will be
1145      * set to USER and the vector size to 1 indicating non-vector.
1146      *
1147      * @param rs The context associated with the new Element.
1148      * @param dt The DataType for the new element.
1149      * @return Element
1150      */
createUser(RenderScript rs, DataType dt)1151     static Element createUser(RenderScript rs, DataType dt) {
1152         DataKind dk = DataKind.USER;
1153         boolean norm = false;
1154         int vecSize = 1;
1155         long id = rs.nElementCreate(dt.mID, dk.mID, norm, vecSize);
1156         return new Element(id, rs, dt, dk, norm, vecSize);
1157     }
1158 
1159     /**
1160      * Create a custom vector element of the specified DataType and vector size.
1161      * DataKind will be set to USER. Only primitive types (FLOAT_32, FLOAT_64,
1162      * SIGNED_8, SIGNED_16, SIGNED_32, SIGNED_64, UNSIGNED_8, UNSIGNED_16,
1163      * UNSIGNED_32, UNSIGNED_64, BOOLEAN) are supported.
1164      *
1165      * @param rs The context associated with the new Element.
1166      * @param dt The DataType for the new Element.
1167      * @param size Vector size for the new Element.  Range 2-4 inclusive
1168      *             supported.
1169      *
1170      * @return Element
1171      */
createVector(RenderScript rs, DataType dt, int size)1172     public static Element createVector(RenderScript rs, DataType dt, int size) {
1173         if (size < 2 || size > 4) {
1174             throw new RSIllegalArgumentException("Vector size out of range 2-4.");
1175         }
1176 
1177         switch (dt) {
1178         // Support only primitive integer/float/boolean types as vectors.
1179         case FLOAT_16:
1180         case FLOAT_32:
1181         case FLOAT_64:
1182         case SIGNED_8:
1183         case SIGNED_16:
1184         case SIGNED_32:
1185         case SIGNED_64:
1186         case UNSIGNED_8:
1187         case UNSIGNED_16:
1188         case UNSIGNED_32:
1189         case UNSIGNED_64:
1190         case BOOLEAN: {
1191             DataKind dk = DataKind.USER;
1192             boolean norm = false;
1193             long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
1194             return new Element(id, rs, dt, dk, norm, size);
1195         }
1196 
1197         default: {
1198             throw new RSIllegalArgumentException("Cannot create vector of " +
1199                 "non-primitive type.");
1200         }
1201         }
1202     }
1203 
1204     /**
1205      * Create a new pixel Element type.  A matching DataType and DataKind must
1206      * be provided.  The DataType and DataKind must contain the same number of
1207      * components.  Vector size will be set to 1.
1208      *
1209      * @param rs The context associated with the new Element.
1210      * @param dt The DataType for the new element.
1211      * @param dk The DataKind to specify the mapping of each component in the
1212      *           DataType.
1213      *
1214      * @return Element
1215      */
createPixel(RenderScript rs, DataType dt, DataKind dk)1216     public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
1217         if (!(dk == DataKind.PIXEL_L ||
1218               dk == DataKind.PIXEL_A ||
1219               dk == DataKind.PIXEL_LA ||
1220               dk == DataKind.PIXEL_RGB ||
1221               dk == DataKind.PIXEL_RGBA ||
1222               dk == DataKind.PIXEL_DEPTH ||
1223               dk == DataKind.PIXEL_YUV)) {
1224             throw new RSIllegalArgumentException("Unsupported DataKind");
1225         }
1226         if (!(dt == DataType.UNSIGNED_8 ||
1227               dt == DataType.UNSIGNED_16 ||
1228               dt == DataType.UNSIGNED_5_6_5 ||
1229               dt == DataType.UNSIGNED_4_4_4_4 ||
1230               dt == DataType.UNSIGNED_5_5_5_1)) {
1231             throw new RSIllegalArgumentException("Unsupported DataType");
1232         }
1233         if (dt == DataType.UNSIGNED_5_6_5 && dk != DataKind.PIXEL_RGB) {
1234             throw new RSIllegalArgumentException("Bad kind and type combo");
1235         }
1236         if (dt == DataType.UNSIGNED_5_5_5_1 && dk != DataKind.PIXEL_RGBA) {
1237             throw new RSIllegalArgumentException("Bad kind and type combo");
1238         }
1239         if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) {
1240             throw new RSIllegalArgumentException("Bad kind and type combo");
1241         }
1242         if (dt == DataType.UNSIGNED_16 &&
1243             dk != DataKind.PIXEL_DEPTH) {
1244             throw new RSIllegalArgumentException("Bad kind and type combo");
1245         }
1246 
1247         int size = 1;
1248         switch (dk) {
1249         case PIXEL_LA:
1250             size = 2;
1251             break;
1252         case PIXEL_RGB:
1253             size = 3;
1254             break;
1255         case PIXEL_RGBA:
1256             size = 4;
1257             break;
1258         case PIXEL_DEPTH:
1259             size = 2;
1260             break;
1261         }
1262 
1263         boolean norm = true;
1264         long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
1265         return new Element(id, rs, dt, dk, norm, size);
1266     }
1267 
1268     /**
1269      * Check if the current Element is compatible with another Element.
1270      * Primitive Elements are compatible if they share the same underlying
1271      * size and type (i.e. U8 is compatible with A_8). User-defined Elements
1272      * must be equal in order to be compatible. This requires strict name
1273      * equivalence for all sub-Elements (in addition to structural equivalence).
1274      *
1275      * @param e The Element to check compatibility with.
1276      *
1277      * @return boolean true if the Elements are compatible, otherwise false.
1278      */
isCompatible(Element e)1279     public boolean isCompatible(Element e) {
1280         // Try strict BaseObj equality to start with.
1281         if (this.equals(e)) {
1282             return true;
1283         }
1284 
1285         // Ignore mKind because it is allowed to be different (user vs. pixel).
1286         // We also ignore mNormalized because it can be different. The mType
1287         // field must not be NONE since we require name equivalence for
1288         // all user-created Elements.
1289         return ((mSize == e.mSize) &&
1290                 (mType != DataType.NONE) &&
1291                 (mType == e.mType) &&
1292                 (mVectorSize == e.mVectorSize));
1293     }
1294 
1295     /**
1296      * Builder class for producing complex elements with matching field and name
1297      * pairs.  The builder starts empty.  The order in which elements are added
1298      * is retained for the layout in memory.
1299      *
1300      */
1301     public static class Builder {
1302         RenderScript mRS;
1303         Element[] mElements;
1304         String[] mElementNames;
1305         int[] mArraySizes;
1306         int mCount;
1307         int mSkipPadding;
1308 
1309         /**
1310          * Create a builder object.
1311          *
1312          * @param rs
1313          */
Builder(RenderScript rs)1314         public Builder(RenderScript rs) {
1315             mRS = rs;
1316             mCount = 0;
1317             mElements = new Element[8];
1318             mElementNames = new String[8];
1319             mArraySizes = new int[8];
1320         }
1321 
1322         /**
1323          * Add an array of elements to this element.
1324          *
1325          * @param element
1326          * @param name
1327          * @param arraySize
1328          */
add(Element element, String name, int arraySize)1329         public Builder add(Element element, String name, int arraySize) {
1330             if (arraySize < 1) {
1331                 throw new RSIllegalArgumentException("Array size cannot be less than 1.");
1332             }
1333 
1334             // Skip padding fields after a vector 3 type.
1335             if (mSkipPadding != 0) {
1336                 if (name.startsWith("#padding_")) {
1337                     mSkipPadding = 0;
1338                     return this;
1339                 }
1340             }
1341 
1342             if (element.mVectorSize == 3) {
1343                 mSkipPadding = 1;
1344             } else {
1345                 mSkipPadding = 0;
1346             }
1347 
1348             if(mCount == mElements.length) {
1349                 Element[] e = new Element[mCount + 8];
1350                 String[] s = new String[mCount + 8];
1351                 int[] as = new int[mCount + 8];
1352                 System.arraycopy(mElements, 0, e, 0, mCount);
1353                 System.arraycopy(mElementNames, 0, s, 0, mCount);
1354                 System.arraycopy(mArraySizes, 0, as, 0, mCount);
1355                 mElements = e;
1356                 mElementNames = s;
1357                 mArraySizes = as;
1358             }
1359             mElements[mCount] = element;
1360             mElementNames[mCount] = name;
1361             mArraySizes[mCount] = arraySize;
1362             mCount++;
1363             return this;
1364         }
1365 
1366         /**
1367          * Add a single element to this Element.
1368          *
1369          * @param element
1370          * @param name
1371          */
add(Element element, String name)1372         public Builder add(Element element, String name) {
1373             return add(element, name, 1);
1374         }
1375 
1376         /**
1377          * Create the element from this builder.
1378          *
1379          *
1380          * @return Element
1381          */
create()1382         public Element create() {
1383             mRS.validate();
1384             Element[] ein = new Element[mCount];
1385             String[] sin = new String[mCount];
1386             int[] asin = new int[mCount];
1387             java.lang.System.arraycopy(mElements, 0, ein, 0, mCount);
1388             java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
1389             java.lang.System.arraycopy(mArraySizes, 0, asin, 0, mCount);
1390 
1391             long[] ids = new long[ein.length];
1392             for (int ct = 0; ct < ein.length; ct++ ) {
1393                 ids[ct] = ein[ct].getID(mRS);
1394             }
1395             long id = mRS.nElementCreate2(ids, sin, asin);
1396             return new Element(id, mRS, ein, sin, asin);
1397         }
1398     }
1399 }
1400 
1401