blob: 86d294bf3160746279e805b9acdeac457069ffe5 [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
18#include "rsContext.h"
19
20
21#include <utils/String8.h>
22#include "rsFileA3D.h"
23
24#include "rsMesh.h"
25
26using namespace android;
27using namespace android::renderscript;
28
29
30
31FileA3D::FileA3D()
32{
33 mRsc = NULL;
34}
35
36FileA3D::~FileA3D()
37{
38}
39
40bool FileA3D::load(Context *rsc, FILE *f)
41{
42 char magicString[12];
43 size_t len;
44
45 LOGE("file open 1");
46 len = fread(magicString, 1, 12, f);
47 if ((len != 12) ||
48 memcmp(magicString, "Android3D_ff", 12)) {
49 return false;
50 }
51
52 LOGE("file open 2");
53 len = fread(&mMajorVersion, 1, sizeof(mMajorVersion), f);
54 if (len != sizeof(mMajorVersion)) {
55 return false;
56 }
57
58 LOGE("file open 3");
59 len = fread(&mMinorVersion, 1, sizeof(mMinorVersion), f);
60 if (len != sizeof(mMinorVersion)) {
61 return false;
62 }
63
64 LOGE("file open 4");
65 uint32_t flags;
66 len = fread(&flags, 1, sizeof(flags), f);
67 if (len != sizeof(flags)) {
68 return false;
69 }
70 mUse64BitOffsets = (flags & 1) != 0;
71
72 LOGE("file open 64bit = %i", mUse64BitOffsets);
73
74 if (mUse64BitOffsets) {
75 len = fread(&mDataSize, 1, sizeof(mDataSize), f);
76 if (len != sizeof(mDataSize)) {
77 return false;
78 }
79 } else {
80 uint32_t tmp;
81 len = fread(&tmp, 1, sizeof(tmp), f);
82 if (len != sizeof(tmp)) {
83 return false;
84 }
85 mDataSize = tmp;
86 }
87
88 LOGE("file open size = %lli", mDataSize);
89
90 // We should know enough to read the file in at this point.
91 fseek(f, SEEK_SET, 0);
92 mAlloc= malloc(mDataSize);
93 if (!mAlloc) {
94 return false;
95 }
96 mData = (uint8_t *)mAlloc;
97 len = fread(mAlloc, 1, mDataSize, f);
98 if (len != mDataSize) {
99 return false;
100 }
101
102 LOGE("file start processing");
103 return process(rsc);
104}
105
106bool FileA3D::processIndex(Context *rsc, A3DIndexEntry *ie)
107{
108 bool ret = false;
109 IO io(mData + ie->mOffset, mUse64BitOffsets);
110
111 LOGE("process index, type %i", ie->mType);
112
113 switch(ie->mType) {
114 case CHUNK_ELEMENT:
115 processChunk_Element(rsc, &io, ie);
116 break;
117 case CHUNK_ELEMENT_SOURCE:
118 processChunk_ElementSource(rsc, &io, ie);
119 break;
120 case CHUNK_VERTICIES:
121 processChunk_Verticies(rsc, &io, ie);
122 break;
123 case CHUNK_MESH:
124 processChunk_Mesh(rsc, &io, ie);
125 break;
126 case CHUNK_PRIMITIVE:
127 processChunk_Primitive(rsc, &io, ie);
128 break;
129 default:
130 LOGE("FileA3D Unknown chunk type");
131 break;
132 }
133 return (ie->mRsObj != NULL);
134}
135
136bool FileA3D::process(Context *rsc)
137{
138 LOGE("process");
139 IO io(mData + 12, mUse64BitOffsets);
140 bool ret = true;
141
142 // Build the index first
143 LOGE("process 1");
144 io.loadU32(); // major version, already loaded
145 io.loadU32(); // minor version, already loaded
146 LOGE("process 2");
147
148 io.loadU32(); // flags
149 io.loadOffset(); // filesize, already loaded.
150 LOGE("process 4");
151 uint64_t mIndexOffset = io.loadOffset();
152 uint64_t mStringOffset = io.loadOffset();
153
154 LOGE("process mIndexOffset= 0x%016llx", mIndexOffset);
155 LOGE("process mStringOffset= 0x%016llx", mStringOffset);
156
157 IO index(mData + mIndexOffset, mUse64BitOffsets);
158 IO stringTable(mData + mStringOffset, mUse64BitOffsets);
159
160 uint32_t stringEntryCount = stringTable.loadU32();
161 LOGE("stringEntryCount %i", stringEntryCount);
162 mStrings.setCapacity(stringEntryCount);
163 mStringIndexValues.setCapacity(stringEntryCount);
164 if (stringEntryCount) {
165 uint32_t stringType = stringTable.loadU32();
166 LOGE("stringType %i", stringType);
167 rsAssert(stringType==0);
168 for (uint32_t ct = 0; ct < stringEntryCount; ct++) {
169 uint64_t offset = stringTable.loadOffset();
170 LOGE("string offset 0x%016llx", offset);
171 IO tmp(mData + offset, mUse64BitOffsets);
172 String8 s;
173 tmp.loadString(&s);
174 LOGE("string %s", s.string());
175 mStrings.push(s);
176 }
177 }
178
179 LOGE("strings done");
180 uint32_t indexEntryCount = index.loadU32();
181 LOGE("index count %i", indexEntryCount);
182 mIndex.setCapacity(indexEntryCount);
183 for (uint32_t ct = 0; ct < indexEntryCount; ct++) {
184 A3DIndexEntry e;
185 uint32_t stringIndex = index.loadU32();
186 LOGE("index %i", ct);
187 LOGE(" string index %i", stringIndex);
188 e.mType = (A3DChunkType)index.loadU32();
189 LOGE(" type %i", e.mType);
190 e.mOffset = index.loadOffset();
191 LOGE(" offset 0x%016llx", e.mOffset);
192
193 if (stringIndex && (stringIndex < mStrings.size())) {
194 e.mID = mStrings[stringIndex];
195 mStringIndexValues.editItemAt(stringIndex) = ct;
196 LOGE(" id %s", e.mID.string());
197 }
198
199 mIndex.push(e);
200 }
201 LOGE("index done");
202
203 // At this point the index should be fully populated.
204 // We can now walk though it and load all the objects.
205 for (uint32_t ct = 0; ct < indexEntryCount; ct++) {
206 LOGE("processing index entry %i", ct);
207 processIndex(rsc, &mIndex.editItemAt(ct));
208 }
209
210 return ret;
211}
212
213
214FileA3D::IO::IO(const uint8_t *buf, bool use64)
215{
216 mData = buf;
217 mPos = 0;
218 mUse64 = use64;
219}
220
221uint64_t FileA3D::IO::loadOffset()
222{
223 uint64_t tmp;
224 if (mUse64) {
225 mPos = (mPos + 7) & (~7);
226 tmp = reinterpret_cast<const uint64_t *>(&mData[mPos])[0];
227 mPos += sizeof(uint64_t);
228 return tmp;
229 }
230 return loadU32();
231}
232
233void FileA3D::IO::loadString(String8 *s)
234{
235 LOGE("loadString");
236 uint32_t len = loadU32();
237 LOGE("loadString len %i", len);
238 s->setTo((const char *)&mData[mPos], len);
239 mPos += len;
240}
241
242
243void FileA3D::processChunk_Mesh(Context *rsc, IO *io, A3DIndexEntry *ie)
244{
245 Mesh * m = new Mesh;
246
247 m->mPrimitivesCount = io->loadU32();
248 m->mPrimitives = new Mesh::Primitive_t *[m->mPrimitivesCount];
249
250 for (uint32_t ct = 0; ct < m->mPrimitivesCount; ct++) {
251 uint32_t index = io->loadU32();
252
253 m->mPrimitives[ct] = (Mesh::Primitive_t *)mIndex[index].mRsObj;
254 }
255 ie->mRsObj = m;
256}
257
258void FileA3D::processChunk_Primitive(Context *rsc, IO *io, A3DIndexEntry *ie)
259{
260 Mesh::Primitive_t * p = new Mesh::Primitive_t;
261
262 p->mIndexCount = io->loadU32();
263 uint32_t vertIdx = io->loadU32();
Jason Samsb80dfa72009-07-10 17:32:40 -0700264 p->mRestartCounts = io->loadU16();
Jason Samsa5597fc2009-07-08 18:01:53 -0700265 uint32_t bits = io->loadU8();
266 p->mType = (RsPrimitive)io->loadU8();
267
Jason Samsb80dfa72009-07-10 17:32:40 -0700268 LOGE("processChunk_Primitive count %i, bits %i", p->mIndexCount, bits);
269
Jason Samsa5597fc2009-07-08 18:01:53 -0700270 p->mVerticies = (Mesh::Verticies_t *)mIndex[vertIdx].mRsObj;
271
272 p->mIndicies = new uint16_t[p->mIndexCount];
273 for (uint32_t ct = 0; ct < p->mIndexCount; ct++) {
274 switch(bits) {
275 case 8:
276 p->mIndicies[ct] = io->loadU8();
277 break;
278 case 16:
279 p->mIndicies[ct] = io->loadU16();
280 break;
281 case 32:
282 p->mIndicies[ct] = io->loadU32();
283 break;
284 }
Jason Samsb80dfa72009-07-10 17:32:40 -0700285 LOGE(" idx %i", p->mIndicies[ct]);
286 }
287
288 if (p->mRestartCounts) {
289 p->mRestarts = new uint16_t[p->mRestartCounts];
290 for (uint32_t ct = 0; ct < p->mRestartCounts; ct++) {
291 switch(bits) {
292 case 8:
293 p->mRestarts[ct] = io->loadU8();
294 break;
295 case 16:
296 p->mRestarts[ct] = io->loadU16();
297 break;
298 case 32:
299 p->mRestarts[ct] = io->loadU32();
300 break;
301 }
302 LOGE(" idx %i", p->mRestarts[ct]);
303 }
304 } else {
305 p->mRestarts = NULL;
Jason Samsa5597fc2009-07-08 18:01:53 -0700306 }
307
308 ie->mRsObj = p;
309}
310
311void FileA3D::processChunk_Verticies(Context *rsc, IO *io, A3DIndexEntry *ie)
312{
313 Mesh::Verticies_t *cv = new Mesh::Verticies_t;
314 cv->mAllocationCount = io->loadU32();
315 cv->mAllocations = new Allocation *[cv->mAllocationCount];
Jason Samsb80dfa72009-07-10 17:32:40 -0700316 LOGE("processChunk_Verticies count %i", cv->mAllocationCount);
Jason Samsa5597fc2009-07-08 18:01:53 -0700317 for (uint32_t ct = 0; ct < cv->mAllocationCount; ct++) {
318 uint32_t i = io->loadU32();
319 cv->mAllocations[ct] = (Allocation *)mIndex[i].mRsObj;
Jason Samsb80dfa72009-07-10 17:32:40 -0700320 LOGE(" idx %i", i);
Jason Samsa5597fc2009-07-08 18:01:53 -0700321 }
322 ie->mRsObj = cv;
323}
324
325void FileA3D::processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie)
326{
Jason Samsa5597fc2009-07-08 18:01:53 -0700327 rsi_ElementBegin(rsc);
328
329 uint32_t count = io->loadU32();
330 LOGE("processChunk_Element count %i", count);
331 while (count--) {
332 RsDataKind dk = (RsDataKind)io->loadU8();
333 RsDataType dt = (RsDataType)io->loadU8();
334 uint32_t bits = io->loadU8();
335 bool isNorm = io->loadU8() != 0;
336 LOGE(" %i %i %i %i", dk, dt, bits, isNorm);
337 rsi_ElementAdd(rsc, dk, dt, isNorm, bits);
338 }
339 LOGE("processChunk_Element create");
340 ie->mRsObj = rsi_ElementCreate(rsc);
341}
342
343void FileA3D::processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie)
344{
345 uint32_t index = io->loadU32();
346 uint32_t count = io->loadU32();
347
Jason Samsb80dfa72009-07-10 17:32:40 -0700348 LOGE("processChunk_ElementSource count %i, index %i", count, index);
349
Jason Samsa5597fc2009-07-08 18:01:53 -0700350 RsElement e = (RsElement)mIndex[index].mRsObj;
351
352 RsAllocation a = rsi_AllocationCreateSized(rsc, e, count);
353 Allocation * alloc = static_cast<Allocation *>(a);
354
355 float * data = (float *)alloc->getPtr();
356 while(count--) {
357 *data = io->loadF();
Jason Samsb80dfa72009-07-10 17:32:40 -0700358 LOGE(" %f", *data);
Jason Samsa5597fc2009-07-08 18:01:53 -0700359 data++;
360 }
361 ie->mRsObj = alloc;
362}
363
364namespace android {
365namespace renderscript {
366
367
368RsFile rsi_FileOpen(Context *rsc, char const *path, unsigned int len)
369{
370 FileA3D *fa3d = new FileA3D;
371
372 FILE *f = fopen("/sdcard/test.a3d", "rb");
373 if (f) {
374 fa3d->load(rsc, f);
375 fclose(f);
376 return fa3d;
377 }
378 delete fa3d;
379 return NULL;
380}
381
382
383}
384}