Element.java revision c1d6210fb5cc558ccea95a59a2b33bb9015fc7de
1/*
2 * Copyright (C) 2008 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
17package android.renderscript;
18
19import java.lang.reflect.Field;
20import android.util.Log;
21
22/**
23 * @hide
24 *
25 **/
26public class Element extends BaseObj {
27    int mSize;
28    Element[] mElements;
29    String[] mElementNames;
30    int[] mArraySizes;
31
32    DataType mType;
33    DataKind mKind;
34    boolean mNormalized;
35    int mVectorSize;
36
37    int getSizeBytes() {return mSize;}
38
39    public enum DataType {
40        //FLOAT_16 (1, 2),
41        FLOAT_32 (2, 4),
42        FLOAT_64 (3, 8),
43        SIGNED_8 (4, 1),
44        SIGNED_16 (5, 2),
45        SIGNED_32 (6, 4),
46        SIGNED_64 (7, 8),
47        UNSIGNED_8 (8, 1),
48        UNSIGNED_16 (9, 2),
49        UNSIGNED_32 (10, 4),
50        UNSIGNED_64 (11, 8),
51
52        BOOLEAN(12, 1),
53
54        UNSIGNED_5_6_5 (13, 2),
55        UNSIGNED_5_5_5_1 (14, 2),
56        UNSIGNED_4_4_4_4 (15, 2),
57
58        MATRIX_4X4 (16, 64),
59        MATRIX_3X3 (17, 36),
60        MATRIX_2X2 (18, 16),
61
62        RS_ELEMENT (1000, 4),
63        RS_TYPE (1001, 4),
64        RS_ALLOCATION (1002, 4),
65        RS_SAMPLER (1003, 4),
66        RS_SCRIPT (1004, 4),
67        RS_MESH (1005, 4),
68        RS_PROGRAM_FRAGMENT (1006, 4),
69        RS_PROGRAM_VERTEX (1007, 4),
70        RS_PROGRAM_RASTER (1008, 4),
71        RS_PROGRAM_STORE (1009, 4);
72
73        int mID;
74        int mSize;
75        DataType(int id, int size) {
76            mID = id;
77            mSize = size;
78        }
79    }
80
81    public enum DataKind {
82        USER (0),
83
84        PIXEL_L (7),
85        PIXEL_A (8),
86        PIXEL_LA (9),
87        PIXEL_RGB (10),
88        PIXEL_RGBA (11);
89
90        int mID;
91        DataKind(int id) {
92            mID = id;
93        }
94    }
95
96    public boolean isComplex() {
97        if (mElements == null) {
98            return false;
99        }
100        for (int ct=0; ct < mElements.length; ct++) {
101            if (mElements[ct].mElements != null) {
102                return true;
103            }
104        }
105        return false;
106    }
107
108    public static Element BOOLEAN(RenderScript rs) {
109        if(rs.mElement_BOOLEAN == null) {
110            rs.mElement_BOOLEAN = createUser(rs, DataType.BOOLEAN);
111        }
112        return rs.mElement_BOOLEAN;
113    }
114
115    public static Element U8(RenderScript rs) {
116        if(rs.mElement_U8 == null) {
117            rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8);
118        }
119        return rs.mElement_U8;
120    }
121
122    public static Element I8(RenderScript rs) {
123        if(rs.mElement_I8 == null) {
124            rs.mElement_I8 = createUser(rs, DataType.SIGNED_8);
125        }
126        return rs.mElement_I8;
127    }
128
129    public static Element U16(RenderScript rs) {
130        if(rs.mElement_U16 == null) {
131            rs.mElement_U16 = createUser(rs, DataType.UNSIGNED_16);
132        }
133        return rs.mElement_U16;
134    }
135
136    public static Element I16(RenderScript rs) {
137        if(rs.mElement_I16 == null) {
138            rs.mElement_I16 = createUser(rs, DataType.SIGNED_16);
139        }
140        return rs.mElement_I16;
141    }
142
143    public static Element U32(RenderScript rs) {
144        if(rs.mElement_U32 == null) {
145            rs.mElement_U32 = createUser(rs, DataType.UNSIGNED_32);
146        }
147        return rs.mElement_U32;
148    }
149
150    public static Element I32(RenderScript rs) {
151        if(rs.mElement_I32 == null) {
152            rs.mElement_I32 = createUser(rs, DataType.SIGNED_32);
153        }
154        return rs.mElement_I32;
155    }
156
157    public static Element U64(RenderScript rs) {
158        if(rs.mElement_U64 == null) {
159            rs.mElement_U64 = createUser(rs, DataType.UNSIGNED_64);
160        }
161        return rs.mElement_U64;
162    }
163
164    public static Element I64(RenderScript rs) {
165        if(rs.mElement_I64 == null) {
166            rs.mElement_I64 = createUser(rs, DataType.SIGNED_64);
167        }
168        return rs.mElement_I64;
169    }
170
171    public static Element F32(RenderScript rs) {
172        if(rs.mElement_F32 == null) {
173            rs.mElement_F32 = createUser(rs, DataType.FLOAT_32);
174        }
175        return rs.mElement_F32;
176    }
177
178    public static Element F64(RenderScript rs) {
179        if(rs.mElement_F64 == null) {
180            rs.mElement_F64 = createUser(rs, DataType.FLOAT_64);
181        }
182        return rs.mElement_F64;
183    }
184
185    public static Element ELEMENT(RenderScript rs) {
186        if(rs.mElement_ELEMENT == null) {
187            rs.mElement_ELEMENT = createUser(rs, DataType.RS_ELEMENT);
188        }
189        return rs.mElement_ELEMENT;
190    }
191
192    public static Element TYPE(RenderScript rs) {
193        if(rs.mElement_TYPE == null) {
194            rs.mElement_TYPE = createUser(rs, DataType.RS_TYPE);
195        }
196        return rs.mElement_TYPE;
197    }
198
199    public static Element ALLOCATION(RenderScript rs) {
200        if(rs.mElement_ALLOCATION == null) {
201            rs.mElement_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION);
202        }
203        return rs.mElement_ALLOCATION;
204    }
205
206    public static Element SAMPLER(RenderScript rs) {
207        if(rs.mElement_SAMPLER == null) {
208            rs.mElement_SAMPLER = createUser(rs, DataType.RS_SAMPLER);
209        }
210        return rs.mElement_SAMPLER;
211    }
212
213    public static Element SCRIPT(RenderScript rs) {
214        if(rs.mElement_SCRIPT == null) {
215            rs.mElement_SCRIPT = createUser(rs, DataType.RS_SCRIPT);
216        }
217        return rs.mElement_SCRIPT;
218    }
219
220    public static Element MESH(RenderScript rs) {
221        if(rs.mElement_MESH == null) {
222            rs.mElement_MESH = createUser(rs, DataType.RS_MESH);
223        }
224        return rs.mElement_MESH;
225    }
226
227    public static Element PROGRAM_FRAGMENT(RenderScript rs) {
228        if(rs.mElement_PROGRAM_FRAGMENT == null) {
229            rs.mElement_PROGRAM_FRAGMENT = createUser(rs, DataType.RS_PROGRAM_FRAGMENT);
230        }
231        return rs.mElement_PROGRAM_FRAGMENT;
232    }
233
234    public static Element PROGRAM_VERTEX(RenderScript rs) {
235        if(rs.mElement_PROGRAM_VERTEX == null) {
236            rs.mElement_PROGRAM_VERTEX = createUser(rs, DataType.RS_PROGRAM_VERTEX);
237        }
238        return rs.mElement_PROGRAM_VERTEX;
239    }
240
241    public static Element PROGRAM_RASTER(RenderScript rs) {
242        if(rs.mElement_PROGRAM_RASTER == null) {
243            rs.mElement_PROGRAM_RASTER = createUser(rs, DataType.RS_PROGRAM_RASTER);
244        }
245        return rs.mElement_PROGRAM_RASTER;
246    }
247
248    public static Element PROGRAM_STORE(RenderScript rs) {
249        if(rs.mElement_PROGRAM_STORE == null) {
250            rs.mElement_PROGRAM_STORE = createUser(rs, DataType.RS_PROGRAM_STORE);
251        }
252        return rs.mElement_PROGRAM_STORE;
253    }
254
255
256    public static Element A_8(RenderScript rs) {
257        if(rs.mElement_A_8 == null) {
258            rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A);
259        }
260        return rs.mElement_A_8;
261    }
262
263    public static Element RGB_565(RenderScript rs) {
264        if(rs.mElement_RGB_565 == null) {
265            rs.mElement_RGB_565 = createPixel(rs, DataType.UNSIGNED_5_6_5, DataKind.PIXEL_RGB);
266        }
267        return rs.mElement_RGB_565;
268    }
269
270    public static Element RGB_888(RenderScript rs) {
271        if(rs.mElement_RGB_888 == null) {
272            rs.mElement_RGB_888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGB);
273        }
274        return rs.mElement_RGB_888;
275    }
276
277    public static Element RGBA_5551(RenderScript rs) {
278        if(rs.mElement_RGBA_5551 == null) {
279            rs.mElement_RGBA_5551 = createPixel(rs, DataType.UNSIGNED_5_5_5_1, DataKind.PIXEL_RGBA);
280        }
281        return rs.mElement_RGBA_5551;
282    }
283
284    public static Element RGBA_4444(RenderScript rs) {
285        if(rs.mElement_RGBA_4444 == null) {
286            rs.mElement_RGBA_4444 = createPixel(rs, DataType.UNSIGNED_4_4_4_4, DataKind.PIXEL_RGBA);
287        }
288        return rs.mElement_RGBA_4444;
289    }
290
291    public static Element RGBA_8888(RenderScript rs) {
292        if(rs.mElement_RGBA_8888 == null) {
293            rs.mElement_RGBA_8888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGBA);
294        }
295        return rs.mElement_RGBA_8888;
296    }
297
298    public static Element F32_2(RenderScript rs) {
299        if(rs.mElement_FLOAT_2 == null) {
300            rs.mElement_FLOAT_2 = createVector(rs, DataType.FLOAT_32, 2);
301        }
302        return rs.mElement_FLOAT_2;
303    }
304
305    public static Element F32_3(RenderScript rs) {
306        if(rs.mElement_FLOAT_3 == null) {
307            rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3);
308        }
309        return rs.mElement_FLOAT_3;
310    }
311
312    public static Element F32_4(RenderScript rs) {
313        if(rs.mElement_FLOAT_4 == null) {
314            rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4);
315        }
316        return rs.mElement_FLOAT_4;
317    }
318
319    public static Element U8_4(RenderScript rs) {
320        if(rs.mElement_UCHAR_4 == null) {
321            rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4);
322        }
323        return rs.mElement_UCHAR_4;
324    }
325
326    public static Element MATRIX_4X4(RenderScript rs) {
327        if(rs.mElement_MATRIX_4X4 == null) {
328            rs.mElement_MATRIX_4X4 = createUser(rs, DataType.MATRIX_4X4);
329        }
330        return rs.mElement_MATRIX_4X4;
331    }
332    public static Element MATRIX4X4(RenderScript rs) {
333        return MATRIX_4X4(rs);
334    }
335
336    public static Element MATRIX_3X3(RenderScript rs) {
337        if(rs.mElement_MATRIX_3X3 == null) {
338            rs.mElement_MATRIX_3X3 = createUser(rs, DataType.MATRIX_3X3);
339        }
340        return rs.mElement_MATRIX_4X4;
341    }
342
343    public static Element MATRIX_2X2(RenderScript rs) {
344        if(rs.mElement_MATRIX_2X2 == null) {
345            rs.mElement_MATRIX_2X2 = createUser(rs, DataType.MATRIX_2X2);
346        }
347        return rs.mElement_MATRIX_2X2;
348    }
349
350    Element(int id, RenderScript rs, Element[] e, String[] n, int[] as) {
351        super(id, rs);
352        mSize = 0;
353        mElements = e;
354        mElementNames = n;
355        mArraySizes = as;
356        for (int ct = 0; ct < mElements.length; ct++ ) {
357            mSize += mElements[ct].mSize * mArraySizes[ct];
358        }
359    }
360
361    Element(int id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
362        super(id, rs);
363        mSize = dt.mSize * size;
364        mType = dt;
365        mKind = dk;
366        mNormalized = norm;
367        mVectorSize = size;
368    }
369
370    Element(int id, RenderScript rs) {
371        super(id, rs);
372    }
373
374    @Override
375    void updateFromNative() {
376
377        // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
378        int[] dataBuffer = new int[5];
379        mRS.nElementGetNativeData(mID, dataBuffer);
380
381        mNormalized = dataBuffer[2] == 1 ? true : false;
382        mVectorSize = dataBuffer[3];
383        mSize = 0;
384        for (DataType dt: DataType.values()) {
385            if(dt.mID == dataBuffer[0]){
386                mType = dt;
387                mSize = mType.mSize * mVectorSize;
388            }
389        }
390        for (DataKind dk: DataKind.values()) {
391            if(dk.mID == dataBuffer[1]){
392                mKind = dk;
393            }
394        }
395
396        int numSubElements = dataBuffer[4];
397        if(numSubElements > 0) {
398            mElements = new Element[numSubElements];
399            mElementNames = new String[numSubElements];
400
401            int[] subElementIds = new int[numSubElements];
402            mRS.nElementGetSubElements(mID, subElementIds, mElementNames);
403            for(int i = 0; i < numSubElements; i ++) {
404                mElements[i] = new Element(subElementIds[i], mRS);
405                mElements[i].updateFromNative();
406                mSize += mElements[i].mSize;
407            }
408        }
409
410    }
411
412    public void destroy() {
413        super.destroy();
414    }
415
416    /////////////////////////////////////////
417    public static Element createUser(RenderScript rs, DataType dt) {
418        DataKind dk = DataKind.USER;
419        boolean norm = false;
420        int vecSize = 1;
421        int id = rs.nElementCreate(dt.mID, dk.mID, norm, vecSize);
422        return new Element(id, rs, dt, dk, norm, vecSize);
423    }
424
425    public static Element createVector(RenderScript rs, DataType dt, int size) {
426        if (size < 2 || size > 4) {
427            throw new RSIllegalArgumentException("Vector size out of rance 2-4.");
428        }
429        DataKind dk = DataKind.USER;
430        boolean norm = false;
431        int id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
432        return new Element(id, rs, dt, dk, norm, size);
433    }
434
435    public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
436        if (!(dk == DataKind.PIXEL_L ||
437              dk == DataKind.PIXEL_A ||
438              dk == DataKind.PIXEL_LA ||
439              dk == DataKind.PIXEL_RGB ||
440              dk == DataKind.PIXEL_RGBA)) {
441            throw new RSIllegalArgumentException("Unsupported DataKind");
442        }
443        if (!(dt == DataType.UNSIGNED_8 ||
444              dt == DataType.UNSIGNED_5_6_5 ||
445              dt == DataType.UNSIGNED_4_4_4_4 ||
446              dt == DataType.UNSIGNED_5_5_5_1)) {
447            throw new RSIllegalArgumentException("Unsupported DataType");
448        }
449        if (dt == DataType.UNSIGNED_5_6_5 && dk != DataKind.PIXEL_RGB) {
450            throw new RSIllegalArgumentException("Bad kind and type combo");
451        }
452        if (dt == DataType.UNSIGNED_5_5_5_1 && dk != DataKind.PIXEL_RGBA) {
453            throw new RSIllegalArgumentException("Bad kind and type combo");
454        }
455        if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) {
456            throw new RSIllegalArgumentException("Bad kind and type combo");
457        }
458
459        int size = 1;
460        if (dk == DataKind.PIXEL_LA) {
461            size = 2;
462        }
463        if (dk == DataKind.PIXEL_RGB) {
464            size = 3;
465        }
466        if (dk == DataKind.PIXEL_RGBA) {
467            size = 4;
468        }
469
470        boolean norm = true;
471        int id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
472        return new Element(id, rs, dt, dk, norm, size);
473    }
474
475    public static class Builder {
476        RenderScript mRS;
477        Element[] mElements;
478        String[] mElementNames;
479        int[] mArraySizes;
480        int mCount;
481
482        public Builder(RenderScript rs) {
483            mRS = rs;
484            mCount = 0;
485            mElements = new Element[8];
486            mElementNames = new String[8];
487            mArraySizes = new int[8];
488        }
489
490        public void add(Element element, String name, int arraySize) {
491            if (arraySize < 1) {
492                throw new RSIllegalArgumentException("Array size cannot be less than 1.");
493            }
494            if(mCount == mElements.length) {
495                Element[] e = new Element[mCount + 8];
496                String[] s = new String[mCount + 8];
497                int[] as = new int[mCount + 8];
498                System.arraycopy(mElements, 0, e, 0, mCount);
499                System.arraycopy(mElementNames, 0, s, 0, mCount);
500                System.arraycopy(mArraySizes, 0, as, 0, mCount);
501                mElements = e;
502                mElementNames = s;
503                mArraySizes = as;
504            }
505            mElements[mCount] = element;
506            mElementNames[mCount] = name;
507            mArraySizes[mCount] = arraySize;
508            mCount++;
509        }
510
511        public void add(Element element, String name) {
512            add(element, name, 1);
513        }
514
515        public Element create() {
516            mRS.validate();
517            Element[] ein = new Element[mCount];
518            String[] sin = new String[mCount];
519            int[] asin = new int[mCount];
520            java.lang.System.arraycopy(mElements, 0, ein, 0, mCount);
521            java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
522            java.lang.System.arraycopy(mArraySizes, 0, asin, 0, mCount);
523
524            int[] ids = new int[ein.length];
525            for (int ct = 0; ct < ein.length; ct++ ) {
526                ids[ct] = ein[ct].mID;
527            }
528            int id = mRS.nElementCreate2(ids, sin, asin);
529            return new Element(id, mRS, ein, sin, asin);
530        }
531    }
532
533    static void initPredefined(RenderScript rs) {
534        int a8 = rs.nElementCreate(DataType.UNSIGNED_8.mID,
535                                   DataKind.PIXEL_A.mID, true, 1);
536        int rgba4444 = rs.nElementCreate(DataType.UNSIGNED_4_4_4_4.mID,
537                                         DataKind.PIXEL_RGBA.mID, true, 4);
538        int rgba8888 = rs.nElementCreate(DataType.UNSIGNED_8.mID,
539                                         DataKind.PIXEL_RGBA.mID, true, 4);
540        int rgb565 = rs.nElementCreate(DataType.UNSIGNED_5_6_5.mID,
541                                       DataKind.PIXEL_RGB.mID, true, 3);
542        rs.nInitElements(a8, rgba4444, rgba8888, rgb565);
543    }
544}
545
546