Element.java revision 718cd1f322ee5b62b6a49cb36195bcb18a5ab711
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;
20
21/**
22 * @hide
23 *
24 **/
25public class Element extends BaseObj {
26    int mSize;
27    Element[] mElements;
28    String[] mElementNames;
29
30    DataType mType;
31    DataKind mKind;
32    boolean mNormalized;
33    int mVectorSize;
34
35    int getSizeBytes() {return mSize;}
36
37    public enum DataType {
38        //FLOAT_16 (1, 2),
39        FLOAT_32 (2, 4),
40        //FLOAT_64 (3, 8),
41        SIGNED_8 (4, 1),
42        SIGNED_16 (5, 2),
43        SIGNED_32 (6, 4),
44        //SIGNED_64 (7, 8),
45        UNSIGNED_8 (8, 1),
46        UNSIGNED_16 (9, 2),
47        UNSIGNED_32 (10, 4),
48        //UNSIGNED_64 (11, 8),
49
50        UNSIGNED_5_6_5 (12, 2),
51        UNSIGNED_5_5_5_1 (13, 2),
52        UNSIGNED_4_4_4_4 (14, 2),
53
54        RS_ELEMENT (15, 4),
55        RS_TYPE (16, 4),
56        RS_ALLOCATION (17, 4),
57        RS_SAMPLER (18, 4),
58        RS_SCRIPT (19, 4),
59        RS_MESH (20, 4),
60        RS_PROGRAM_FRAGMENT (21, 4),
61        RS_PROGRAM_VERTEX (22, 4),
62        RS_PROGRAM_RASTER (23, 4),
63        RS_PROGRAM_STORE (24, 4);
64
65        int mID;
66        int mSize;
67        DataType(int id, int size) {
68            mID = id;
69            mSize = size;
70        }
71    }
72
73    public enum DataKind {
74        USER (0),
75        COLOR (1),
76        POSITION (2),
77        TEXTURE (3),
78        NORMAL (4),
79        INDEX (5),
80        POINT_SIZE(6),
81
82        PIXEL_L (7),
83        PIXEL_A (8),
84        PIXEL_LA (9),
85        PIXEL_RGB (10),
86        PIXEL_RGBA (11);
87
88        int mID;
89        DataKind(int id) {
90            mID = id;
91        }
92    }
93
94    public static Element USER_U8(RenderScript rs) {
95        if(rs.mElement_USER_U8 == null) {
96            rs.mElement_USER_U8 = createUser(rs, DataType.UNSIGNED_8);
97        }
98        return rs.mElement_USER_U8;
99    }
100
101    public static Element USER_I8(RenderScript rs) {
102        if(rs.mElement_USER_I8 == null) {
103            rs.mElement_USER_I8 = createUser(rs, DataType.SIGNED_8);
104        }
105        return rs.mElement_USER_I8;
106    }
107
108    public static Element USER_U32(RenderScript rs) {
109        if(rs.mElement_USER_U32 == null) {
110            rs.mElement_USER_U32 = createUser(rs, DataType.UNSIGNED_32);
111        }
112        return rs.mElement_USER_U32;
113    }
114
115    public static Element USER_I32(RenderScript rs) {
116        if(rs.mElement_USER_I32 == null) {
117            rs.mElement_USER_I32 = createUser(rs, DataType.SIGNED_32);
118        }
119        return rs.mElement_USER_I32;
120    }
121
122    public static Element USER_F32(RenderScript rs) {
123        if(rs.mElement_USER_F32 == null) {
124            rs.mElement_USER_F32 = createUser(rs, DataType.FLOAT_32);
125        }
126        return rs.mElement_USER_F32;
127    }
128
129    public static Element A_8(RenderScript rs) {
130        if(rs.mElement_A_8 == null) {
131            rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A);
132        }
133        return rs.mElement_A_8;
134    }
135
136    public static Element RGB_565(RenderScript rs) {
137        if(rs.mElement_RGB_565 == null) {
138            rs.mElement_RGB_565 = createPixel(rs, DataType.UNSIGNED_5_6_5, DataKind.PIXEL_RGB);
139        }
140        return rs.mElement_RGB_565;
141    }
142
143    public static Element RGB_888(RenderScript rs) {
144        if(rs.mElement_RGB_888 == null) {
145            rs.mElement_RGB_888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGB);
146        }
147        return rs.mElement_RGB_888;
148    }
149
150    public static Element RGBA_5551(RenderScript rs) {
151        if(rs.mElement_RGBA_5551 == null) {
152            rs.mElement_RGBA_5551 = createPixel(rs, DataType.UNSIGNED_5_5_5_1, DataKind.PIXEL_RGBA);
153        }
154        return rs.mElement_RGBA_5551;
155    }
156
157    public static Element RGBA_4444(RenderScript rs) {
158        if(rs.mElement_RGBA_4444 == null) {
159            rs.mElement_RGBA_4444 = createPixel(rs, DataType.UNSIGNED_4_4_4_4, DataKind.PIXEL_RGBA);
160        }
161        return rs.mElement_RGBA_4444;
162    }
163
164    public static Element RGBA_8888(RenderScript rs) {
165        if(rs.mElement_RGBA_8888 == null) {
166            rs.mElement_RGBA_8888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGBA);
167        }
168        return rs.mElement_RGBA_8888;
169    }
170
171    public static Element INDEX_16(RenderScript rs) {
172        if(rs.mElement_INDEX_16 == null) {
173            rs.mElement_INDEX_16 = createIndex(rs);
174        }
175        return rs.mElement_INDEX_16;
176    }
177
178    public static Element ATTRIB_POSITION_2(RenderScript rs) {
179        if(rs.mElement_POSITION_2 == null) {
180            rs.mElement_POSITION_2 = createAttrib(rs, DataType.FLOAT_32, DataKind.POSITION, 2);
181        }
182        return rs.mElement_POSITION_2;
183    }
184
185    public static Element ATTRIB_POSITION_3(RenderScript rs) {
186        if(rs.mElement_POSITION_3 == null) {
187            rs.mElement_POSITION_3 = createAttrib(rs, DataType.FLOAT_32, DataKind.POSITION, 3);
188        }
189        return rs.mElement_POSITION_3;
190    }
191
192    public static Element ATTRIB_TEXTURE_2(RenderScript rs) {
193        if(rs.mElement_TEXTURE_2 == null) {
194            rs.mElement_TEXTURE_2 = createAttrib(rs, DataType.FLOAT_32, DataKind.TEXTURE, 2);
195        }
196        return rs.mElement_TEXTURE_2;
197    }
198
199    public static Element ATTRIB_NORMAL_3(RenderScript rs) {
200        if(rs.mElement_NORMAL_3 == null) {
201            rs.mElement_NORMAL_3 = createAttrib(rs, DataType.FLOAT_32, DataKind.NORMAL, 3);
202        }
203        return rs.mElement_NORMAL_3;
204    }
205
206    public static Element ATTRIB_COLOR_U8_4(RenderScript rs) {
207        if(rs.mElement_COLOR_U8_4 == null) {
208            rs.mElement_COLOR_U8_4 = createAttrib(rs, DataType.UNSIGNED_8, DataKind.COLOR, 4);
209        }
210        return rs.mElement_COLOR_U8_4;
211    }
212
213    public static Element ATTRIB_COLOR_F32_4(RenderScript rs) {
214        if(rs.mElement_COLOR_F32_4 == null) {
215            rs.mElement_COLOR_F32_4 = createAttrib(rs, DataType.FLOAT_32, DataKind.COLOR, 4);
216        }
217        return rs.mElement_COLOR_F32_4;
218    }
219
220    Element(RenderScript rs, Element[] e, String[] n) {
221        super(rs);
222        mSize = 0;
223        mElements = e;
224        mElementNames = n;
225        int[] ids = new int[mElements.length];
226        for (int ct = 0; ct < mElements.length; ct++ ) {
227            mSize += mElements[ct].mSize;
228            ids[ct] = mElements[ct].mID;
229        }
230        mID = rs.nElementCreate2(ids, mElementNames);
231    }
232
233    Element(RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
234        super(rs);
235        mSize = dt.mSize * size;
236        mType = dt;
237        mKind = dk;
238        mNormalized = norm;
239        mVectorSize = size;
240        mID = rs.nElementCreate(dt.mID, dk.mID, norm, size);
241    }
242
243    public void destroy() throws IllegalStateException {
244        super.destroy();
245    }
246
247    public static Element createFromClass(RenderScript rs, Class c) {
248        rs.validate();
249        Field[] fields = c.getFields();
250        Builder b = new Builder(rs);
251
252        for(Field f: fields) {
253            Class fc = f.getType();
254            if(fc == int.class) {
255                b.add(createUser(rs, DataType.SIGNED_32), f.getName());
256            } else if(fc == short.class) {
257                b.add(createUser(rs, DataType.SIGNED_16), f.getName());
258            } else if(fc == byte.class) {
259                b.add(createUser(rs, DataType.SIGNED_8), f.getName());
260            } else if(fc == float.class) {
261                b.add(createUser(rs, DataType.FLOAT_32), f.getName());
262            } else {
263                throw new IllegalArgumentException("Unkown field type");
264            }
265        }
266        return b.create();
267    }
268
269
270    /////////////////////////////////////////
271    public static Element createUser(RenderScript rs, DataType dt) {
272        //android.util.Log.e("rs", "createUser " + dt.mID);
273        return new Element(rs, dt, DataKind.USER, false, 1);
274    }
275
276    public static Element createVector(RenderScript rs, DataType dt, int size) {
277        //android.util.Log.e("rs", "createVector " + dt.mID + ", " + size);
278        if (size < 2 || size > 4) {
279            throw new IllegalArgumentException("Bad size");
280        }
281        return new Element(rs, dt, DataKind.USER, false, size);
282    }
283
284    public static Element createIndex(RenderScript rs) {
285        android.util.Log.e("rs", "createIndex ");
286        return new Element(rs, DataType.UNSIGNED_16, DataKind.INDEX, false, 1);
287    }
288
289    public static Element createAttrib(RenderScript rs, DataType dt, DataKind dk, int size) {
290        android.util.Log.e("rs", "createAttrib " + dt.mID + ", " + dk.mID + ", " + size);
291        if (!(dt == DataType.FLOAT_32 ||
292              dt == DataType.UNSIGNED_8 ||
293              dt == DataType.UNSIGNED_16 ||
294              dt == DataType.UNSIGNED_32 ||
295              dt == DataType.SIGNED_8 ||
296              dt == DataType.SIGNED_16 ||
297              dt == DataType.SIGNED_32)) {
298            throw new IllegalArgumentException("Unsupported DataType");
299        }
300
301        if (!(dk == DataKind.COLOR ||
302              dk == DataKind.POSITION ||
303              dk == DataKind.TEXTURE ||
304              dk == DataKind.NORMAL ||
305              dk == DataKind.POINT_SIZE)) {
306            throw new IllegalArgumentException("Unsupported DataKind");
307        }
308
309        if (dk == DataKind.COLOR &&
310            ((dt != DataType.FLOAT_32 && dt != DataType.UNSIGNED_8) ||
311             size < 3 || size > 4)) {
312            throw new IllegalArgumentException("Bad combo");
313        }
314        if (dk == DataKind.POSITION && (size < 1 || size > 4)) {
315            throw new IllegalArgumentException("Bad combo");
316        }
317        if (dk == DataKind.TEXTURE &&
318            (dt != DataType.FLOAT_32 || size < 1 || size > 4)) {
319            throw new IllegalArgumentException("Bad combo");
320        }
321        if (dk == DataKind.NORMAL &&
322            (dt != DataType.FLOAT_32 || size != 3)) {
323            throw new IllegalArgumentException("Bad combo");
324        }
325        if (dk == DataKind.POINT_SIZE &&
326            (dt != DataType.FLOAT_32 || size != 1)) {
327            throw new IllegalArgumentException("Bad combo");
328        }
329
330        boolean norm = false;
331        if (dk == DataKind.COLOR && dt == DataType.UNSIGNED_8) {
332            norm = true;
333        }
334
335        return new Element(rs, dt, dk, norm, size);
336    }
337
338    public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
339        android.util.Log.e("rs", "createPixel " + dt.mID + ", " + dk.mID);
340        if (!(dk == DataKind.PIXEL_L ||
341              dk == DataKind.PIXEL_A ||
342              dk == DataKind.PIXEL_LA ||
343              dk == DataKind.PIXEL_RGB ||
344              dk == DataKind.PIXEL_RGBA)) {
345            throw new IllegalArgumentException("Unsupported DataKind");
346        }
347        if (!(dt == DataType.UNSIGNED_8 ||
348              dt == DataType.UNSIGNED_5_6_5 ||
349              dt == DataType.UNSIGNED_4_4_4_4 ||
350              dt == DataType.UNSIGNED_5_5_5_1)) {
351            throw new IllegalArgumentException("Unsupported DataType");
352        }
353        if (dt == DataType.UNSIGNED_5_6_5 && dk != DataKind.PIXEL_RGB) {
354            throw new IllegalArgumentException("Bad kind and type combo");
355        }
356        if (dt == DataType.UNSIGNED_5_5_5_1 && dk != DataKind.PIXEL_RGBA) {
357            throw new IllegalArgumentException("Bad kind and type combo");
358        }
359        if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) {
360            throw new IllegalArgumentException("Bad kind and type combo");
361        }
362
363        int size = 1;
364        if (dk == DataKind.PIXEL_LA) {
365            size = 2;
366        }
367        if (dk == DataKind.PIXEL_RGB) {
368            size = 3;
369        }
370        if (dk == DataKind.PIXEL_RGBA) {
371            size = 4;
372        }
373
374        return new Element(rs, dt, dk, true, size);
375    }
376
377    public static class Builder {
378        RenderScript mRS;
379        Element[] mElements;
380        String[] mElementNames;
381        int mCount;
382
383        public Builder(RenderScript rs) {
384            mRS = rs;
385            mCount = 0;
386            mElements = new Element[8];
387            mElementNames = new String[8];
388        }
389
390        public void add(Element element, String name) {
391            if(mCount == mElements.length) {
392                Element[] e = new Element[mCount + 8];
393                String[] s = new String[mCount + 8];
394                System.arraycopy(mElements, 0, e, 0, mCount);
395                System.arraycopy(mElementNames, 0, s, 0, mCount);
396                mElements = e;
397                mElementNames = s;
398            }
399            mElements[mCount] = element;
400            mElementNames[mCount] = name;
401            mCount++;
402        }
403
404        public Element create() {
405            mRS.validate();
406            Element[] ein = new Element[mCount];
407            String[] sin = new String[mCount];
408            java.lang.System.arraycopy(mElements, 0, ein, 0, mCount);
409            java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
410            return new Element(mRS, ein, sin);
411        }
412    }
413
414    static void initPredefined(RenderScript rs) {
415        int a8 = rs.nElementCreate(DataType.UNSIGNED_8.mID,
416                                   DataKind.PIXEL_A.mID, true, 1);
417        int rgba4444 = rs.nElementCreate(DataType.UNSIGNED_4_4_4_4.mID,
418                                         DataKind.PIXEL_RGBA.mID, true, 4);
419        int rgba8888 = rs.nElementCreate(DataType.UNSIGNED_8.mID,
420                                         DataKind.PIXEL_RGBA.mID, true, 4);
421        int rgb565 = rs.nElementCreate(DataType.UNSIGNED_5_6_5.mID,
422                                       DataKind.PIXEL_RGB.mID, true, 3);
423        rs.nInitElements(a8, rgba4444, rgba8888, rgb565);
424    }
425}
426
427