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 int mArrays[]; 56 57 static final int mMaxArrays = 4; 58 59 public enum CubemapFace { 60 POSITIVE_X (0), 61 NEGATIVE_X (1), 62 POSITIVE_Y (2), 63 NEGATIVE_Y (3), 64 POSITIVE_Z (4), 65 NEGATIVE_Z (5), 66 @Deprecated 67 POSITVE_X (0), 68 @Deprecated 69 POSITVE_Y (2), 70 @Deprecated 71 POSITVE_Z (4); 72 73 int mID; CubemapFace(int id)74 CubemapFace(int id) { 75 mID = id; 76 } 77 } 78 79 /** 80 * Return the element associated with this Type. 81 * 82 * @return Element 83 */ getElement()84 public Element getElement() { 85 return mElement; 86 } 87 88 /** 89 * Return the value of the X dimension. 90 * 91 * @return int 92 */ getX()93 public int getX() { 94 return mDimX; 95 } 96 97 /** 98 * Return the value of the Y dimension or 0 for a 1D allocation. 99 * 100 * @return int 101 */ getY()102 public int getY() { 103 return mDimY; 104 } 105 106 /** 107 * Return the value of the Z dimension or 0 for a 1D or 2D allocation. 108 * 109 * @return int 110 */ getZ()111 public int getZ() { 112 return mDimZ; 113 } 114 115 /** 116 * Get the YUV format 117 * 118 * 119 * @return int 120 */ getYuv()121 public int getYuv() { 122 return mDimYuv; 123 } 124 125 /** 126 * Return if the Type has a mipmap chain. 127 * 128 * @return boolean 129 */ hasMipmaps()130 public boolean hasMipmaps() { 131 return mDimMipmaps; 132 } 133 134 /** 135 * Return if the Type is a cube map. 136 * 137 * @return boolean 138 */ hasFaces()139 public boolean hasFaces() { 140 return mDimFaces; 141 } 142 143 /** 144 * Return the total number of accessable cells in the Type. 145 * 146 * @return int 147 */ getCount()148 public int getCount() { 149 return mElementCount; 150 } 151 152 /** 153 * @hide 154 * Return the dimension of the specified array. 155 * 156 * @param arrayNum The array dimension to query 157 * @return int 158 */ getArray(int arrayNum)159 public int getArray(int arrayNum) { 160 if ((arrayNum < 0) || (arrayNum >= mMaxArrays)) { 161 throw new RSIllegalArgumentException("Array dimension out of range."); 162 } 163 164 if (mArrays == null || arrayNum >= mArrays.length) { 165 // Dimension in range but no array for that dimension allocated 166 return 0; 167 } 168 169 return mArrays[arrayNum]; 170 } 171 172 /** 173 * @hide 174 * Return the number of array dimensions. 175 * 176 * @return int 177 */ getArrayCount()178 public int getArrayCount() { 179 if (mArrays != null) return mArrays.length; 180 return 0; 181 } 182 calcElementCount()183 void calcElementCount() { 184 boolean hasLod = hasMipmaps(); 185 int x = getX(); 186 int y = getY(); 187 int z = getZ(); 188 int faces = 1; 189 if (hasFaces()) { 190 faces = 6; 191 } 192 if (x == 0) { 193 x = 1; 194 } 195 if (y == 0) { 196 y = 1; 197 } 198 if (z == 0) { 199 z = 1; 200 } 201 202 int count = x * y * z * faces; 203 204 while (hasLod && ((x > 1) || (y > 1) || (z > 1))) { 205 if(x > 1) { 206 x >>= 1; 207 } 208 if(y > 1) { 209 y >>= 1; 210 } 211 if(z > 1) { 212 z >>= 1; 213 } 214 215 count += x * y * z * faces; 216 } 217 218 if (mArrays != null) { 219 for (int ct = 0; ct < mArrays.length; ct++) { 220 count *= mArrays[ct]; 221 } 222 } 223 224 mElementCount = count; 225 } 226 227 Type(long id, RenderScript rs)228 Type(long id, RenderScript rs) { 229 super(id, rs); 230 guard.open("destroy"); 231 } 232 233 @Override updateFromNative()234 void updateFromNative() { 235 // We have 6 integer/long to obtain mDimX; mDimY; mDimZ; 236 // mDimLOD; mDimFaces; mElement; 237 long[] dataBuffer = new long[6]; 238 mRS.nTypeGetNativeData(getID(mRS), dataBuffer); 239 240 mDimX = (int)dataBuffer[0]; 241 mDimY = (int)dataBuffer[1]; 242 mDimZ = (int)dataBuffer[2]; 243 mDimMipmaps = dataBuffer[3] == 1 ? true : false; 244 mDimFaces = dataBuffer[4] == 1 ? true : false; 245 246 long elementID = dataBuffer[5]; 247 if(elementID != 0) { 248 mElement = new Element(elementID, mRS); 249 mElement.updateFromNative(); 250 } 251 calcElementCount(); 252 } 253 254 /** 255 * Utility function for creating basic 1D types. The type is 256 * created without mipmaps enabled. 257 * 258 * @param rs The RenderScript context 259 * @param e The Element for the Type 260 * @param dimX The X dimension, must be > 0 261 * 262 * @return Type 263 */ createX(RenderScript rs, Element e, int dimX)264 static public Type createX(RenderScript rs, Element e, int dimX) { 265 if (dimX < 1) { 266 throw new RSInvalidStateException("Dimension must be >= 1."); 267 } 268 269 long id = rs.nTypeCreate(e.getID(rs), dimX, 0, 0, false, false, 0); 270 Type t = new Type(id, rs); 271 t.mElement = e; 272 t.mDimX = dimX; 273 t.calcElementCount(); 274 return t; 275 } 276 277 /** 278 * Utility function for creating basic 2D types. The type is 279 * created without mipmaps or cubemaps. 280 * 281 * @param rs The RenderScript context 282 * @param e The Element for the Type 283 * @param dimX The X dimension, must be > 0 284 * @param dimY The Y dimension, must be > 0 285 * 286 * @return Type 287 */ createXY(RenderScript rs, Element e, int dimX, int dimY)288 static public Type createXY(RenderScript rs, Element e, int dimX, int dimY) { 289 if ((dimX < 1) || (dimY < 1)) { 290 throw new RSInvalidStateException("Dimension must be >= 1."); 291 } 292 293 long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, 0, false, false, 0); 294 Type t = new Type(id, rs); 295 t.mElement = e; 296 t.mDimX = dimX; 297 t.mDimY = dimY; 298 t.calcElementCount(); 299 return t; 300 } 301 302 /** 303 * Utility function for creating basic 3D types. The type is 304 * created without mipmaps. 305 * 306 * @param rs The RenderScript context 307 * @param e The Element for the Type 308 * @param dimX The X dimension, must be > 0 309 * @param dimY The Y dimension, must be > 0 310 * @param dimZ The Z dimension, must be > 0 311 * 312 * @return Type 313 */ createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ)314 static public Type createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ) { 315 if ((dimX < 1) || (dimY < 1) || (dimZ < 1)) { 316 throw new RSInvalidStateException("Dimension must be >= 1."); 317 } 318 319 long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, dimZ, false, false, 0); 320 Type t = new Type(id, rs); 321 t.mElement = e; 322 t.mDimX = dimX; 323 t.mDimY = dimY; 324 t.mDimZ = dimZ; 325 t.calcElementCount(); 326 return t; 327 } 328 329 /** 330 * Builder class for Type. 331 * 332 */ 333 public static class Builder { 334 RenderScript mRS; 335 int mDimX = 1; 336 int mDimY; 337 int mDimZ; 338 boolean mDimMipmaps; 339 boolean mDimFaces; 340 int mYuv; 341 int[] mArray = new int[mMaxArrays]; 342 343 Element mElement; 344 345 /** 346 * Create a new builder object. 347 * 348 * @param rs 349 * @param e The element for the type to be created. 350 */ Builder(RenderScript rs, Element e)351 public Builder(RenderScript rs, Element e) { 352 e.checkValid(); 353 mRS = rs; 354 mElement = e; 355 } 356 357 /** 358 * Add a dimension to the Type. 359 * 360 * 361 * @param value 362 */ setX(int value)363 public Builder setX(int value) { 364 if(value < 1) { 365 throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid."); 366 } 367 mDimX = value; 368 return this; 369 } 370 setY(int value)371 public Builder setY(int value) { 372 if(value < 1) { 373 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid."); 374 } 375 mDimY = value; 376 return this; 377 } 378 setZ(int value)379 public Builder setZ(int value) { 380 if(value < 1) { 381 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Z are not valid."); 382 } 383 mDimZ = value; 384 return this; 385 } 386 387 /** 388 * @hide 389 * Adds an array dimension to the builder 390 * 391 * @param dim 392 * @param value 393 * 394 * @return Builder 395 */ setArray(int dim, int value)396 public Builder setArray(int dim, int value) { 397 if(dim < 0 || dim >= mMaxArrays) { 398 throw new RSIllegalArgumentException("Array dimension out of range."); 399 } 400 mArray[dim] = value; 401 return this; 402 } 403 setMipmaps(boolean value)404 public Builder setMipmaps(boolean value) { 405 mDimMipmaps = value; 406 return this; 407 } 408 setFaces(boolean value)409 public Builder setFaces(boolean value) { 410 mDimFaces = value; 411 return this; 412 } 413 414 /** 415 * Set the YUV layout for a Type. 416 * 417 * @param yuvFormat {@link android.graphics.ImageFormat#YV12}, {@link android.graphics.ImageFormat#NV21}, or 418 * {@link android.graphics.ImageFormat#YUV_420_888}. 419 */ setYuvFormat(int yuvFormat)420 public Builder setYuvFormat(int yuvFormat) { 421 switch (yuvFormat) { 422 case android.graphics.ImageFormat.NV21: 423 case android.graphics.ImageFormat.YV12: 424 case android.graphics.ImageFormat.YUV_420_888: 425 break; 426 427 default: 428 throw new RSIllegalArgumentException( 429 "Only ImageFormat.NV21, .YV12, and .YUV_420_888 are supported.."); 430 } 431 432 mYuv = yuvFormat; 433 return this; 434 } 435 436 437 /** 438 * Validate structure and create a new Type. 439 * 440 * @return Type 441 */ create()442 public Type create() { 443 if (mDimZ > 0) { 444 if ((mDimX < 1) || (mDimY < 1)) { 445 throw new RSInvalidStateException("Both X and Y dimension required when Z is present."); 446 } 447 if (mDimFaces) { 448 throw new RSInvalidStateException("Cube maps not supported with 3D types."); 449 } 450 } 451 if (mDimY > 0) { 452 if (mDimX < 1) { 453 throw new RSInvalidStateException("X dimension required when Y is present."); 454 } 455 } 456 if (mDimFaces) { 457 if (mDimY < 1) { 458 throw new RSInvalidStateException("Cube maps require 2D Types."); 459 } 460 } 461 462 if (mYuv != 0) { 463 if ((mDimZ != 0) || mDimFaces || mDimMipmaps) { 464 throw new RSInvalidStateException("YUV only supports basic 2D."); 465 } 466 } 467 468 int[] arrays = null; 469 for (int ct = mMaxArrays - 1; ct >= 0; ct--) { 470 if (mArray[ct] != 0 && arrays == null) { 471 arrays = new int[ct]; 472 } 473 if ((mArray[ct] == 0) && (arrays != null)) { 474 throw new RSInvalidStateException("Array dimensions must be contigous from 0."); 475 } 476 } 477 478 long id = mRS.nTypeCreate(mElement.getID(mRS), 479 mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv); 480 Type t = new Type(id, mRS); 481 t.mElement = mElement; 482 t.mDimX = mDimX; 483 t.mDimY = mDimY; 484 t.mDimZ = mDimZ; 485 t.mDimMipmaps = mDimMipmaps; 486 t.mDimFaces = mDimFaces; 487 t.mDimYuv = mYuv; 488 t.mArrays = arrays; 489 490 t.calcElementCount(); 491 return t; 492 } 493 } 494 495 } 496