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