Element.java revision 7d46f612a25fc9f190358e9bd807b71d424ce7d2
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        return new Element(rs, dt, DataKind.USER, false, 1);
273    }
274
275    public static Element createVector(RenderScript rs, DataType dt, int size) {
276        if (size < 2 || size > 4) {
277            throw new IllegalArgumentException("Bad size");
278        }
279        return new Element(rs, dt, DataKind.USER, false, size);
280    }
281
282    public static Element createIndex(RenderScript rs) {
283        return new Element(rs, DataType.UNSIGNED_16, DataKind.INDEX, false, 1);
284    }
285
286    public static Element createAttrib(RenderScript rs, DataType dt, DataKind dk, int size) {
287        if (!(dt == DataType.FLOAT_32 ||
288              dt == DataType.UNSIGNED_8 ||
289              dt == DataType.UNSIGNED_16 ||
290              dt == DataType.UNSIGNED_32 ||
291              dt == DataType.SIGNED_8 ||
292              dt == DataType.SIGNED_16 ||
293              dt == DataType.SIGNED_32)) {
294            throw new IllegalArgumentException("Unsupported DataType");
295        }
296
297        if (!(dk == DataKind.COLOR ||
298              dk == DataKind.POSITION ||
299              dk == DataKind.TEXTURE ||
300              dk == DataKind.NORMAL ||
301              dk == DataKind.POINT_SIZE)) {
302            throw new IllegalArgumentException("Unsupported DataKind");
303        }
304
305        if (dk == DataKind.COLOR &&
306            ((dt != DataType.FLOAT_32 && dt != DataType.UNSIGNED_8) ||
307             size < 3 || size > 4)) {
308            throw new IllegalArgumentException("Bad combo");
309        }
310        if (dk == DataKind.POSITION && (size < 1 || size > 4)) {
311            throw new IllegalArgumentException("Bad combo");
312        }
313        if (dk == DataKind.TEXTURE &&
314            (dt != DataType.FLOAT_32 || size < 1 || size > 4)) {
315            throw new IllegalArgumentException("Bad combo");
316        }
317        if (dk == DataKind.NORMAL &&
318            (dt != DataType.FLOAT_32 || size != 3)) {
319            throw new IllegalArgumentException("Bad combo");
320        }
321        if (dk == DataKind.POINT_SIZE &&
322            (dt != DataType.FLOAT_32 || size != 1)) {
323            throw new IllegalArgumentException("Bad combo");
324        }
325
326        boolean norm = false;
327        if (dk == DataKind.COLOR && dt == DataType.UNSIGNED_8) {
328            norm = true;
329        }
330
331        return new Element(rs, dt, dk, norm, size);
332    }
333
334    public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
335        if (!(dk == DataKind.PIXEL_L ||
336              dk == DataKind.PIXEL_A ||
337              dk == DataKind.PIXEL_LA ||
338              dk == DataKind.PIXEL_RGB ||
339              dk == DataKind.PIXEL_RGBA)) {
340            throw new IllegalArgumentException("Unsupported DataKind");
341        }
342        if (!(dt == DataType.UNSIGNED_8 ||
343              dt == DataType.UNSIGNED_5_6_5 ||
344              dt == DataType.UNSIGNED_4_4_4_4 ||
345              dt == DataType.UNSIGNED_5_5_5_1)) {
346            throw new IllegalArgumentException("Unsupported DataType");
347        }
348        if (dt == DataType.UNSIGNED_5_6_5 && dk != DataKind.PIXEL_RGB) {
349            throw new IllegalArgumentException("Bad kind and type combo");
350        }
351        if (dt == DataType.UNSIGNED_5_5_5_1 && dk != DataKind.PIXEL_RGBA) {
352            throw new IllegalArgumentException("Bad kind and type combo");
353        }
354        if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) {
355            throw new IllegalArgumentException("Bad kind and type combo");
356        }
357
358        int size = 1;
359        if (dk == DataKind.PIXEL_LA) {
360            size = 2;
361        }
362        if (dk == DataKind.PIXEL_RGB) {
363            size = 3;
364        }
365        if (dk == DataKind.PIXEL_RGBA) {
366            size = 4;
367        }
368
369        return new Element(rs, dt, dk, true, size);
370    }
371
372    public static class Builder {
373        RenderScript mRS;
374        Element[] mElements;
375        String[] mElementNames;
376        int mCount;
377
378        public Builder(RenderScript rs) {
379            mRS = rs;
380            mCount = 0;
381            mElements = new Element[8];
382            mElementNames = new String[8];
383        }
384
385        public void add(Element element, String name) {
386            if(mCount == mElements.length) {
387                Element[] e = new Element[mCount + 8];
388                String[] s = new String[mCount + 8];
389                System.arraycopy(mElements, 0, e, 0, mCount);
390                System.arraycopy(mElementNames, 0, s, 0, mCount);
391                mElements = e;
392                mElementNames = s;
393            }
394            mElements[mCount] = element;
395            mElementNames[mCount] = name;
396            mCount++;
397        }
398
399        public Element create() {
400            mRS.validate();
401            Element[] ein = new Element[mCount];
402            String[] sin = new String[mCount];
403            java.lang.System.arraycopy(mElements, 0, ein, 0, mCount);
404            java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
405            return new Element(mRS, ein, sin);
406        }
407    }
408
409    static void initPredefined(RenderScript rs) {
410        int a8 = rs.nElementCreate(DataType.UNSIGNED_8.mID,
411                                   DataKind.PIXEL_A.mID, true, 1);
412        int rgba4444 = rs.nElementCreate(DataType.UNSIGNED_4_4_4_4.mID,
413                                         DataKind.PIXEL_RGBA.mID, true, 4);
414        int rgba8888 = rs.nElementCreate(DataType.UNSIGNED_8.mID,
415                                         DataKind.PIXEL_RGBA.mID, true, 4);
416        int rgb565 = rs.nElementCreate(DataType.UNSIGNED_5_6_5.mID,
417                                       DataKind.PIXEL_RGB.mID, true, 3);
418        rs.nInitElements(a8, rgba4444, rgba8888, rgb565);
419    }
420}
421
422