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 import java.io.File;
     20 import java.io.IOException;
     21 import java.io.InputStream;
     22 
     23 import android.content.res.AssetManager;
     24 import android.content.res.Resources;
     25 import android.graphics.Bitmap;
     26 import android.graphics.BitmapFactory;
     27 import android.util.Log;
     28 import android.util.TypedValue;
     29 
     30 /**
     31  * FileA3D allows users to load Renderscript objects from files
     32  * or resources stored on disk. It could be used to load items
     33  * such as 3D geometry data converted to a Renderscript format from
     34  * content creation tools. Currently only meshes are supported
     35  * in FileA3D.
     36  *
     37  * When successfully loaded, FileA3D will contain a list of
     38  * index entries for all the objects stored inside it.
     39  *
     40  **/
     41 public class FileA3D extends BaseObj {
     42 
     43     /**
     44     * Specifies what renderscript object type is contained within
     45     * the FileA3D IndexEntry
     46     **/
     47     public enum EntryType {
     48 
     49         /**
     50         * Unknown or or invalid object, nothing will be loaded
     51         **/
     52         UNKNOWN (0),
     53         /**
     54         * Renderscript Mesh object
     55         **/
     56         MESH (1);
     57 
     58         int mID;
     59         EntryType(int id) {
     60             mID = id;
     61         }
     62 
     63         static EntryType toEntryType(int intID) {
     64             return EntryType.values()[intID];
     65         }
     66     }
     67 
     68     /**
     69     * IndexEntry contains information about one of the Renderscript
     70     * objects inside the file's index. It could be used to query the
     71     * object's type and also name and load the object itself if
     72     * necessary.
     73     */
     74     public static class IndexEntry {
     75         RenderScript mRS;
     76         int mIndex;
     77         int mID;
     78         String mName;
     79         EntryType mEntryType;
     80         BaseObj mLoadedObj;
     81 
     82         /**
     83         * Returns the name of a renderscript object the index entry
     84         * describes
     85         *
     86         * @return name of a renderscript object the index entry
     87         * describes
     88         *
     89         */
     90         public String getName() {
     91             return mName;
     92         }
     93 
     94         /**
     95         * Returns the type of a renderscript object the index entry
     96         * describes
     97         * @return type of a renderscript object the index entry
     98         *         describes
     99         */
    100         public EntryType getEntryType() {
    101             return mEntryType;
    102         }
    103 
    104         /**
    105         * Used to load the object described by the index entry
    106         * @return base renderscript object described by the entry
    107         */
    108         public BaseObj getObject() {
    109             mRS.validate();
    110             BaseObj obj = internalCreate(mRS, this);
    111             return obj;
    112         }
    113 
    114         /**
    115         * Used to load the mesh described by the index entry, object
    116         * described by the index entry must be a renderscript mesh
    117         *
    118         * @return renderscript mesh object described by the entry
    119         */
    120         public Mesh getMesh() {
    121             return (Mesh)getObject();
    122         }
    123 
    124         static synchronized BaseObj internalCreate(RenderScript rs, IndexEntry entry) {
    125             if(entry.mLoadedObj != null) {
    126                 return entry.mLoadedObj;
    127             }
    128 
    129             // to be purged on cleanup
    130             if(entry.mEntryType == EntryType.UNKNOWN) {
    131                 return null;
    132             }
    133 
    134             int objectID = rs.nFileA3DGetEntryByIndex(entry.mID, entry.mIndex);
    135             if(objectID == 0) {
    136                 return null;
    137             }
    138 
    139             switch (entry.mEntryType) {
    140             case MESH:
    141                 entry.mLoadedObj = new Mesh(objectID, rs);
    142                 break;
    143             }
    144 
    145             entry.mLoadedObj.updateFromNative();
    146             return entry.mLoadedObj;
    147         }
    148 
    149         IndexEntry(RenderScript rs, int index, int id, String name, EntryType type) {
    150             mRS = rs;
    151             mIndex = index;
    152             mID = id;
    153             mName = name;
    154             mEntryType = type;
    155             mLoadedObj = null;
    156         }
    157     }
    158 
    159     IndexEntry[] mFileEntries;
    160     InputStream mInputStream;
    161 
    162     FileA3D(int id, RenderScript rs, InputStream stream) {
    163         super(id, rs);
    164         mInputStream = stream;
    165     }
    166 
    167     private void initEntries() {
    168         int numFileEntries = mRS.nFileA3DGetNumIndexEntries(getID());
    169         if(numFileEntries <= 0) {
    170             return;
    171         }
    172 
    173         mFileEntries = new IndexEntry[numFileEntries];
    174         int[] ids = new int[numFileEntries];
    175         String[] names = new String[numFileEntries];
    176 
    177         mRS.nFileA3DGetIndexEntries(getID(), numFileEntries, ids, names);
    178 
    179         for(int i = 0; i < numFileEntries; i ++) {
    180             mFileEntries[i] = new IndexEntry(mRS, i, getID(), names[i], EntryType.toEntryType(ids[i]));
    181         }
    182     }
    183 
    184     /**
    185     * Returns the number of objects stored inside the a3d file
    186     *
    187     * @return the number of objects stored inside the a3d file
    188     */
    189     public int getIndexEntryCount() {
    190         if(mFileEntries == null) {
    191             return 0;
    192         }
    193         return mFileEntries.length;
    194     }
    195 
    196     /**
    197     * Returns an index entry from the list of all objects inside
    198     * FileA3D
    199     *
    200     * @param index number of the entry from the list to return
    201     *
    202     * @return entry in the a3d file described by the index
    203     */
    204     public IndexEntry getIndexEntry(int index) {
    205         if(getIndexEntryCount() == 0 || index < 0 || index >= mFileEntries.length) {
    206             return null;
    207         }
    208         return mFileEntries[index];
    209     }
    210 
    211     /**
    212     * Creates a FileA3D object from an asset stored on disk
    213     *
    214     * @param rs Context to which the object will belong.
    215     * @param mgr asset manager used to load asset
    216     * @param path location of the file to load
    217     *
    218     * @return a3d file containing renderscript objects
    219     */
    220     static public FileA3D createFromAsset(RenderScript rs, AssetManager mgr, String path) {
    221         rs.validate();
    222         int fileId = rs.nFileA3DCreateFromAsset(mgr, path);
    223 
    224         if(fileId == 0) {
    225             throw new RSRuntimeException("Unable to create a3d file from asset " + path);
    226         }
    227         FileA3D fa3d = new FileA3D(fileId, rs, null);
    228         fa3d.initEntries();
    229         return fa3d;
    230     }
    231 
    232     /**
    233     * Creates a FileA3D object from a file stored on disk
    234     *
    235     * @param rs Context to which the object will belong.
    236     * @param path location of the file to load
    237     *
    238     * @return a3d file containing renderscript objects
    239     */
    240     static public FileA3D createFromFile(RenderScript rs, String path) {
    241         int fileId = rs.nFileA3DCreateFromFile(path);
    242 
    243         if(fileId == 0) {
    244             throw new RSRuntimeException("Unable to create a3d file from " + path);
    245         }
    246         FileA3D fa3d = new FileA3D(fileId, rs, null);
    247         fa3d.initEntries();
    248         return fa3d;
    249     }
    250 
    251     /**
    252     * Creates a FileA3D object from a file stored on disk
    253     *
    254     * @param rs Context to which the object will belong.
    255     * @param path location of the file to load
    256     *
    257     * @return a3d file containing renderscript objects
    258     */
    259     static public FileA3D createFromFile(RenderScript rs, File path) {
    260         return createFromFile(rs, path.getAbsolutePath());
    261     }
    262 
    263     /**
    264     * Creates a FileA3D object from an application resource
    265     *
    266     * @param rs Context to which the object will belong.
    267     * @param res resource manager used for loading
    268     * @param id resource to create FileA3D from
    269     *
    270     * @return a3d file containing renderscript objects
    271     */
    272     static public FileA3D createFromResource(RenderScript rs, Resources res, int id) {
    273 
    274         rs.validate();
    275         InputStream is = null;
    276         try {
    277             is = res.openRawResource(id);
    278         } catch (Exception e) {
    279             throw new RSRuntimeException("Unable to open resource " + id);
    280         }
    281 
    282         int fileId = 0;
    283         if (is instanceof AssetManager.AssetInputStream) {
    284             int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
    285             fileId = rs.nFileA3DCreateFromAssetStream(asset);
    286         } else {
    287             throw new RSRuntimeException("Unsupported asset stream");
    288         }
    289 
    290         if(fileId == 0) {
    291             throw new RSRuntimeException("Unable to create a3d file from resource " + id);
    292         }
    293         FileA3D fa3d = new FileA3D(fileId, rs, is);
    294         fa3d.initEntries();
    295         return fa3d;
    296 
    297     }
    298 }
    299