Home | History | Annotate | Download | only in renderscript
      1 /*
      2  * Copyright (C) 2008 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 import android.util.Log;
     22 
     23 /**
     24  * <p>Type is an allocation template. It consists of an Element and one or more
     25  * dimensions. It describes only the layout of memory but does not allocate any
     26  * storage for the data that is described.</p>
     27  *
     28  * <p>A Type consists of several dimensions. Those are X, Y, Z, LOD (level of
     29  * detail), Faces (faces of a cube map).  The X,Y,Z dimensions can be assigned
     30  * any positive integral value within the constraints of available memory.  A
     31  * single dimension allocation would have an X dimension of greater than zero
     32  * while the Y and Z dimensions would be zero to indicate not present.  In this
     33  * regard an allocation of x=10, y=1 would be considered 2 dimensionsal while
     34  * x=10, y=0 would be considered 1 dimensional.</p>
     35  *
     36  * <p>The LOD and Faces dimensions are booleans to indicate present or not present.</p>
     37  *
     38  * <div class="special reference">
     39  * <h3>Developer Guides</h3>
     40  * <p>For more information about creating an application that uses Renderscript, read the
     41  * <a href="{@docRoot}guide/topics/graphics/renderscript.html">Renderscript</a> developer guide.</p>
     42  * </div>
     43  **/
     44 public class Type extends BaseObj {
     45     int mDimX;
     46     int mDimY;
     47     int mDimZ;
     48     boolean mDimMipmaps;
     49     boolean mDimFaces;
     50     int mElementCount;
     51     Element mElement;
     52 
     53     public enum CubemapFace {
     54         POSITIVE_X (0),
     55         NEGATIVE_X (1),
     56         POSITIVE_Y (2),
     57         NEGATIVE_Y (3),
     58         POSITIVE_Z (4),
     59         NEGATIVE_Z (5),
     60         @Deprecated
     61         POSITVE_X (0),
     62         @Deprecated
     63         POSITVE_Y (2),
     64         @Deprecated
     65         POSITVE_Z (4);
     66 
     67         int mID;
     68         CubemapFace(int id) {
     69             mID = id;
     70         }
     71     }
     72 
     73     /**
     74      * Return the element associated with this Type.
     75      *
     76      * @return Element
     77      */
     78     public Element getElement() {
     79         return mElement;
     80     }
     81 
     82     /**
     83      * Return the value of the X dimension.
     84      *
     85      * @return int
     86      */
     87     public int getX() {
     88         return mDimX;
     89     }
     90 
     91     /**
     92      * Return the value of the Y dimension or 0 for a 1D allocation.
     93      *
     94      * @return int
     95      */
     96     public int getY() {
     97         return mDimY;
     98     }
     99 
    100     /**
    101      * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
    102      *
    103      * @return int
    104      */
    105     public int getZ() {
    106         return mDimZ;
    107     }
    108 
    109     /**
    110      * Return if the Type has a mipmap chain.
    111      *
    112      * @return boolean
    113      */
    114     public boolean hasMipmaps() {
    115         return mDimMipmaps;
    116     }
    117 
    118     /**
    119      * Return if the Type is a cube map.
    120      *
    121      * @return boolean
    122      */
    123     public boolean hasFaces() {
    124         return mDimFaces;
    125     }
    126 
    127     /**
    128      * Return the total number of accessable cells in the Type.
    129      *
    130      * @return int
    131      */
    132     public int getCount() {
    133         return mElementCount;
    134     }
    135 
    136     void calcElementCount() {
    137         boolean hasLod = hasMipmaps();
    138         int x = getX();
    139         int y = getY();
    140         int z = getZ();
    141         int faces = 1;
    142         if (hasFaces()) {
    143             faces = 6;
    144         }
    145         if (x == 0) {
    146             x = 1;
    147         }
    148         if (y == 0) {
    149             y = 1;
    150         }
    151         if (z == 0) {
    152             z = 1;
    153         }
    154 
    155         int count = x * y * z * faces;
    156 
    157         while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
    158             if(x > 1) {
    159                 x >>= 1;
    160             }
    161             if(y > 1) {
    162                 y >>= 1;
    163             }
    164             if(z > 1) {
    165                 z >>= 1;
    166             }
    167 
    168             count += x * y * z * faces;
    169         }
    170         mElementCount = count;
    171     }
    172 
    173 
    174     Type(int id, RenderScript rs) {
    175         super(id, rs);
    176     }
    177 
    178     @Override
    179     void updateFromNative() {
    180         // We have 6 integer to obtain mDimX; mDimY; mDimZ;
    181         // mDimLOD; mDimFaces; mElement;
    182         int[] dataBuffer = new int[6];
    183         mRS.nTypeGetNativeData(getID(), dataBuffer);
    184 
    185         mDimX = dataBuffer[0];
    186         mDimY = dataBuffer[1];
    187         mDimZ = dataBuffer[2];
    188         mDimMipmaps = dataBuffer[3] == 1 ? true : false;
    189         mDimFaces = dataBuffer[4] == 1 ? true : false;
    190 
    191         int elementID = dataBuffer[5];
    192         if(elementID != 0) {
    193             mElement = new Element(elementID, mRS);
    194             mElement.updateFromNative();
    195         }
    196         calcElementCount();
    197     }
    198 
    199     /**
    200      * Builder class for Type.
    201      *
    202      */
    203     public static class Builder {
    204         RenderScript mRS;
    205         int mDimX = 1;
    206         int mDimY;
    207         int mDimZ;
    208         boolean mDimMipmaps;
    209         boolean mDimFaces;
    210 
    211         Element mElement;
    212 
    213         /**
    214          * Create a new builder object.
    215          *
    216          * @param rs
    217          * @param e The element for the type to be created.
    218          */
    219         public Builder(RenderScript rs, Element e) {
    220             e.checkValid();
    221             mRS = rs;
    222             mElement = e;
    223         }
    224 
    225         /**
    226          * Add a dimension to the Type.
    227          *
    228          *
    229          * @param value
    230          */
    231         public Builder setX(int value) {
    232             if(value < 1) {
    233                 throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid.");
    234             }
    235             mDimX = value;
    236             return this;
    237         }
    238 
    239         public Builder setY(int value) {
    240             if(value < 1) {
    241                 throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid.");
    242             }
    243             mDimY = value;
    244             return this;
    245         }
    246 
    247         public Builder setMipmaps(boolean value) {
    248             mDimMipmaps = value;
    249             return this;
    250         }
    251 
    252         public Builder setFaces(boolean value) {
    253             mDimFaces = value;
    254             return this;
    255         }
    256 
    257 
    258         /**
    259          * Validate structure and create a new type.
    260          *
    261          * @return Type
    262          */
    263         public Type create() {
    264             if (mDimZ > 0) {
    265                 if ((mDimX < 1) || (mDimY < 1)) {
    266                     throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
    267                 }
    268                 if (mDimFaces) {
    269                     throw new RSInvalidStateException("Cube maps not supported with 3D types.");
    270                 }
    271             }
    272             if (mDimY > 0) {
    273                 if (mDimX < 1) {
    274                     throw new RSInvalidStateException("X dimension required when Y is present.");
    275                 }
    276             }
    277             if (mDimFaces) {
    278                 if (mDimY < 1) {
    279                     throw new RSInvalidStateException("Cube maps require 2D Types.");
    280                 }
    281             }
    282 
    283             int id = mRS.nTypeCreate(mElement.getID(), mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces);
    284             Type t = new Type(id, mRS);
    285             t.mElement = mElement;
    286             t.mDimX = mDimX;
    287             t.mDimY = mDimY;
    288             t.mDimZ = mDimZ;
    289             t.mDimMipmaps = mDimMipmaps;
    290             t.mDimFaces = mDimFaces;
    291 
    292             t.calcElementCount();
    293             return t;
    294         }
    295     }
    296 
    297 }
    298