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 } 231 232 @Override updateFromNative()233 void updateFromNative() { 234 // We have 6 integer/long to obtain mDimX; mDimY; mDimZ; 235 // mDimLOD; mDimFaces; mElement; 236 long[] dataBuffer = new long[6]; 237 mRS.nTypeGetNativeData(getID(mRS), dataBuffer); 238 239 mDimX = (int)dataBuffer[0]; 240 mDimY = (int)dataBuffer[1]; 241 mDimZ = (int)dataBuffer[2]; 242 mDimMipmaps = dataBuffer[3] == 1 ? true : false; 243 mDimFaces = dataBuffer[4] == 1 ? true : false; 244 245 long elementID = dataBuffer[5]; 246 if(elementID != 0) { 247 mElement = new Element(elementID, mRS); 248 mElement.updateFromNative(); 249 } 250 calcElementCount(); 251 } 252 253 /** 254 * Utility function for creating basic 1D types. The type is 255 * created without mipmaps enabled. 256 * 257 * @param rs The RenderScript context 258 * @param e The Element for the Type 259 * @param dimX The X dimension, must be > 0 260 * 261 * @return Type 262 */ createX(RenderScript rs, Element e, int dimX)263 static public Type createX(RenderScript rs, Element e, int dimX) { 264 if (dimX < 1) { 265 throw new RSInvalidStateException("Dimension must be >= 1."); 266 } 267 268 long id = rs.nTypeCreate(e.getID(rs), dimX, 0, 0, false, false, 0); 269 Type t = new Type(id, rs); 270 t.mElement = e; 271 t.mDimX = dimX; 272 t.calcElementCount(); 273 return t; 274 } 275 276 /** 277 * Utility function for creating basic 2D types. The type is 278 * created without mipmaps or cubemaps. 279 * 280 * @param rs The RenderScript context 281 * @param e The Element for the Type 282 * @param dimX The X dimension, must be > 0 283 * @param dimY The Y dimension, must be > 0 284 * 285 * @return Type 286 */ createXY(RenderScript rs, Element e, int dimX, int dimY)287 static public Type createXY(RenderScript rs, Element e, int dimX, int dimY) { 288 if ((dimX < 1) || (dimY < 1)) { 289 throw new RSInvalidStateException("Dimension must be >= 1."); 290 } 291 292 long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, 0, false, false, 0); 293 Type t = new Type(id, rs); 294 t.mElement = e; 295 t.mDimX = dimX; 296 t.mDimY = dimY; 297 t.calcElementCount(); 298 return t; 299 } 300 301 /** 302 * Utility function for creating basic 3D types. The type is 303 * created without mipmaps. 304 * 305 * @param rs The RenderScript context 306 * @param e The Element for the Type 307 * @param dimX The X dimension, must be > 0 308 * @param dimY The Y dimension, must be > 0 309 * @param dimZ The Z dimension, must be > 0 310 * 311 * @return Type 312 */ createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ)313 static public Type createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ) { 314 if ((dimX < 1) || (dimY < 1) || (dimZ < 1)) { 315 throw new RSInvalidStateException("Dimension must be >= 1."); 316 } 317 318 long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, dimZ, false, false, 0); 319 Type t = new Type(id, rs); 320 t.mElement = e; 321 t.mDimX = dimX; 322 t.mDimY = dimY; 323 t.mDimZ = dimZ; 324 t.calcElementCount(); 325 return t; 326 } 327 328 /** 329 * Builder class for Type. 330 * 331 */ 332 public static class Builder { 333 RenderScript mRS; 334 int mDimX = 1; 335 int mDimY; 336 int mDimZ; 337 boolean mDimMipmaps; 338 boolean mDimFaces; 339 int mYuv; 340 int[] mArray = new int[mMaxArrays]; 341 342 Element mElement; 343 344 /** 345 * Create a new builder object. 346 * 347 * @param rs 348 * @param e The element for the type to be created. 349 */ Builder(RenderScript rs, Element e)350 public Builder(RenderScript rs, Element e) { 351 e.checkValid(); 352 mRS = rs; 353 mElement = e; 354 } 355 356 /** 357 * Add a dimension to the Type. 358 * 359 * 360 * @param value 361 */ setX(int value)362 public Builder setX(int value) { 363 if(value < 1) { 364 throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid."); 365 } 366 mDimX = value; 367 return this; 368 } 369 setY(int value)370 public Builder setY(int value) { 371 if(value < 1) { 372 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid."); 373 } 374 mDimY = value; 375 return this; 376 } 377 setZ(int value)378 public Builder setZ(int value) { 379 if(value < 1) { 380 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Z are not valid."); 381 } 382 mDimZ = value; 383 return this; 384 } 385 386 /** 387 * @hide 388 * Adds an array dimension to the builder 389 * 390 * @param dim 391 * @param value 392 * 393 * @return Builder 394 */ setArray(int dim, int value)395 public Builder setArray(int dim, int value) { 396 if(dim < 0 || dim >= mMaxArrays) { 397 throw new RSIllegalArgumentException("Array dimension out of range."); 398 } 399 mArray[dim] = value; 400 return this; 401 } 402 setMipmaps(boolean value)403 public Builder setMipmaps(boolean value) { 404 mDimMipmaps = value; 405 return this; 406 } 407 setFaces(boolean value)408 public Builder setFaces(boolean value) { 409 mDimFaces = value; 410 return this; 411 } 412 413 /** 414 * Set the YUV layout for a Type. 415 * 416 * @param yuvFormat {@link android.graphics.ImageFormat#YV12}, {@link android.graphics.ImageFormat#NV21}, or 417 * {@link android.graphics.ImageFormat#YUV_420_888}. 418 */ setYuvFormat(int yuvFormat)419 public Builder setYuvFormat(int yuvFormat) { 420 switch (yuvFormat) { 421 case android.graphics.ImageFormat.NV21: 422 case android.graphics.ImageFormat.YV12: 423 case android.graphics.ImageFormat.YUV_420_888: 424 break; 425 426 default: 427 throw new RSIllegalArgumentException( 428 "Only ImageFormat.NV21, .YV12, and .YUV_420_888 are supported.."); 429 } 430 431 mYuv = yuvFormat; 432 return this; 433 } 434 435 436 /** 437 * Validate structure and create a new Type. 438 * 439 * @return Type 440 */ create()441 public Type create() { 442 if (mDimZ > 0) { 443 if ((mDimX < 1) || (mDimY < 1)) { 444 throw new RSInvalidStateException("Both X and Y dimension required when Z is present."); 445 } 446 if (mDimFaces) { 447 throw new RSInvalidStateException("Cube maps not supported with 3D types."); 448 } 449 } 450 if (mDimY > 0) { 451 if (mDimX < 1) { 452 throw new RSInvalidStateException("X dimension required when Y is present."); 453 } 454 } 455 if (mDimFaces) { 456 if (mDimY < 1) { 457 throw new RSInvalidStateException("Cube maps require 2D Types."); 458 } 459 } 460 461 if (mYuv != 0) { 462 if ((mDimZ != 0) || mDimFaces || mDimMipmaps) { 463 throw new RSInvalidStateException("YUV only supports basic 2D."); 464 } 465 } 466 467 int[] arrays = null; 468 for (int ct = mMaxArrays - 1; ct >= 0; ct--) { 469 if (mArray[ct] != 0 && arrays == null) { 470 arrays = new int[ct]; 471 } 472 if ((mArray[ct] == 0) && (arrays != null)) { 473 throw new RSInvalidStateException("Array dimensions must be contigous from 0."); 474 } 475 } 476 477 long id = mRS.nTypeCreate(mElement.getID(mRS), 478 mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv); 479 Type t = new Type(id, mRS); 480 t.mElement = mElement; 481 t.mDimX = mDimX; 482 t.mDimY = mDimY; 483 t.mDimZ = mDimZ; 484 t.mDimMipmaps = mDimMipmaps; 485 t.mDimFaces = mDimFaces; 486 t.mDimYuv = mYuv; 487 t.mArrays = arrays; 488 489 t.calcElementCount(); 490 return t; 491 } 492 } 493 494 } 495