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