diff options
| -rw-r--r-- | RenderScript.h | 1 | ||||
| -rw-r--r-- | java/RenderScript/android/renderscript/RenderScript.java | 31 | ||||
| -rw-r--r-- | jni/RenderScript_jni.cpp | 15 | ||||
| -rw-r--r-- | rs.spec | 7 | ||||
| -rw-r--r-- | rsFileA3D.cpp | 356 | ||||
| -rw-r--r-- | rsFileA3D.h | 122 | ||||
| -rw-r--r-- | rsFileA3DDecls.h | 44 | ||||
| -rw-r--r-- | rsMesh.cpp | 5 | ||||
| -rw-r--r-- | rsMesh.h | 24 |
9 files changed, 593 insertions, 12 deletions
diff --git a/RenderScript.h b/RenderScript.h index 5f551df6..855ea634 100644 --- a/RenderScript.h +++ b/RenderScript.h @@ -33,6 +33,7 @@ typedef void * RsAllocation; typedef void * RsContext; typedef void * RsDevice; typedef void * RsElement; +typedef void * RsFile; typedef void * RsSampler; typedef void * RsScript; typedef void * RsScriptBasicTemp; diff --git a/java/RenderScript/android/renderscript/RenderScript.java b/java/RenderScript/android/renderscript/RenderScript.java index a9db15f0..09d18369 100644 --- a/java/RenderScript/android/renderscript/RenderScript.java +++ b/java/RenderScript/android/renderscript/RenderScript.java @@ -70,6 +70,7 @@ public class RenderScript { native private void nContextBindProgramVertex(int pf); native private void nAssignName(int obj, byte[] name); + native private int nFileOpen(byte[] name); native private void nElementBegin(); native private void nElementAddPredefined(int predef); @@ -916,6 +917,36 @@ public class RenderScript { return new Light(id); } + ////////////////////////////////////////////////////////////////////////////////// + // File + + public class File extends BaseObj { + File(int id) { + mID = id; + } + + public void destroy() { + //nLightDestroy(mID); + mID = 0; + } + } + + public File fileOpen(String s) throws IllegalStateException, IllegalArgumentException + { + if(s.length() < 1) { + throw new IllegalArgumentException("fileOpen does not accept a zero length string."); + } + + try { + byte[] bytes = s.getBytes("UTF-8"); + int id = nFileOpen(bytes); + return new File(id); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + /////////////////////////////////////////////////////////////////////////////////// // Root state diff --git a/jni/RenderScript_jni.cpp b/jni/RenderScript_jni.cpp index 5677bb7f..248a6bd7 100644 --- a/jni/RenderScript_jni.cpp +++ b/jni/RenderScript_jni.cpp @@ -75,6 +75,19 @@ nAssignName(JNIEnv *_env, jobject _this, jint obj, jbyteArray str) } +static jint +nFileOpen(JNIEnv *_env, jobject _this, jbyteArray str) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nFileOpen, con(%p)", con); + + jint len = _env->GetArrayLength(str); + jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0); + jint ret = (jint)rsFileOpen((const char *)cptr, len); + _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT); + return ret; +} + // --------------------------------------------------------------------------- static jint @@ -955,6 +968,8 @@ static JNINativeMethod methods[] = { {"nContextDestroy", "(I)V", (void*)nContextDestroy }, {"nAssignName", "(I[B)V", (void*)nAssignName }, +{"nFileOpen", "([B)I", (void*)nFileOpen }, + {"nElementBegin", "()V", (void*)nElementBegin }, {"nElementAddPredefined", "(I)V", (void*)nElementAddPredefined }, {"nElementAdd", "(IIII)V", (void*)nElementAdd }, @@ -436,3 +436,10 @@ LightSetColor { param float b } +FileOpen { + ret RsFile + param const char *name + param size_t len + } + + diff --git a/rsFileA3D.cpp b/rsFileA3D.cpp new file mode 100644 index 00000000..f669417d --- /dev/null +++ b/rsFileA3D.cpp @@ -0,0 +1,356 @@ + +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rsContext.h" + + +#include <utils/String8.h> +#include "rsFileA3D.h" + +#include "rsMesh.h" + +using namespace android; +using namespace android::renderscript; + + + +FileA3D::FileA3D() +{ + mRsc = NULL; +} + +FileA3D::~FileA3D() +{ +} + +bool FileA3D::load(Context *rsc, FILE *f) +{ + char magicString[12]; + size_t len; + + LOGE("file open 1"); + len = fread(magicString, 1, 12, f); + if ((len != 12) || + memcmp(magicString, "Android3D_ff", 12)) { + return false; + } + + LOGE("file open 2"); + len = fread(&mMajorVersion, 1, sizeof(mMajorVersion), f); + if (len != sizeof(mMajorVersion)) { + return false; + } + + LOGE("file open 3"); + len = fread(&mMinorVersion, 1, sizeof(mMinorVersion), f); + if (len != sizeof(mMinorVersion)) { + return false; + } + + LOGE("file open 4"); + uint32_t flags; + len = fread(&flags, 1, sizeof(flags), f); + if (len != sizeof(flags)) { + return false; + } + 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; + } + } else { + uint32_t tmp; + len = fread(&tmp, 1, sizeof(tmp), f); + if (len != sizeof(tmp)) { + return false; + } + mDataSize = tmp; + } + + 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); + if (!mAlloc) { + return false; + } + mData = (uint8_t *)mAlloc; + len = fread(mAlloc, 1, mDataSize, f); + if (len != mDataSize) { + return false; + } + + LOGE("file start processing"); + return process(rsc); +} + +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); +} + +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); + } + } + + 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); + } + 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)); + } + + return ret; +} + + +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; + } + 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; + + 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; + } + 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(); + uint32_t bits = io->loadU8(); + p->mType = (RsPrimitive)io->loadU8(); + + 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; + } + } + + 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]; + for (uint32_t ct = 0; ct < cv->mAllocationCount; ct++) { + uint32_t i = io->loadU32(); + cv->mAllocations[ct] = (Allocation *)mIndex[i].mRsObj; + } + ie->mRsObj = cv; +} + +void FileA3D::processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie) +{ + LOGE("processChunk_Element ie %p", 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); + } + 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(); + + 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(); + data++; + } + ie->mRsObj = alloc; +} + +namespace android { +namespace renderscript { + + +RsFile rsi_FileOpen(Context *rsc, char const *path, unsigned int len) +{ + FileA3D *fa3d = new FileA3D; + + FILE *f = fopen("/sdcard/test.a3d", "rb"); + if (f) { + fa3d->load(rsc, f); + fclose(f); + return fa3d; + } + delete fa3d; + return NULL; +} + + +} +} diff --git a/rsFileA3D.h b/rsFileA3D.h new file mode 100644 index 00000000..9ee08ec4 --- /dev/null +++ b/rsFileA3D.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_RS_FILE_A3D_H +#define ANDROID_RS_FILE_A3D_H + +#include "RenderScript.h" +#include "rsFileA3DDecls.h" +#include "rsMesh.h" + +#include <utils/String8.h> +#include <stdio.h> + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + +class FileA3D +{ +public: + FileA3D(); + ~FileA3D(); + + uint32_t mMajorVersion; + uint32_t mMinorVersion; + uint64_t mIndexOffset; + uint64_t mStringTableOffset; + bool mUse64BitOffsets; + + struct A3DIndexEntry { + String8 mID; + A3DChunkType mType; + uint64_t mOffset; + void * mRsObj; + }; + + bool load(Context *rsc, FILE *f); + +protected: + class IO + { + public: + IO(const uint8_t *, bool use64); + + float loadF() { + mPos = (mPos + 3) & (~3); + float tmp = reinterpret_cast<const float *>(&mData[mPos])[0]; + mPos += sizeof(float); + return tmp; + } + int32_t loadI32() { + mPos = (mPos + 3) & (~3); + int32_t tmp = reinterpret_cast<const int32_t *>(&mData[mPos])[0]; + mPos += sizeof(int32_t); + return tmp; + } + uint32_t loadU32() { + mPos = (mPos + 3) & (~3); + uint32_t tmp = reinterpret_cast<const uint32_t *>(&mData[mPos])[0]; + mPos += sizeof(uint32_t); + return tmp; + } + uint16_t loadU16() { + mPos = (mPos + 1) & (~1); + uint16_t tmp = reinterpret_cast<const uint16_t *>(&mData[mPos])[0]; + mPos += sizeof(uint16_t); + return tmp; + } + uint8_t loadU8() { + uint8_t tmp = reinterpret_cast<const uint8_t *>(&mData[mPos])[0]; + mPos += sizeof(uint8_t); + return tmp; + } + uint64_t loadOffset(); + void loadString(String8 *s); + uint64_t getPos() const {return mPos;} + const uint8_t * getPtr() const; + protected: + const uint8_t * mData; + uint64_t mPos; + bool mUse64; + }; + + + bool process(Context *rsc); + bool processIndex(Context *rsc, A3DIndexEntry *); + void processChunk_Mesh(Context *rsc, IO *io, A3DIndexEntry *ie); + void processChunk_Primitive(Context *rsc, IO *io, A3DIndexEntry *ie); + void processChunk_Verticies(Context *rsc, IO *io, A3DIndexEntry *ie); + void processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie); + void processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie); + + const uint8_t * mData; + void * mAlloc; + uint64_t mDataSize; + Context * mRsc; + + Vector<A3DIndexEntry> mIndex; + Vector<String8> mStrings; + Vector<uint32_t> mStringIndexValues; + +}; + + +} +} +#endif //ANDROID_RS_FILE_A3D_H + + diff --git a/rsFileA3DDecls.h b/rsFileA3DDecls.h new file mode 100644 index 00000000..2a08bd36 --- /dev/null +++ b/rsFileA3DDecls.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_RS_FILE_A3D_DECLS_H +#define ANDROID_RS_FILE_A3D_DECLS_H + + +#define A3D_MAGIC_KEY "Android3D_ff" + +namespace android { +namespace renderscript { + + enum A3DChunkType { + CHUNK_EMPTY, + + CHUNK_ELEMENT, + CHUNK_ELEMENT_SOURCE, + CHUNK_VERTICIES, + CHUNK_MESH, + CHUNK_PRIMITIVE, + + CHUNK_LAST + }; + + +} +} +#endif //ANDROID_RS_FILE_A3D_H + + + @@ -24,9 +24,10 @@ using namespace android::renderscript; Mesh::Mesh() { - mSources = NULL; + mVerticies = NULL; + mVerticiesCount = 0; mPrimitives = NULL; - mPrimitiveCount = 0; + mPrimitivesCount = 0; } Mesh::~Mesh() @@ -32,10 +32,11 @@ public: Mesh(); ~Mesh(); - struct VertexSource_t + struct Verticies_t { - const Element * mVertexElement; - void * mVertexData; + Allocation ** mAllocations; + uint32_t mAllocationCount; + size_t mVertexDataSize; size_t mOffsetCoord; @@ -52,16 +53,19 @@ public: struct Primitive_t { RsPrimitive mType; - const Element * mIndexElement; - void * mVertexData; - size_t mIndexDataSize; + Verticies_t *mVerticies; - uint32_t mBufferObject; + uint32_t mIndexCount; + uint16_t *mIndicies; }; - VertexSource_t * mSources; - Primitive_t * mPrimitives; - uint32_t mPrimitiveCount; + Verticies_t * mVerticies; + uint32_t mVerticiesCount; + + Primitive_t ** mPrimitives; + uint32_t mPrimitivesCount; + + void analyzeElement(); protected: |
