1 /* 2 * Copyright (C) 2013 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 22 import android.graphics.ImageFormat; 23 import android.util.Log; 24 25 /** 26 * <p>A Type describes the {@link android.renderscript.Element} and dimensions used for an {@link 27 * android.renderscript.Allocation} or a parallel operation. Types are created through {@link 28 * android.renderscript.Type.Builder}.</p> 29 * 30 * <p>A Type always includes an {@link android.renderscript.Element} and an X 31 * dimension. A Type may be multidimensional, up to three dimensions. A nonzero 32 * value in the Y or Z dimensions indicates that the dimension is present. Note 33 * that a Type with only a given X dimension and a Type with the same X 34 * dimension but Y = 1 are not equivalent.</p> 35 * 36 * <p>A Type also supports inclusion of level of detail (LOD) or cube map 37 * faces. LOD and cube map faces are booleans to indicate present or not 38 * present. </p> 39 * 40 * <p>A Type also supports YUV format information to support an 41 * {@link android.renderscript.Allocation} in a YUV format. The YUV formats 42 * supported are {@link android.graphics.ImageFormat#YV12}, 43 * {@link android.graphics.ImageFormat#NV21}, and 44 * {@link android.graphics.ImageFormat#YUV_420_888}</p> 45 * 46 * <div class="special reference"> 47 * <h3>Developer Guides</h3> 48 * <p>For more information about creating an application that uses RenderScript, read the 49 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> 50 * </div> 51 **/ 52 public class Type extends BaseObj { 53 int mDimX; 54 int mDimY; 55 int mDimZ; 56 boolean mDimMipmaps; 57 boolean mDimFaces; 58 int mDimYuv; 59 int mElementCount; 60 Element mElement; 61 62 public enum CubemapFace { 63 POSITIVE_X (0), 64 NEGATIVE_X (1), 65 POSITIVE_Y (2), 66 NEGATIVE_Y (3), 67 POSITIVE_Z (4), 68 NEGATIVE_Z (5), 69 @Deprecated 70 POSITVE_X (0), 71 @Deprecated 72 POSITVE_Y (2), 73 @Deprecated 74 POSITVE_Z (4); 75 76 int mID; 77 CubemapFace(int id) { 78 mID = id; 79 } 80 } 81 82 /** 83 * Return the element associated with this Type. 84 * 85 * @return Element 86 */ 87 public Element getElement() { 88 return mElement; 89 } 90 91 /** 92 * Return the value of the X dimension. 93 * 94 * @return int 95 */ 96 public int getX() { 97 return mDimX; 98 } 99 100 /** 101 * Return the value of the Y dimension or 0 for a 1D allocation. 102 * 103 * @return int 104 */ 105 public int getY() { 106 return mDimY; 107 } 108 109 /** 110 * Return the value of the Z dimension or 0 for a 1D or 2D allocation. 111 * 112 * @return int 113 */ 114 public int getZ() { 115 return mDimZ; 116 } 117 118 /** 119 * Get the YUV format 120 * 121 * 122 * @return int 123 */ 124 public int getYuv() { 125 return mDimYuv; 126 } 127 128 /** 129 * Return if the Type has a mipmap chain. 130 * 131 * @return boolean 132 */ 133 public boolean hasMipmaps() { 134 return mDimMipmaps; 135 } 136 137 /** 138 * Return if the Type is a cube map. 139 * 140 * @return boolean 141 */ 142 public boolean hasFaces() { 143 return mDimFaces; 144 } 145 146 /** 147 * Return the total number of accessable cells in the Type. 148 * 149 * @return int 150 */ 151 public int getCount() { 152 return mElementCount; 153 } 154 155 void calcElementCount() { 156 boolean hasLod = hasMipmaps(); 157 int x = getX(); 158 int y = getY(); 159 int z = getZ(); 160 int faces = 1; 161 if (hasFaces()) { 162 faces = 6; 163 } 164 if (x == 0) { 165 x = 1; 166 } 167 if (y == 0) { 168 y = 1; 169 } 170 if (z == 0) { 171 z = 1; 172 } 173 174 int count = x * y * z * faces; 175 176 while (hasLod && ((x > 1) || (y > 1) || (z > 1))) { 177 if(x > 1) { 178 x >>= 1; 179 } 180 if(y > 1) { 181 y >>= 1; 182 } 183 if(z > 1) { 184 z >>= 1; 185 } 186 187 count += x * y * z * faces; 188 } 189 mElementCount = count; 190 } 191 192 193 Type(int id, RenderScript rs) { 194 super(id, rs); 195 } 196 197 @Override 198 void updateFromNative() { 199 // We have 6 integer to obtain mDimX; mDimY; mDimZ; 200 // mDimLOD; mDimFaces; mElement; 201 int[] dataBuffer = new int[6]; 202 mRS.nTypeGetNativeData(getID(mRS), dataBuffer); 203 204 mDimX = dataBuffer[0]; 205 mDimY = dataBuffer[1]; 206 mDimZ = dataBuffer[2]; 207 mDimMipmaps = dataBuffer[3] == 1 ? true : false; 208 mDimFaces = dataBuffer[4] == 1 ? true : false; 209 210 int elementID = dataBuffer[5]; 211 if(elementID != 0) { 212 mElement = new Element(elementID, mRS); 213 mElement.updateFromNative(); 214 } 215 calcElementCount(); 216 } 217 218 /** 219 * Builder class for Type. 220 * 221 */ 222 public static class Builder { 223 RenderScript mRS; 224 int mDimX = 1; 225 int mDimY; 226 int mDimZ; 227 boolean mDimMipmaps; 228 boolean mDimFaces; 229 int mYuv; 230 231 Element mElement; 232 233 /** 234 * Create a new builder object. 235 * 236 * @param rs 237 * @param e The element for the type to be created. 238 */ 239 public Builder(RenderScript rs, Element e) { 240 e.checkValid(); 241 mRS = rs; 242 mElement = e; 243 } 244 245 /** 246 * Add a dimension to the Type. 247 * 248 * 249 * @param value 250 */ 251 public Builder setX(int value) { 252 if(value < 1) { 253 throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid."); 254 } 255 mDimX = value; 256 return this; 257 } 258 259 public Builder setY(int value) { 260 if(value < 1) { 261 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid."); 262 } 263 mDimY = value; 264 return this; 265 } 266 267 public Builder setZ(int value) { 268 if(value < 1) { 269 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Z are not valid."); 270 } 271 mDimZ = value; 272 return this; 273 } 274 275 public Builder setMipmaps(boolean value) { 276 mDimMipmaps = value; 277 return this; 278 } 279 280 public Builder setFaces(boolean value) { 281 mDimFaces = value; 282 return this; 283 } 284 285 /** 286 * Set the YUV layout for a Type. 287 * 288 * @param yuvFormat {@link android.graphics.ImageFormat#YV12}, {@link android.graphics.ImageFormat#NV21}, or 289 * {@link android.graphics.ImageFormat#YUV_420_888}. 290 */ 291 public Builder setYuvFormat(int yuvFormat) { 292 switch (yuvFormat) { 293 case android.graphics.ImageFormat.NV21: 294 case android.graphics.ImageFormat.YV12: 295 case android.graphics.ImageFormat.YUV_420_888: 296 break; 297 298 default: 299 throw new RSIllegalArgumentException( 300 "Only ImageFormat.NV21, .YV12, and .YUV_420_888 are supported.."); 301 } 302 303 mYuv = yuvFormat; 304 return this; 305 } 306 307 308 /** 309 * Validate structure and create a new Type. 310 * 311 * @return Type 312 */ 313 public Type create() { 314 if (mDimZ > 0) { 315 if ((mDimX < 1) || (mDimY < 1)) { 316 throw new RSInvalidStateException("Both X and Y dimension required when Z is present."); 317 } 318 if (mDimFaces) { 319 throw new RSInvalidStateException("Cube maps not supported with 3D types."); 320 } 321 } 322 if (mDimY > 0) { 323 if (mDimX < 1) { 324 throw new RSInvalidStateException("X dimension required when Y is present."); 325 } 326 } 327 if (mDimFaces) { 328 if (mDimY < 1) { 329 throw new RSInvalidStateException("Cube maps require 2D Types."); 330 } 331 } 332 333 if (mYuv != 0) { 334 if ((mDimZ != 0) || mDimFaces || mDimMipmaps) { 335 throw new RSInvalidStateException("YUV only supports basic 2D."); 336 } 337 } 338 339 int id = mRS.nTypeCreate(mElement.getID(mRS), 340 mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv); 341 Type t = new Type(id, mRS); 342 t.mElement = mElement; 343 t.mDimX = mDimX; 344 t.mDimY = mDimY; 345 t.mDimZ = mDimZ; 346 t.mDimMipmaps = mDimMipmaps; 347 t.mDimFaces = mDimFaces; 348 t.mDimYuv = mYuv; 349 350 t.calcElementCount(); 351 return t; 352 } 353 } 354 355 } 356