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.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