blob: 79ee99758e45614f64c4d89fa9d6061e6d253276 [file] [log] [blame]
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -07001/*
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
17package android.renderscript;
18
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -080019import java.io.File;
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -070020import java.io.IOException;
21import java.io.InputStream;
22
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -070023import android.content.res.AssetManager;
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -080024import android.content.res.Resources;
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -070025import android.graphics.Bitmap;
26import android.graphics.BitmapFactory;
27import android.util.Log;
28import android.util.TypedValue;
29
30/**
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -080031 * 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 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.
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -070039 *
40 **/
41public class FileA3D extends BaseObj {
42
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -080043 /**
44 * Specifies what renderscript object type is contained within
45 * the FileA3D IndexEntry
46 **/
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -080047 public enum EntryType {
48
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080049 /**
50 * Unknown or or invalid object, nothing will be loaded
51 **/
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -080052 UNKNOWN (0),
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080053 /**
54 * Renderscript Mesh object
55 **/
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -080056 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
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -080068 /**
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 name and load the object itself if
72 * necessary.
73 */
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -070074 public static class IndexEntry {
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -070075 RenderScript mRS;
76 int mIndex;
77 int mID;
78 String mName;
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -080079 EntryType mEntryType;
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -070080 BaseObj mLoadedObj;
81
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -080082 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080083 * Returns the name of a renderscript object the index entry
84 * describes
85 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -080086 * @return name of a renderscript object the index entry
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080087 * describes
88 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -080089 */
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -070090 public String getName() {
91 return mName;
92 }
93
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -080094 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080095 * Returns the type of a renderscript object the index entry
96 * describes
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -080097 * @return type of a renderscript object the index entry
98 * describes
99 */
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800100 public EntryType getEntryType() {
101 return mEntryType;
102 }
103
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800104 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800105 * Used to load the object described by the index entry
106 * @return base renderscript object described by the entry
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800107 */
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700108 public BaseObj getObject() {
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700109 mRS.validate();
110 BaseObj obj = internalCreate(mRS, this);
111 return obj;
112 }
113
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800114 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800115 * Used to load the mesh described by the index entry, object
116 * described by the index entry must be a renderscript mesh
117 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800118 * @return renderscript mesh object described by the entry
119 */
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800120 public Mesh getMesh() {
121 return (Mesh)getObject();
122 }
123
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700124 static synchronized BaseObj internalCreate(RenderScript rs, IndexEntry entry) {
125 if(entry.mLoadedObj != null) {
126 return entry.mLoadedObj;
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700127 }
128
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800129 // to be purged on cleanup
130 if(entry.mEntryType == EntryType.UNKNOWN) {
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700131 return null;
132 }
133
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700134 int objectID = rs.nFileA3DGetEntryByIndex(entry.mID, entry.mIndex);
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700135 if(objectID == 0) {
136 return null;
137 }
138
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800139 switch (entry.mEntryType) {
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700140 case MESH:
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700141 entry.mLoadedObj = new Mesh(objectID, rs);
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700142 break;
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700143 }
144
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700145 entry.mLoadedObj.updateFromNative();
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700146 return entry.mLoadedObj;
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700147 }
148
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800149 IndexEntry(RenderScript rs, int index, int id, String name, EntryType type) {
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700150 mRS = rs;
151 mIndex = index;
152 mID = id;
153 mName = name;
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800154 mEntryType = type;
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700155 mLoadedObj = null;
156 }
157 }
158
159 IndexEntry[] mFileEntries;
Alex Sakhartchouk581cc642010-10-27 14:10:07 -0700160 InputStream mInputStream;
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700161
Alex Sakhartchouk581cc642010-10-27 14:10:07 -0700162 FileA3D(int id, RenderScript rs, InputStream stream) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700163 super(id, rs);
Alex Sakhartchouk581cc642010-10-27 14:10:07 -0700164 mInputStream = stream;
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700165 }
166
167 private void initEntries() {
Jason Sams06d69de2010-11-09 17:11:40 -0800168 int numFileEntries = mRS.nFileA3DGetNumIndexEntries(getID());
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700169 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
Jason Sams06d69de2010-11-09 17:11:40 -0800177 mRS.nFileA3DGetIndexEntries(getID(), numFileEntries, ids, names);
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700178
179 for(int i = 0; i < numFileEntries; i ++) {
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800180 mFileEntries[i] = new IndexEntry(mRS, i, getID(), names[i], EntryType.toEntryType(ids[i]));
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700181 }
182 }
183
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800184 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800185 * Returns the number of objects stored inside the a3d file
186 *
187 * @return the number of objects stored inside the a3d file
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800188 */
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800189 public int getIndexEntryCount() {
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700190 if(mFileEntries == null) {
191 return 0;
192 }
193 return mFileEntries.length;
194 }
195
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800196 /**
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
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800201 *
202 * @return entry in the a3d file described by the index
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800203 */
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700204 public IndexEntry getIndexEntry(int index) {
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800205 if(getIndexEntryCount() == 0 || index < 0 || index >= mFileEntries.length) {
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700206 return null;
207 }
208 return mFileEntries[index];
209 }
210
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800211 /**
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 *
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800218 * @return a3d file containing renderscript objects
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800219 */
Alex Sakhartchoukb0253ea2011-01-07 11:12:08 -0800220 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;
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800230 }
231
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800232 /**
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 *
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800238 * @return a3d file containing renderscript objects
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800239 */
Alex Sakhartchoukb0253ea2011-01-07 11:12:08 -0800240 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;
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800249 }
250
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800251 /**
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 *
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800257 * @return a3d file containing renderscript objects
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800258 */
Alex Sakhartchoukb0253ea2011-01-07 11:12:08 -0800259 static public FileA3D createFromFile(RenderScript rs, File path) {
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800260 return createFromFile(rs, path.getAbsolutePath());
261 }
262
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800263 /**
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 *
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800270 * @return a3d file containing renderscript objects
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800271 */
Alex Sakhartchoukb0253ea2011-01-07 11:12:08 -0800272 static public FileA3D createFromResource(RenderScript rs, Resources res, int id) {
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700273
274 rs.validate();
275 InputStream is = null;
276 try {
Alex Sakhartchoukb0253ea2011-01-07 11:12:08 -0800277 is = res.openRawResource(id);
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700278 } catch (Exception e) {
Alex Sakhartchoukb0253ea2011-01-07 11:12:08 -0800279 throw new RSRuntimeException("Unable to open resource " + id);
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700280 }
281
Alex Sakhartchoukb0253ea2011-01-07 11:12:08 -0800282 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
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700297 }
298}