blob: b88f7b0e04d194be048f7a66449d7a500591ebf0 [file] [log] [blame]
Jason Samsa5597fc2009-07-08 18:01:53 -07001
2/*
3 * Copyright (C) 2009 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070018#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Samsa5597fc2009-07-08 18:01:53 -070019#include "rsContext.h"
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070020#else
21#include "rsContextHostStub.h"
22#endif
Jason Samsa5597fc2009-07-08 18:01:53 -070023
Jason Samsa5597fc2009-07-08 18:01:53 -070024#include "rsFileA3D.h"
25
26#include "rsMesh.h"
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070027#include "rsAnimation.h"
Jason Samsa5597fc2009-07-08 18:01:53 -070028
29using namespace android;
30using namespace android::renderscript;
31
32
33
34FileA3D::FileA3D()
35{
36 mRsc = NULL;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070037 mAlloc = NULL;
38 mData = NULL;
39 mWriteStream = NULL;
40 mReadStream = NULL;
41
42 mMajorVersion = 0;
43 mMinorVersion = 1;
44 mDataSize = 0;
Jason Samsa5597fc2009-07-08 18:01:53 -070045}
46
47FileA3D::~FileA3D()
48{
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070049 for(size_t i = 0; i < mIndex.size(); i ++) {
50 delete mIndex[i];
51 }
52 for(size_t i = 0; i < mWriteIndex.size(); i ++) {
53 delete mWriteIndex[i];
54 }
55 if(mWriteStream) {
56 delete mWriteStream;
57 }
58 if(mReadStream) {
59 delete mWriteStream;
60 }
61 if(mAlloc) {
62 free(mAlloc);
63 }
Jason Samsa5597fc2009-07-08 18:01:53 -070064}
65
66bool FileA3D::load(Context *rsc, FILE *f)
67{
68 char magicString[12];
69 size_t len;
70
71 LOGE("file open 1");
72 len = fread(magicString, 1, 12, f);
73 if ((len != 12) ||
74 memcmp(magicString, "Android3D_ff", 12)) {
75 return false;
76 }
77
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070078 // Next thing is the size of the header
79 uint64_t headerSize = 0;
80 len = fread(&headerSize, 1, sizeof(headerSize), f);
81 if (len != sizeof(headerSize) || headerSize == 0) {
Jason Samsa5597fc2009-07-08 18:01:53 -070082 return false;
83 }
84
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070085 uint8_t *headerData = (uint8_t *)malloc(headerSize);
86 if(!headerData) {
Jason Samsa5597fc2009-07-08 18:01:53 -070087 return false;
88 }
89
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070090 len = fread(headerData, 1, headerSize, f);
91 if (len != headerSize) {
Jason Samsa5597fc2009-07-08 18:01:53 -070092 return false;
93 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070094
95 // Now open the stream to parse the header
96 IStream headerStream(headerData, false);
97
98 mMajorVersion = headerStream.loadU32();
99 mMinorVersion = headerStream.loadU32();
100 uint32_t flags = headerStream.loadU32();
Jason Samsa5597fc2009-07-08 18:01:53 -0700101 mUse64BitOffsets = (flags & 1) != 0;
102
103 LOGE("file open 64bit = %i", mUse64BitOffsets);
104
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700105 uint32_t numIndexEntries = headerStream.loadU32();
106 for(uint32_t i = 0; i < numIndexEntries; i ++) {
107 A3DIndexEntry *entry = new A3DIndexEntry();
108 headerStream.loadString(&entry->mID);
109 entry->mType = (A3DClassID)headerStream.loadU32();
110 if(mUse64BitOffsets){
111 entry->mOffset = headerStream.loadOffset();
Jason Samsa5597fc2009-07-08 18:01:53 -0700112 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700113 else {
114 entry->mOffset = headerStream.loadU32();
Jason Samsa5597fc2009-07-08 18:01:53 -0700115 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700116 entry->mRsObj = NULL;
117 mIndex.push(entry);
118 }
119
120 // Next thing is the size of the header
121 len = fread(&mDataSize, 1, sizeof(mDataSize), f);
122 if (len != sizeof(mDataSize) || mDataSize == 0) {
123 return false;
Jason Samsa5597fc2009-07-08 18:01:53 -0700124 }
125
126 LOGE("file open size = %lli", mDataSize);
127
128 // We should know enough to read the file in at this point.
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700129 mAlloc = malloc(mDataSize);
Jason Samsa5597fc2009-07-08 18:01:53 -0700130 if (!mAlloc) {
131 return false;
132 }
133 mData = (uint8_t *)mAlloc;
134 len = fread(mAlloc, 1, mDataSize, f);
135 if (len != mDataSize) {
136 return false;
137 }
138
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700139 mReadStream = new IStream(mData, mUse64BitOffsets);
140
141 mRsc = rsc;
142
143 LOGE("Header is read an stream initialized");
144 return true;
Jason Samsa5597fc2009-07-08 18:01:53 -0700145}
146
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700147size_t FileA3D::getNumLoadedEntries() const {
148 return mIndex.size();
149}
Jason Samsa5597fc2009-07-08 18:01:53 -0700150
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700151const FileA3D::A3DIndexEntry *FileA3D::getLoadedEntry(size_t index) const {
152 if(index < mIndex.size()) {
153 return mIndex[index];
Jason Samsa5597fc2009-07-08 18:01:53 -0700154 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700155 return NULL;
Jason Samsa5597fc2009-07-08 18:01:53 -0700156}
157
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700158ObjectBase *FileA3D::initializeFromEntry(const FileA3D::A3DIndexEntry *entry) {
159 if(!entry) {
160 return NULL;
161 }
162
163 // Seek to the beginning of object
164 mReadStream->reset(entry->mOffset);
165 switch (entry->mType) {
166 case A3D_CLASS_ID_UNKNOWN:
167 return NULL;
168 case A3D_CLASS_ID_MESH:
169 return Mesh::createFromStream(mRsc, mReadStream);
170 case A3D_CLASS_ID_SIMPLE_MESH:
171 return SimpleMesh::createFromStream(mRsc, mReadStream);
172 case A3D_CLASS_ID_TYPE:
173 return Type::createFromStream(mRsc, mReadStream);
174 case A3D_CLASS_ID_ELEMENT:
175 return Element::createFromStream(mRsc, mReadStream);
176 case A3D_CLASS_ID_ALLOCATION:
177 return Allocation::createFromStream(mRsc, mReadStream);
178 case A3D_CLASS_ID_PROGRAM_VERTEX:
179 return ProgramVertex::createFromStream(mRsc, mReadStream);
180 case A3D_CLASS_ID_PROGRAM_RASTER:
181 return ProgramRaster::createFromStream(mRsc, mReadStream);
182 case A3D_CLASS_ID_PROGRAM_FRAGMENT:
183 return ProgramFragment::createFromStream(mRsc, mReadStream);
184 case A3D_CLASS_ID_PROGRAM_STORE:
185 return ProgramStore::createFromStream(mRsc, mReadStream);
186 case A3D_CLASS_ID_SAMPLER:
187 return Sampler::createFromStream(mRsc, mReadStream);
188 case A3D_CLASS_ID_ANIMATION:
189 return Animation::createFromStream(mRsc, mReadStream);
190 case A3D_CLASS_ID_LIGHT:
191 return Light::createFromStream(mRsc, mReadStream);
192 case A3D_CLASS_ID_ADAPTER_1D:
193 return Adapter1D::createFromStream(mRsc, mReadStream);
194 case A3D_CLASS_ID_ADAPTER_2D:
195 return Adapter2D::createFromStream(mRsc, mReadStream);
196 case A3D_CLASS_ID_SCRIPT_C:
197 return NULL;
198 }
199 return NULL;
200}
201
202bool FileA3D::writeFile(const char *filename)
Jason Samsa5597fc2009-07-08 18:01:53 -0700203{
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700204 if(!mWriteStream) {
205 LOGE("No objects to write\n");
206 return false;
207 }
208 if(mWriteStream->getPos() == 0) {
209 LOGE("No objects to write\n");
210 return false;
211 }
Jason Samsa5597fc2009-07-08 18:01:53 -0700212
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700213 FILE *writeHandle = fopen(filename, "wb");
214 if(!writeHandle) {
215 LOGE("Couldn't open the file for writing\n");
216 return false;
217 }
Jason Samsa5597fc2009-07-08 18:01:53 -0700218
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700219 // Open a new stream to make writing the header easier
220 OStream headerStream(5*1024, false);
221 headerStream.addU32(mMajorVersion);
222 headerStream.addU32(mMinorVersion);
223 uint32_t is64Bit = 0;
224 headerStream.addU32(is64Bit);
Jason Samsa5597fc2009-07-08 18:01:53 -0700225
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700226 uint32_t writeIndexSize = mWriteIndex.size();
227 headerStream.addU32(writeIndexSize);
228 for(uint32_t i = 0; i < writeIndexSize; i ++) {
229 headerStream.addString(&mWriteIndex[i]->mID);
230 headerStream.addU32((uint32_t)mWriteIndex[i]->mType);
231 if(mUse64BitOffsets){
232 headerStream.addOffset(mWriteIndex[i]->mOffset);
233 }
234 else {
235 uint32_t offset = (uint32_t)mWriteIndex[i]->mOffset;
236 headerStream.addU32(offset);
Jason Samsa5597fc2009-07-08 18:01:53 -0700237 }
238 }
239
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700240 // Write our magic string so we know we are reading the right file
241 String8 magicString(A3D_MAGIC_KEY);
242 fwrite(magicString.string(), sizeof(char), magicString.size(), writeHandle);
Jason Samsa5597fc2009-07-08 18:01:53 -0700243
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700244 // Store the size of the header to make it easier to parse when we read it
245 uint64_t headerSize = headerStream.getPos();
246 fwrite(&headerSize, sizeof(headerSize), 1, writeHandle);
Jason Samsa5597fc2009-07-08 18:01:53 -0700247
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700248 // Now write our header
249 fwrite(headerStream.getPtr(), sizeof(uint8_t), headerStream.getPos(), writeHandle);
Jason Samsa5597fc2009-07-08 18:01:53 -0700250
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700251 // Now write the size of the data part of the file for easier parsing later
252 uint64_t fileDataSize = mWriteStream->getPos();
253 fwrite(&fileDataSize, sizeof(fileDataSize), 1, writeHandle);
254
255 fwrite(mWriteStream->getPtr(), sizeof(uint8_t), mWriteStream->getPos(), writeHandle);
256
257 int status = fclose(writeHandle);
258
259 if(status != 0) {
260 LOGE("Couldn't close file\n");
261 return false;
Jason Samsa5597fc2009-07-08 18:01:53 -0700262 }
263
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700264 return true;
Jason Samsa5597fc2009-07-08 18:01:53 -0700265}
266
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700267void FileA3D::appendToFile(ObjectBase *obj) {
268 if(!obj) {
269 return;
Jason Samsa5597fc2009-07-08 18:01:53 -0700270 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700271 if(!mWriteStream) {
272 const uint64_t initialStreamSize = 256*1024;
273 mWriteStream = new OStream(initialStreamSize, false);
Jason Samsa5597fc2009-07-08 18:01:53 -0700274 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700275 A3DIndexEntry *indexEntry = new A3DIndexEntry();
276 indexEntry->mID.setTo(obj->getName());
277 indexEntry->mType = obj->getClassId();
278 indexEntry->mOffset = mWriteStream->getPos();
279 indexEntry->mRsObj = (void*)obj;
280 mWriteIndex.push(indexEntry);
281 obj->serialize(mWriteStream);
Jason Samsa5597fc2009-07-08 18:01:53 -0700282}
283
284namespace android {
285namespace renderscript {
286
287
288RsFile rsi_FileOpen(Context *rsc, char const *path, unsigned int len)
289{
290 FileA3D *fa3d = new FileA3D;
291
292 FILE *f = fopen("/sdcard/test.a3d", "rb");
293 if (f) {
294 fa3d->load(rsc, f);
295 fclose(f);
296 return fa3d;
297 }
298 delete fa3d;
299 return NULL;
300}
301
302
303}
304}