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