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