3 * Copyright (C) 2009 The Android Open Source Project
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "rsContext.h"
21 #include <utils/String8.h>
22 #include "rsFileA3D.h"
26 using namespace android;
27 using namespace android::renderscript;
40 bool FileA3D::load(Context *rsc, FILE *f)
46 len = fread(magicString, 1, 12, f);
48 memcmp(magicString, "Android3D_ff", 12)) {
53 len = fread(&mMajorVersion, 1, sizeof(mMajorVersion), f);
54 if (len != sizeof(mMajorVersion)) {
59 len = fread(&mMinorVersion, 1, sizeof(mMinorVersion), f);
60 if (len != sizeof(mMinorVersion)) {
66 len = fread(&flags, 1, sizeof(flags), f);
67 if (len != sizeof(flags)) {
70 mUse64BitOffsets = (flags & 1) != 0;
72 LOGE("file open 64bit = %i", mUse64BitOffsets);
74 if (mUse64BitOffsets) {
75 len = fread(&mDataSize, 1, sizeof(mDataSize), f);
76 if (len != sizeof(mDataSize)) {
81 len = fread(&tmp, 1, sizeof(tmp), f);
82 if (len != sizeof(tmp)) {
88 LOGE("file open size = %lli", mDataSize);
90 // We should know enough to read the file in at this point.
91 fseek(f, SEEK_SET, 0);
92 mAlloc= malloc(mDataSize);
96 mData = (uint8_t *)mAlloc;
97 len = fread(mAlloc, 1, mDataSize, f);
98 if (len != mDataSize) {
102 LOGE("file start processing");
106 bool FileA3D::processIndex(Context *rsc, A3DIndexEntry *ie)
109 IO io(mData + ie->mOffset, mUse64BitOffsets);
111 LOGE("process index, type %i", ie->mType);
115 processChunk_Element(rsc, &io, ie);
117 case CHUNK_ELEMENT_SOURCE:
118 processChunk_ElementSource(rsc, &io, ie);
120 case CHUNK_VERTICIES:
121 processChunk_Verticies(rsc, &io, ie);
124 processChunk_Mesh(rsc, &io, ie);
126 case CHUNK_PRIMITIVE:
127 processChunk_Primitive(rsc, &io, ie);
130 LOGE("FileA3D Unknown chunk type");
133 return (ie->mRsObj != NULL);
136 bool FileA3D::process(Context *rsc)
139 IO io(mData + 12, mUse64BitOffsets);
142 // Build the index first
144 io.loadU32(); // major version, already loaded
145 io.loadU32(); // minor version, already loaded
148 io.loadU32(); // flags
149 io.loadOffset(); // filesize, already loaded.
151 uint64_t mIndexOffset = io.loadOffset();
152 uint64_t mStringOffset = io.loadOffset();
154 LOGE("process mIndexOffset= 0x%016llx", mIndexOffset);
155 LOGE("process mStringOffset= 0x%016llx", mStringOffset);
157 IO index(mData + mIndexOffset, mUse64BitOffsets);
158 IO stringTable(mData + mStringOffset, mUse64BitOffsets);
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);
174 LOGE("string %s", s.string());
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++) {
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);
193 if (stringIndex && (stringIndex < mStrings.size())) {
194 e.mID = mStrings[stringIndex];
195 mStringIndexValues.editItemAt(stringIndex) = ct;
196 LOGE(" id %s", e.mID.string());
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));
214 FileA3D::IO::IO(const uint8_t *buf, bool use64)
221 uint64_t FileA3D::IO::loadOffset()
225 mPos = (mPos + 7) & (~7);
226 tmp = reinterpret_cast<const uint64_t *>(&mData[mPos])[0];
227 mPos += sizeof(uint64_t);
233 void FileA3D::IO::loadString(String8 *s)
236 uint32_t len = loadU32();
237 LOGE("loadString len %i", len);
238 s->setTo((const char *)&mData[mPos], len);
243 void FileA3D::processChunk_Mesh(Context *rsc, IO *io, A3DIndexEntry *ie)
245 Mesh * m = new Mesh(rsc);
247 m->mPrimitivesCount = io->loadU32();
248 m->mPrimitives = new Mesh::Primitive_t *[m->mPrimitivesCount];
250 for (uint32_t ct = 0; ct < m->mPrimitivesCount; ct++) {
251 uint32_t index = io->loadU32();
253 m->mPrimitives[ct] = (Mesh::Primitive_t *)mIndex[index].mRsObj;
258 void FileA3D::processChunk_Primitive(Context *rsc, IO *io, A3DIndexEntry *ie)
260 Mesh::Primitive_t * p = new Mesh::Primitive_t;
262 p->mIndexCount = io->loadU32();
263 uint32_t vertIdx = io->loadU32();
264 p->mRestartCounts = io->loadU16();
265 uint32_t bits = io->loadU8();
266 p->mType = (RsPrimitive)io->loadU8();
268 LOGE("processChunk_Primitive count %i, bits %i", p->mIndexCount, bits);
270 p->mVerticies = (Mesh::Verticies_t *)mIndex[vertIdx].mRsObj;
272 p->mIndicies = new uint16_t[p->mIndexCount];
273 for (uint32_t ct = 0; ct < p->mIndexCount; ct++) {
276 p->mIndicies[ct] = io->loadU8();
279 p->mIndicies[ct] = io->loadU16();
282 p->mIndicies[ct] = io->loadU32();
285 LOGE(" idx %i", p->mIndicies[ct]);
288 if (p->mRestartCounts) {
289 p->mRestarts = new uint16_t[p->mRestartCounts];
290 for (uint32_t ct = 0; ct < p->mRestartCounts; ct++) {
293 p->mRestarts[ct] = io->loadU8();
296 p->mRestarts[ct] = io->loadU16();
299 p->mRestarts[ct] = io->loadU32();
302 LOGE(" idx %i", p->mRestarts[ct]);
311 void FileA3D::processChunk_Verticies(Context *rsc, IO *io, A3DIndexEntry *ie)
313 Mesh::Verticies_t *cv = new Mesh::Verticies_t;
314 cv->mAllocationCount = io->loadU32();
315 cv->mAllocations = new Allocation *[cv->mAllocationCount];
316 LOGE("processChunk_Verticies count %i", cv->mAllocationCount);
317 for (uint32_t ct = 0; ct < cv->mAllocationCount; ct++) {
318 uint32_t i = io->loadU32();
319 cv->mAllocations[ct] = (Allocation *)mIndex[i].mRsObj;
325 void FileA3D::processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie)
328 rsi_ElementBegin(rsc);
330 uint32_t count = io->loadU32();
331 LOGE("processChunk_Element count %i", count);
333 RsDataKind dk = (RsDataKind)io->loadU8();
334 RsDataType dt = (RsDataType)io->loadU8();
335 uint32_t bits = io->loadU8();
336 bool isNorm = io->loadU8() != 0;
337 LOGE(" %i %i %i %i", dk, dt, bits, isNorm);
338 rsi_ElementAdd(rsc, dk, dt, isNorm, bits, 0);
340 LOGE("processChunk_Element create");
341 ie->mRsObj = rsi_ElementCreate(rsc);
345 void FileA3D::processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie)
347 uint32_t index = io->loadU32();
348 uint32_t count = io->loadU32();
350 LOGE("processChunk_ElementSource count %i, index %i", count, index);
352 RsElement e = (RsElement)mIndex[index].mRsObj;
354 RsAllocation a = rsi_AllocationCreateSized(rsc, e, count);
355 Allocation * alloc = static_cast<Allocation *>(a);
357 float * data = (float *)alloc->getPtr();
367 namespace renderscript {
370 RsFile rsi_FileOpen(Context *rsc, char const *path, unsigned int len)
372 FileA3D *fa3d = new FileA3D;
374 FILE *f = fopen("/sdcard/test.a3d", "rb");