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 20 import java.lang.reflect.Field; 21 import android.util.Log; 22 23 /** 24 * <p>Type is an allocation template. It consists of an Element and one or more 25 * dimensions. It describes only the layout of memory but does not allocate any 26 * storage for the data that is described.</p> 27 * 28 * <p>A Type consists of several dimensions. Those are X, Y, Z, LOD (level of 29 * detail), Faces (faces of a cube map). The X,Y,Z dimensions can be assigned 30 * any positive integral value within the constraints of available memory. A 31 * single dimension allocation would have an X dimension of greater than zero 32 * while the Y and Z dimensions would be zero to indicate not present. In this 33 * regard an allocation of x=10, y=1 would be considered 2 dimensionsal while 34 * x=10, y=0 would be considered 1 dimensional.</p> 35 * 36 * <p>The LOD and Faces dimensions are booleans to indicate present or not present.</p> 37 * 38 **/ 39 public class Type extends BaseObj { 40 int mDimX; 41 int mDimY; 42 int mDimZ; 43 boolean mDimMipmaps; 44 boolean mDimFaces; 45 int mElementCount; 46 Element mElement; 47 48 public enum CubemapFace { 49 POSITIVE_X (0), 50 NEGATIVE_X (1), 51 POSITIVE_Y (2), 52 NEGATIVE_Y (3), 53 POSITIVE_Z (4), 54 NEGATIVE_Z (5), 55 @Deprecated 56 POSITVE_X (0), 57 @Deprecated 58 POSITVE_Y (2), 59 @Deprecated 60 POSITVE_Z (4); 61 62 int mID; 63 CubemapFace(int id) { 64 mID = id; 65 } 66 } 67 68 /** 69 * Return the element associated with this Type. 70 * 71 * @return Element 72 */ 73 public Element getElement() { 74 return mElement; 75 } 76 77 /** 78 * Return the value of the X dimension. 79 * 80 * @return int 81 */ 82 public int getX() { 83 return mDimX; 84 } 85 86 /** 87 * Return the value of the Y dimension or 0 for a 1D allocation. 88 * 89 * @return int 90 */ 91 public int getY() { 92 return mDimY; 93 } 94 95 /** 96 * Return the value of the Z dimension or 0 for a 1D or 2D allocation. 97 * 98 * @return int 99 */ 100 public int getZ() { 101 return mDimZ; 102 } 103 104 /** 105 * Return if the Type has a mipmap chain. 106 * 107 * @return boolean 108 */ 109 public boolean hasMipmaps() { 110 return mDimMipmaps; 111 } 112 113 /** 114 * Return if the Type is a cube map. 115 * 116 * @return boolean 117 */ 118 public boolean hasFaces() { 119 return mDimFaces; 120 } 121 122 /** 123 * Return the total number of accessable cells in the Type. 124 * 125 * @return int 126 */ 127 public int getCount() { 128 return mElementCount; 129 } 130 131 void calcElementCount() { 132 boolean hasLod = hasMipmaps(); 133 int x = getX(); 134 int y = getY(); 135 int z = getZ(); 136 int faces = 1; 137 if (hasFaces()) { 138 faces = 6; 139 } 140 if (x == 0) { 141 x = 1; 142 } 143 if (y == 0) { 144 y = 1; 145 } 146 if (z == 0) { 147 z = 1; 148 } 149 150 int count = x * y * z * faces; 151 152 while (hasLod && ((x > 1) || (y > 1) || (z > 1))) { 153 if(x > 1) { 154 x >>= 1; 155 } 156 if(y > 1) { 157 y >>= 1; 158 } 159 if(z > 1) { 160 z >>= 1; 161 } 162 163 count += x * y * z * faces; 164 } 165 mElementCount = count; 166 } 167 168 169 Type(int id, RenderScript rs) { 170 super(id, rs); 171 } 172 173 @Override 174 void updateFromNative() { 175 // We have 6 integer to obtain mDimX; mDimY; mDimZ; 176 // mDimLOD; mDimFaces; mElement; 177 int[] dataBuffer = new int[6]; 178 mRS.nTypeGetNativeData(getID(), dataBuffer); 179 180 mDimX = dataBuffer[0]; 181 mDimY = dataBuffer[1]; 182 mDimZ = dataBuffer[2]; 183 mDimMipmaps = dataBuffer[3] == 1 ? true : false; 184 mDimFaces = dataBuffer[4] == 1 ? true : false; 185 186 int elementID = dataBuffer[5]; 187 if(elementID != 0) { 188 mElement = new Element(elementID, mRS); 189 mElement.updateFromNative(); 190 } 191 calcElementCount(); 192 } 193 194 /** 195 * Builder class for Type. 196 * 197 */ 198 public static class Builder { 199 RenderScript mRS; 200 int mDimX = 1; 201 int mDimY; 202 int mDimZ; 203 boolean mDimMipmaps; 204 boolean mDimFaces; 205 206 Element mElement; 207 208 /** 209 * Create a new builder object. 210 * 211 * @param rs 212 * @param e The element for the type to be created. 213 */ 214 public Builder(RenderScript rs, Element e) { 215 e.checkValid(); 216 mRS = rs; 217 mElement = e; 218 } 219 220 /** 221 * Add a dimension to the Type. 222 * 223 * 224 * @param value 225 */ 226 public Builder setX(int value) { 227 if(value < 1) { 228 throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid."); 229 } 230 mDimX = value; 231 return this; 232 } 233 234 public Builder setY(int value) { 235 if(value < 1) { 236 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid."); 237 } 238 mDimY = value; 239 return this; 240 } 241 242 public Builder setMipmaps(boolean value) { 243 mDimMipmaps = value; 244 return this; 245 } 246 247 public Builder setFaces(boolean value) { 248 mDimFaces = value; 249 return this; 250 } 251 252 253 /** 254 * Validate structure and create a new type. 255 * 256 * @return Type 257 */ 258 public Type create() { 259 if (mDimZ > 0) { 260 if ((mDimX < 1) || (mDimY < 1)) { 261 throw new RSInvalidStateException("Both X and Y dimension required when Z is present."); 262 } 263 if (mDimFaces) { 264 throw new RSInvalidStateException("Cube maps not supported with 3D types."); 265 } 266 } 267 if (mDimY > 0) { 268 if (mDimX < 1) { 269 throw new RSInvalidStateException("X dimension required when Y is present."); 270 } 271 } 272 if (mDimFaces) { 273 if (mDimY < 1) { 274 throw new RSInvalidStateException("Cube maps require 2D Types."); 275 } 276 } 277 278 int id = mRS.nTypeCreate(mElement.getID(), mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces); 279 Type t = new Type(id, mRS); 280 t.mElement = mElement; 281 t.mDimX = mDimX; 282 t.mDimY = mDimY; 283 t.mDimZ = mDimZ; 284 t.mDimMipmaps = mDimMipmaps; 285 t.mDimFaces = mDimFaces; 286 287 t.calcElementCount(); 288 return t; 289 } 290 } 291 292 } 293