Type.java revision 768bc02d815a94ad29146f1ed60c847d1af118cc
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 Type extends BaseObj {
26    int mDimX;
27    int mDimY;
28    int mDimZ;
29    boolean mDimLOD;
30    boolean mDimFaces;
31    int mElementCount;
32    Element mElement;
33
34    private int mNativeCache;
35    Class mJavaClass;
36
37
38    public int getX() {
39        return mDimX;
40    }
41    public int getY() {
42        return mDimY;
43    }
44    public int getZ() {
45        return mDimZ;
46    }
47    public boolean getLOD() {
48        return mDimLOD;
49    }
50    public boolean getFaces() {
51        return mDimFaces;
52    }
53    public int getElementCount() {
54        return mElementCount;
55    }
56
57    void calcElementCount() {
58        boolean hasLod = getLOD();
59        int x = getX();
60        int y = getY();
61        int z = getZ();
62        int faces = 1;
63        if(getFaces()) {
64            faces = 6;
65        }
66        if(x == 0) {
67            x = 1;
68        }
69        if(y == 0) {
70            y = 1;
71        }
72        if(z == 0) {
73            z = 1;
74        }
75
76        int count = x * y * z * faces;
77        if(hasLod && (x > 1) && (y > 1) && (z > 1)) {
78            if(x > 1) {
79                x >>= 1;
80            }
81            if(y > 1) {
82                y >>= 1;
83            }
84            if(z > 1) {
85                z >>= 1;
86            }
87
88            count += x * y * z * faces;
89        }
90        mElementCount = count;
91    }
92
93
94    Type(int id, RenderScript rs) {
95        super(rs);
96        mID = id;
97        mNativeCache = 0;
98    }
99
100    protected void finalize() throws Throwable {
101        if(mNativeCache != 0) {
102            mRS.nTypeFinalDestroy(this);
103            mNativeCache = 0;
104        }
105        super.finalize();
106    }
107
108    public static Type createFromClass(RenderScript rs, Class c, int size) {
109        Element e = Element.createFromClass(rs, c);
110        Builder b = new Builder(rs, e);
111        b.add(Dimension.X, size);
112        Type t = b.create();
113        e.destroy();
114
115        // native fields
116        {
117            Field[] fields = c.getFields();
118            int[] arTypes = new int[fields.length];
119            int[] arBits = new int[fields.length];
120
121            for(int ct=0; ct < fields.length; ct++) {
122                Field f = fields[ct];
123                Class fc = f.getType();
124                if(fc == int.class) {
125                    arTypes[ct] = Element.DataType.SIGNED.mID;
126                    arBits[ct] = 32;
127                } else if(fc == short.class) {
128                    arTypes[ct] = Element.DataType.SIGNED.mID;
129                    arBits[ct] = 16;
130                } else if(fc == byte.class) {
131                    arTypes[ct] = Element.DataType.SIGNED.mID;
132                    arBits[ct] = 8;
133                } else if(fc == float.class) {
134                    arTypes[ct] = Element.DataType.FLOAT.mID;
135                    arBits[ct] = 32;
136                } else {
137                    throw new IllegalArgumentException("Unkown field type");
138                }
139            }
140            rs.nTypeSetupFields(t, arTypes, arBits, fields);
141        }
142        t.mJavaClass = c;
143        return t;
144    }
145
146    public static Type createFromClass(RenderScript rs, Class c, int size, String scriptName) {
147        Type t = createFromClass(rs, c, size);
148        t.setName(scriptName);
149        return t;
150    }
151
152
153    public static class Builder {
154        RenderScript mRS;
155        Entry[] mEntries;
156        int mEntryCount;
157        Element mElement;
158
159        class Entry {
160            Dimension mDim;
161            int mValue;
162        }
163
164        public Builder(RenderScript rs, Element e) {
165            mRS = rs;
166            mEntries = new Entry[4];
167            mElement = e;
168        }
169
170        public void add(Dimension d, int value) {
171            if(mEntries.length >= mEntryCount) {
172                Entry[] en = new Entry[mEntryCount + 8];
173                System.arraycopy(mEntries, 0, en, 0, mEntries.length);
174                mEntries = en;
175            }
176            mEntries[mEntryCount] = new Entry();
177            mEntries[mEntryCount].mDim = d;
178            mEntries[mEntryCount].mValue = value;
179            mEntryCount++;
180        }
181
182        static synchronized Type internalCreate(RenderScript rs, Builder b) {
183            rs.nTypeBegin(b.mElement.mID);
184            for (int ct=0; ct < b.mEntryCount; ct++) {
185                Entry en = b.mEntries[ct];
186                rs.nTypeAdd(en.mDim.mID, en.mValue);
187            }
188            int id = rs.nTypeCreate();
189            return new Type(id, rs);
190        }
191
192        public Type create() {
193            Type t = internalCreate(mRS, this);
194            t.mElement = mElement;
195
196            for(int ct=0; ct < mEntryCount; ct++) {
197                if(mEntries[ct].mDim == Dimension.X) {
198                    t.mDimX = mEntries[ct].mValue;
199                }
200                if(mEntries[ct].mDim == Dimension.Y) {
201                    t.mDimY = mEntries[ct].mValue;
202                }
203                if(mEntries[ct].mDim == Dimension.Z) {
204                    t.mDimZ = mEntries[ct].mValue;
205                }
206                if(mEntries[ct].mDim == Dimension.LOD) {
207                    t.mDimLOD = mEntries[ct].mValue != 0;
208                }
209                if(mEntries[ct].mDim == Dimension.FACE) {
210                    t.mDimFaces = mEntries[ct].mValue != 0;
211                }
212            }
213            t.calcElementCount();
214            return t;
215        }
216    }
217
218}
219