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