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