diff options
Diffstat (limited to 'libs/rs/rsFileA3D.cpp')
-rw-r--r-- | libs/rs/rsFileA3D.cpp | 434 |
1 files changed, 176 insertions, 258 deletions
diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp index e3272c5d68e9..b88f7b0e04d1 100644 --- a/libs/rs/rsFileA3D.cpp +++ b/libs/rs/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 @@ using namespace android::renderscript; 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 @@ bool FileA3D::load(Context *rsc, FILE *f) 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 @@ bool FileA3D::load(Context *rsc, FILE *f) 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); - - 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; - } - return (ie->mRsObj != NULL); +size_t FileA3D::getNumLoadedEntries() const { + return mIndex.size(); } -bool FileA3D::process(Context *rsc) -{ - LOGE("process"); - IO io(mData + 12, mUse64BitOffsets); - bool ret = true; - - // Build the index first - LOGE("process 1"); - io.loadU32(); // major version, already loaded - io.loadU32(); // minor version, already loaded - LOGE("process 2"); - - io.loadU32(); // flags - io.loadOffset(); // filesize, already loaded. - LOGE("process 4"); - uint64_t mIndexOffset = io.loadOffset(); - uint64_t mStringOffset = io.loadOffset(); - - 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); - } +const FileA3D::A3DIndexEntry *FileA3D::getLoadedEntry(size_t index) const { + if(index < mIndex.size()) { + return mIndex[index]; } + return NULL; +} - 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); - - if (stringIndex && (stringIndex < mStrings.size())) { - e.mID = mStrings[stringIndex]; - mStringIndexValues.editItemAt(stringIndex) = ct; - LOGE(" id %s", e.mID.string()); - } - - mIndex.push(e); +ObjectBase *FileA3D::initializeFromEntry(const FileA3D::A3DIndexEntry *entry) { + if(!entry) { + return NULL; } - LOGE("index done"); - // 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)); + // 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 ret; -} - - -FileA3D::IO::IO(const uint8_t *buf, bool use64) -{ - mData = buf; - mPos = 0; - mUse64 = use64; + return NULL; } -uint64_t FileA3D::IO::loadOffset() +bool FileA3D::writeFile(const char *filename) { - uint64_t tmp; - if (mUse64) { - mPos = (mPos + 7) & (~7); - tmp = reinterpret_cast<const uint64_t *>(&mData[mPos])[0]; - mPos += sizeof(uint64_t); - return tmp; + if(!mWriteStream) { + LOGE("No objects to write\n"); + return false; } - 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->getPos() == 0) { + LOGE("No objects to write\n"); + return 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]); + FILE *writeHandle = fopen(filename, "wb"); + if(!writeHandle) { + LOGE("Couldn't open the file for writing\n"); + return false; } - 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]); + // 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); + + 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); } - } else { - p->mRestarts = NULL; } - ie->mRsObj = p; -} + // 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); -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; -} + // 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); -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); - */ -} + // Now write our header + fwrite(headerStream.getPtr(), sizeof(uint8_t), headerStream.getPos(), writeHandle); -void FileA3D::processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie) -{ - uint32_t index = io->loadU32(); - uint32_t count = io->loadU32(); + // 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); - LOGE("processChunk_ElementSource count %i, index %i", count, index); + fwrite(mWriteStream->getPtr(), sizeof(uint8_t), mWriteStream->getPos(), writeHandle); - RsElement e = (RsElement)mIndex[index].mRsObj; + int status = fclose(writeHandle); - RsAllocation a = rsi_AllocationCreateSized(rsc, e, count); - Allocation * alloc = static_cast<Allocation *>(a); + if(status != 0) { + LOGE("Couldn't close file\n"); + return false; + } - float * data = (float *)alloc->getPtr(); - while(count--) { - *data = io->loadF(); - LOGE(" %f", *data); - data++; + return true; +} + +void FileA3D::appendToFile(ObjectBase *obj) { + if(!obj) { + return; + } + if(!mWriteStream) { + const uint64_t initialStreamSize = 256*1024; + mWriteStream = new OStream(initialStreamSize, false); } - 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 { |