Removed unnecessary change based on comments.
Now using android utils lib.
collada_to_a3d seems to work with android util libs.
Integrating old changelist
Changing assert to rsAssrt in VertexArray
making context compile.
Change-Id: I33890defa777f09253bfab630d97782359ec49d7
Added serialization code to rsLib
Integrated old changelist
Change-Id: Ie4746113f6d1817fbb3264f97fdddde25b779311
Added serialization code to rsLib
Change-Id: Ie4746113f6d1817fbb3264f97fdddde25b779311
diff --git a/rsFileA3D.cpp b/rsFileA3D.cpp
index e3272c5..b88f7b0 100644
--- a/rsFileA3D.cpp
+++ b/rsFileA3D.cpp
@@ -15,13 +15,16 @@
* limitations under the License.
*/
+#ifndef ANDROID_RS_BUILD_FOR_HOST
#include "rsContext.h"
+#else
+#include "rsContextHostStub.h"
+#endif
-
-#include <utils/String8.h>
#include "rsFileA3D.h"
#include "rsMesh.h"
+#include "rsAnimation.h"
using namespace android;
using namespace android::renderscript;
@@ -31,10 +34,33 @@
FileA3D::FileA3D()
{
mRsc = NULL;
+ mAlloc = NULL;
+ mData = NULL;
+ mWriteStream = NULL;
+ mReadStream = NULL;
+
+ mMajorVersion = 0;
+ mMinorVersion = 1;
+ mDataSize = 0;
}
FileA3D::~FileA3D()
{
+ for(size_t i = 0; i < mIndex.size(); i ++) {
+ delete mIndex[i];
+ }
+ for(size_t i = 0; i < mWriteIndex.size(); i ++) {
+ delete mWriteIndex[i];
+ }
+ if(mWriteStream) {
+ delete mWriteStream;
+ }
+ if(mReadStream) {
+ delete mWriteStream;
+ }
+ if(mAlloc) {
+ free(mAlloc);
+ }
}
bool FileA3D::load(Context *rsc, FILE *f)
@@ -49,47 +75,58 @@
return false;
}
- LOGE("file open 2");
- len = fread(&mMajorVersion, 1, sizeof(mMajorVersion), f);
- if (len != sizeof(mMajorVersion)) {
+ // Next thing is the size of the header
+ uint64_t headerSize = 0;
+ len = fread(&headerSize, 1, sizeof(headerSize), f);
+ if (len != sizeof(headerSize) || headerSize == 0) {
return false;
}
- LOGE("file open 3");
- len = fread(&mMinorVersion, 1, sizeof(mMinorVersion), f);
- if (len != sizeof(mMinorVersion)) {
+ uint8_t *headerData = (uint8_t *)malloc(headerSize);
+ if(!headerData) {
return false;
}
- LOGE("file open 4");
- uint32_t flags;
- len = fread(&flags, 1, sizeof(flags), f);
- if (len != sizeof(flags)) {
+ len = fread(headerData, 1, headerSize, f);
+ if (len != headerSize) {
return false;
}
+
+ // Now open the stream to parse the header
+ IStream headerStream(headerData, false);
+
+ mMajorVersion = headerStream.loadU32();
+ mMinorVersion = headerStream.loadU32();
+ uint32_t flags = headerStream.loadU32();
mUse64BitOffsets = (flags & 1) != 0;
LOGE("file open 64bit = %i", mUse64BitOffsets);
- if (mUse64BitOffsets) {
- len = fread(&mDataSize, 1, sizeof(mDataSize), f);
- if (len != sizeof(mDataSize)) {
- return false;
+ uint32_t numIndexEntries = headerStream.loadU32();
+ for(uint32_t i = 0; i < numIndexEntries; i ++) {
+ A3DIndexEntry *entry = new A3DIndexEntry();
+ headerStream.loadString(&entry->mID);
+ entry->mType = (A3DClassID)headerStream.loadU32();
+ if(mUse64BitOffsets){
+ entry->mOffset = headerStream.loadOffset();
}
- } else {
- uint32_t tmp;
- len = fread(&tmp, 1, sizeof(tmp), f);
- if (len != sizeof(tmp)) {
- return false;
+ else {
+ entry->mOffset = headerStream.loadU32();
}
- mDataSize = tmp;
+ entry->mRsObj = NULL;
+ mIndex.push(entry);
+ }
+
+ // Next thing is the size of the header
+ len = fread(&mDataSize, 1, sizeof(mDataSize), f);
+ if (len != sizeof(mDataSize) || mDataSize == 0) {
+ return false;
}
LOGE("file open size = %lli", mDataSize);
// We should know enough to read the file in at this point.
- fseek(f, SEEK_SET, 0);
- mAlloc= malloc(mDataSize);
+ mAlloc = malloc(mDataSize);
if (!mAlloc) {
return false;
}
@@ -99,268 +136,149 @@
return false;
}
- LOGE("file start processing");
- return process(rsc);
+ mReadStream = new IStream(mData, mUse64BitOffsets);
+
+ mRsc = rsc;
+
+ LOGE("Header is read an stream initialized");
+ return true;
}
-bool FileA3D::processIndex(Context *rsc, A3DIndexEntry *ie)
-{
- bool ret = false;
- IO io(mData + ie->mOffset, mUse64BitOffsets);
+size_t FileA3D::getNumLoadedEntries() const {
+ return mIndex.size();
+}
- LOGE("process index, type %i", ie->mType);
-
- switch(ie->mType) {
- case CHUNK_ELEMENT:
- processChunk_Element(rsc, &io, ie);
- break;
- case CHUNK_ELEMENT_SOURCE:
- processChunk_ElementSource(rsc, &io, ie);
- break;
- case CHUNK_VERTICIES:
- processChunk_Verticies(rsc, &io, ie);
- break;
- case CHUNK_MESH:
- processChunk_Mesh(rsc, &io, ie);
- break;
- case CHUNK_PRIMITIVE:
- processChunk_Primitive(rsc, &io, ie);
- break;
- default:
- LOGE("FileA3D Unknown chunk type");
- break;
+const FileA3D::A3DIndexEntry *FileA3D::getLoadedEntry(size_t index) const {
+ if(index < mIndex.size()) {
+ return mIndex[index];
}
- return (ie->mRsObj != NULL);
+ return NULL;
}
-bool FileA3D::process(Context *rsc)
+ObjectBase *FileA3D::initializeFromEntry(const FileA3D::A3DIndexEntry *entry) {
+ if(!entry) {
+ return NULL;
+ }
+
+ // Seek to the beginning of object
+ mReadStream->reset(entry->mOffset);
+ switch (entry->mType) {
+ case A3D_CLASS_ID_UNKNOWN:
+ return NULL;
+ case A3D_CLASS_ID_MESH:
+ return Mesh::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_SIMPLE_MESH:
+ return SimpleMesh::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_TYPE:
+ return Type::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_ELEMENT:
+ return Element::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_ALLOCATION:
+ return Allocation::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_PROGRAM_VERTEX:
+ return ProgramVertex::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_PROGRAM_RASTER:
+ return ProgramRaster::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_PROGRAM_FRAGMENT:
+ return ProgramFragment::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_PROGRAM_STORE:
+ return ProgramStore::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_SAMPLER:
+ return Sampler::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_ANIMATION:
+ return Animation::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_LIGHT:
+ return Light::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_ADAPTER_1D:
+ return Adapter1D::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_ADAPTER_2D:
+ return Adapter2D::createFromStream(mRsc, mReadStream);
+ case A3D_CLASS_ID_SCRIPT_C:
+ return NULL;
+ }
+ return NULL;
+}
+
+bool FileA3D::writeFile(const char *filename)
{
- LOGE("process");
- IO io(mData + 12, mUse64BitOffsets);
- bool ret = true;
+ if(!mWriteStream) {
+ LOGE("No objects to write\n");
+ return false;
+ }
+ if(mWriteStream->getPos() == 0) {
+ LOGE("No objects to write\n");
+ return false;
+ }
- // Build the index first
- LOGE("process 1");
- io.loadU32(); // major version, already loaded
- io.loadU32(); // minor version, already loaded
- LOGE("process 2");
+ FILE *writeHandle = fopen(filename, "wb");
+ if(!writeHandle) {
+ LOGE("Couldn't open the file for writing\n");
+ return false;
+ }
- io.loadU32(); // flags
- io.loadOffset(); // filesize, already loaded.
- LOGE("process 4");
- uint64_t mIndexOffset = io.loadOffset();
- uint64_t mStringOffset = io.loadOffset();
+ // Open a new stream to make writing the header easier
+ OStream headerStream(5*1024, false);
+ headerStream.addU32(mMajorVersion);
+ headerStream.addU32(mMinorVersion);
+ uint32_t is64Bit = 0;
+ headerStream.addU32(is64Bit);
- LOGE("process mIndexOffset= 0x%016llx", mIndexOffset);
- LOGE("process mStringOffset= 0x%016llx", mStringOffset);
-
- IO index(mData + mIndexOffset, mUse64BitOffsets);
- IO stringTable(mData + mStringOffset, mUse64BitOffsets);
-
- uint32_t stringEntryCount = stringTable.loadU32();
- LOGE("stringEntryCount %i", stringEntryCount);
- mStrings.setCapacity(stringEntryCount);
- mStringIndexValues.setCapacity(stringEntryCount);
- if (stringEntryCount) {
- uint32_t stringType = stringTable.loadU32();
- LOGE("stringType %i", stringType);
- rsAssert(stringType==0);
- for (uint32_t ct = 0; ct < stringEntryCount; ct++) {
- uint64_t offset = stringTable.loadOffset();
- LOGE("string offset 0x%016llx", offset);
- IO tmp(mData + offset, mUse64BitOffsets);
- String8 s;
- tmp.loadString(&s);
- LOGE("string %s", s.string());
- mStrings.push(s);
+ uint32_t writeIndexSize = mWriteIndex.size();
+ headerStream.addU32(writeIndexSize);
+ for(uint32_t i = 0; i < writeIndexSize; i ++) {
+ headerStream.addString(&mWriteIndex[i]->mID);
+ headerStream.addU32((uint32_t)mWriteIndex[i]->mType);
+ if(mUse64BitOffsets){
+ headerStream.addOffset(mWriteIndex[i]->mOffset);
+ }
+ else {
+ uint32_t offset = (uint32_t)mWriteIndex[i]->mOffset;
+ headerStream.addU32(offset);
}
}
- LOGE("strings done");
- uint32_t indexEntryCount = index.loadU32();
- LOGE("index count %i", indexEntryCount);
- mIndex.setCapacity(indexEntryCount);
- for (uint32_t ct = 0; ct < indexEntryCount; ct++) {
- A3DIndexEntry e;
- uint32_t stringIndex = index.loadU32();
- LOGE("index %i", ct);
- LOGE(" string index %i", stringIndex);
- e.mType = (A3DChunkType)index.loadU32();
- LOGE(" type %i", e.mType);
- e.mOffset = index.loadOffset();
- LOGE(" offset 0x%016llx", e.mOffset);
+ // Write our magic string so we know we are reading the right file
+ String8 magicString(A3D_MAGIC_KEY);
+ fwrite(magicString.string(), sizeof(char), magicString.size(), writeHandle);
- if (stringIndex && (stringIndex < mStrings.size())) {
- e.mID = mStrings[stringIndex];
- mStringIndexValues.editItemAt(stringIndex) = ct;
- LOGE(" id %s", e.mID.string());
- }
+ // Store the size of the header to make it easier to parse when we read it
+ uint64_t headerSize = headerStream.getPos();
+ fwrite(&headerSize, sizeof(headerSize), 1, writeHandle);
- mIndex.push(e);
- }
- LOGE("index done");
+ // Now write our header
+ fwrite(headerStream.getPtr(), sizeof(uint8_t), headerStream.getPos(), writeHandle);
- // At this point the index should be fully populated.
- // We can now walk though it and load all the objects.
- for (uint32_t ct = 0; ct < indexEntryCount; ct++) {
- LOGE("processing index entry %i", ct);
- processIndex(rsc, &mIndex.editItemAt(ct));
+ // Now write the size of the data part of the file for easier parsing later
+ uint64_t fileDataSize = mWriteStream->getPos();
+ fwrite(&fileDataSize, sizeof(fileDataSize), 1, writeHandle);
+
+ fwrite(mWriteStream->getPtr(), sizeof(uint8_t), mWriteStream->getPos(), writeHandle);
+
+ int status = fclose(writeHandle);
+
+ if(status != 0) {
+ LOGE("Couldn't close file\n");
+ return false;
}
- return ret;
+ return true;
}
-
-FileA3D::IO::IO(const uint8_t *buf, bool use64)
-{
- mData = buf;
- mPos = 0;
- mUse64 = use64;
-}
-
-uint64_t FileA3D::IO::loadOffset()
-{
- uint64_t tmp;
- if (mUse64) {
- mPos = (mPos + 7) & (~7);
- tmp = reinterpret_cast<const uint64_t *>(&mData[mPos])[0];
- mPos += sizeof(uint64_t);
- return tmp;
+void FileA3D::appendToFile(ObjectBase *obj) {
+ if(!obj) {
+ return;
}
- return loadU32();
-}
-
-void FileA3D::IO::loadString(String8 *s)
-{
- LOGE("loadString");
- uint32_t len = loadU32();
- LOGE("loadString len %i", len);
- s->setTo((const char *)&mData[mPos], len);
- mPos += len;
-}
-
-
-void FileA3D::processChunk_Mesh(Context *rsc, IO *io, A3DIndexEntry *ie)
-{
- Mesh * m = new Mesh(rsc);
-
- m->mPrimitivesCount = io->loadU32();
- m->mPrimitives = new Mesh::Primitive_t *[m->mPrimitivesCount];
-
- for (uint32_t ct = 0; ct < m->mPrimitivesCount; ct++) {
- uint32_t index = io->loadU32();
-
- m->mPrimitives[ct] = (Mesh::Primitive_t *)mIndex[index].mRsObj;
+ if(!mWriteStream) {
+ const uint64_t initialStreamSize = 256*1024;
+ mWriteStream = new OStream(initialStreamSize, false);
}
- ie->mRsObj = m;
-}
-
-void FileA3D::processChunk_Primitive(Context *rsc, IO *io, A3DIndexEntry *ie)
-{
- Mesh::Primitive_t * p = new Mesh::Primitive_t;
-
- p->mIndexCount = io->loadU32();
- uint32_t vertIdx = io->loadU32();
- p->mRestartCounts = io->loadU16();
- uint32_t bits = io->loadU8();
- p->mType = (RsPrimitive)io->loadU8();
-
- LOGE("processChunk_Primitive count %i, bits %i", p->mIndexCount, bits);
-
- p->mVerticies = (Mesh::Verticies_t *)mIndex[vertIdx].mRsObj;
-
- p->mIndicies = new uint16_t[p->mIndexCount];
- for (uint32_t ct = 0; ct < p->mIndexCount; ct++) {
- switch(bits) {
- case 8:
- p->mIndicies[ct] = io->loadU8();
- break;
- case 16:
- p->mIndicies[ct] = io->loadU16();
- break;
- case 32:
- p->mIndicies[ct] = io->loadU32();
- break;
- }
- LOGE(" idx %i", p->mIndicies[ct]);
- }
-
- if (p->mRestartCounts) {
- p->mRestarts = new uint16_t[p->mRestartCounts];
- for (uint32_t ct = 0; ct < p->mRestartCounts; ct++) {
- switch(bits) {
- case 8:
- p->mRestarts[ct] = io->loadU8();
- break;
- case 16:
- p->mRestarts[ct] = io->loadU16();
- break;
- case 32:
- p->mRestarts[ct] = io->loadU32();
- break;
- }
- LOGE(" idx %i", p->mRestarts[ct]);
- }
- } else {
- p->mRestarts = NULL;
- }
-
- ie->mRsObj = p;
-}
-
-void FileA3D::processChunk_Verticies(Context *rsc, IO *io, A3DIndexEntry *ie)
-{
- Mesh::Verticies_t *cv = new Mesh::Verticies_t;
- cv->mAllocationCount = io->loadU32();
- cv->mAllocations = new Allocation *[cv->mAllocationCount];
- LOGE("processChunk_Verticies count %i", cv->mAllocationCount);
- for (uint32_t ct = 0; ct < cv->mAllocationCount; ct++) {
- uint32_t i = io->loadU32();
- cv->mAllocations[ct] = (Allocation *)mIndex[i].mRsObj;
- LOGE(" idx %i", i);
- }
- ie->mRsObj = cv;
-}
-
-void FileA3D::processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie)
-{
- /*
- rsi_ElementBegin(rsc);
-
- uint32_t count = io->loadU32();
- LOGE("processChunk_Element count %i", count);
- while (count--) {
- RsDataKind dk = (RsDataKind)io->loadU8();
- RsDataType dt = (RsDataType)io->loadU8();
- uint32_t bits = io->loadU8();
- bool isNorm = io->loadU8() != 0;
- LOGE(" %i %i %i %i", dk, dt, bits, isNorm);
- rsi_ElementAdd(rsc, dk, dt, isNorm, bits, 0);
- }
- LOGE("processChunk_Element create");
- ie->mRsObj = rsi_ElementCreate(rsc);
- */
-}
-
-void FileA3D::processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie)
-{
- uint32_t index = io->loadU32();
- uint32_t count = io->loadU32();
-
- LOGE("processChunk_ElementSource count %i, index %i", count, index);
-
- RsElement e = (RsElement)mIndex[index].mRsObj;
-
- RsAllocation a = rsi_AllocationCreateSized(rsc, e, count);
- Allocation * alloc = static_cast<Allocation *>(a);
-
- float * data = (float *)alloc->getPtr();
- while(count--) {
- *data = io->loadF();
- LOGE(" %f", *data);
- data++;
- }
- ie->mRsObj = alloc;
+ A3DIndexEntry *indexEntry = new A3DIndexEntry();
+ indexEntry->mID.setTo(obj->getName());
+ indexEntry->mType = obj->getClassId();
+ indexEntry->mOffset = mWriteStream->getPos();
+ indexEntry->mRsObj = (void*)obj;
+ mWriteIndex.push(indexEntry);
+ obj->serialize(mWriteStream);
}
namespace android {