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