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