Home | History | Annotate | Download | only in renderscript
      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