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