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/Android.mk b/Android.mk
index 0f8de2b..3f01415 100644
--- a/Android.mk
+++ b/Android.mk
@@ -102,6 +102,7 @@
     rsShaderCache.cpp \
 	rsSignal.cpp \
 	rsSimpleMesh.cpp \
+    rsStream.cpp \
 	rsThreadIO.cpp \
 	rsType.cpp \
 	rsVertexArray.cpp
diff --git a/rsAdapter.cpp b/rsAdapter.cpp
index 0d31fac..b4ec250 100644
--- a/rsAdapter.cpp
+++ b/rsAdapter.cpp
@@ -15,7 +15,11 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
+#else
+#include "rsContextHostStub.h"
+#endif
 
 using namespace android;
 using namespace android::renderscript;
@@ -70,6 +74,16 @@
            mAllocation.get()->getType()->getSizeBytes());
 }
 
+void Adapter1D::serialize(OStream *stream) const
+{
+    
+}
+
+Adapter1D *Adapter1D::createFromStream(Context *rsc, IStream *stream)
+{
+    return NULL;
+}
+
 namespace android {
 namespace renderscript {
 
@@ -185,6 +199,15 @@
            mAllocation.get()->getType()->getSizeBytes());
 }
 
+void Adapter2D::serialize(OStream *stream) const
+{
+    
+}
+
+Adapter2D *Adapter2D::createFromStream(Context *rsc, IStream *stream)
+{
+    return NULL;
+}
 
 
 namespace android {
diff --git a/rsAdapter.h b/rsAdapter.h
index cb2872e..937ef50 100644
--- a/rsAdapter.h
+++ b/rsAdapter.h
@@ -49,6 +49,10 @@
 
     void subData(uint32_t xoff, uint32_t count, const void *data);
     void data(const void *data);
+    
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_ADAPTER_1D; }
+    static Adapter1D *createFromStream(Context *rsc, IStream *stream);
 
 protected:
     ObjectBaseRef<Allocation> mAllocation;
@@ -81,6 +85,10 @@
 
     void data(const void *data);
     void subData(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data);
+    
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_ADAPTER_2D; }
+    static Adapter2D *createFromStream(Context *rsc, IStream *stream);
 
 protected:
     ObjectBaseRef<Allocation> mAllocation;
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index e5ff1d7..4db6a04 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -13,12 +13,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
 
 #include <GLES/gl.h>
 #include <GLES2/gl2.h>
 #include <GLES/glext.h>
+#else
+#include "rsContextHostStub.h"
+
+#include <OpenGL/gl.h>
+#include <OpenGl/glext.h>
+#endif
 
 using namespace android;
 using namespace android::renderscript;
@@ -167,7 +173,9 @@
                      0, format, type, ptr);
     }
     if (mTextureGenMipmap) {
+#ifndef ANDROID_RS_BUILD_FOR_HOST
         glGenerateMipmap(GL_TEXTURE_2D);
+#endif //ANDROID_RS_BUILD_FOR_HOST
     }
 
     rsc->checkError("Allocation::uploadToTexture");
@@ -286,7 +294,7 @@
 
 void Allocation::addProgramToDirty(const Program *p)
 {
-    mToDirtyList.add(p);
+    mToDirtyList.push(p);
 }
 
 void Allocation::removeProgramToDirty(const Program *p)
@@ -318,6 +326,60 @@
 
 }
 
+void Allocation::serialize(OStream *stream) const
+{
+    // Need to identify ourselves
+    stream->addU32((uint32_t)getClassId());
+
+    String8 name(getName());
+    stream->addString(&name);
+
+    // First thing we need to serialize is the type object since it will be needed
+    // to initialize the class
+    mType->serialize(stream);
+
+    uint32_t dataSize = mType->getSizeBytes();
+    // Write how much data we are storing
+    stream->addU32(dataSize);
+    // Now write the data
+    stream->addByteArray(mPtr, dataSize);
+}
+
+Allocation *Allocation::createFromStream(Context *rsc, IStream *stream)
+{
+    // First make sure we are reading the correct object
+    A3DClassID classID = (A3DClassID)stream->loadU32();
+    if(classID != A3D_CLASS_ID_ALLOCATION) {
+        LOGE("allocation loading skipped due to invalid class id\n");
+        return NULL;
+    }
+
+    String8 name;
+    stream->loadString(&name);
+
+    Type *type = Type::createFromStream(rsc, stream);
+    if(!type) {
+        return NULL;
+    }
+    type->compute();
+
+    // Number of bytes we wrote out for this allocation
+    uint32_t dataSize = stream->loadU32();
+    if(dataSize != type->getSizeBytes()) {
+        LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
+        delete type;
+        return NULL;
+    }
+
+    Allocation *alloc = new Allocation(rsc, type);
+    alloc->setName(name.string(), name.size());
+
+    // Read in all of our allocation data
+    stream->loadByteArray(alloc->getPtr(), dataSize);
+
+    return alloc;
+}
+
 void Allocation::sendDirty() const
 {
     for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
@@ -514,6 +576,8 @@
     return 0;
 }
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
+
 RsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype,
                                            void *bmp, void *callbackData, RsBitmapCallback_t callback)
 {
@@ -615,6 +679,7 @@
     a->read(data);
 }
 
+#endif //ANDROID_RS_BUILD_FOR_HOST
 
 }
 }
diff --git a/rsAllocation.h b/rsAllocation.h
index 516f8b7..84a7c85 100644
--- a/rsAllocation.h
+++ b/rsAllocation.h
@@ -72,6 +72,9 @@
     void removeProgramToDirty(const Program *);
 
     virtual void dumpLOGV(const char *prefix) const;
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_ALLOCATION; }
+    static Allocation *createFromStream(Context *rsc, IStream *stream);
 
     virtual void uploadCheck(const Context *rsc);
 
diff --git a/rsAnimation.cpp b/rsAnimation.cpp
index 48c9334..6200715 100644
--- a/rsAnimation.cpp
+++ b/rsAnimation.cpp
@@ -14,13 +14,28 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
+#else
+#include "rsContextHostStub.h"
+#endif //ANDROID_RS_BUILD_FOR_HOST
+
 #include "rsAnimation.h"
 
 
 using namespace android;
 using namespace android::renderscript;
 
+void Animation::serialize(OStream *stream) const
+{
+    
+}
+
+Animation *Animation::createFromStream(Context *rsc, IStream *stream)
+{
+    return NULL;
+}
+
 /*
 Animation::Animation(Context *rsc) : ObjectBase(rsc)
 {
diff --git a/rsAnimation.h b/rsAnimation.h
index b8db661..ed92c1a 100644
--- a/rsAnimation.h
+++ b/rsAnimation.h
@@ -36,7 +36,10 @@
                               RsAnimationEdge pre, RsAnimationEdge post);
 
     float eval(float) const;
-
+    
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_ANIMATION; }
+    static Animation *createFromStream(Context *rsc, IStream *stream);
 
 protected:
     Animation(Context *rsc);
diff --git a/rsComponent.cpp b/rsComponent.cpp
index 15a56f7..b120c21 100644
--- a/rsComponent.cpp
+++ b/rsComponent.cpp
@@ -16,7 +16,11 @@
 
 #include "rsComponent.h"
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include <GLES/gl.h>
+#else
+#include <OpenGL/gl.h>
+#endif
 
 using namespace android;
 using namespace android::renderscript;
@@ -334,4 +338,25 @@
          prefix, gTypeStrings[mType], gKindStrings[mKind], mVectorSize, mBits);
 }
 
+void Component::serialize(OStream *stream) const
+{
+    stream->addU8((uint8_t)mType);
+    stream->addU8((uint8_t)mKind);
+    stream->addU8((uint8_t)(mNormalized ? 1 : 0));
+    stream->addU32(mVectorSize);
+}
+
+void Component::loadFromStream(IStream *stream)
+{
+    mType = (RsDataType)stream->loadU8();
+    mKind = (RsDataKind)stream->loadU8();
+    uint8_t temp = stream->loadU8();
+    mNormalized = temp != 0;
+    mVectorSize = stream->loadU32();
+
+    set(mType, mKind, mNormalized, mVectorSize);
+}
+
+
+
 
diff --git a/rsComponent.h b/rsComponent.h
index 71de324..0f93a91 100644
--- a/rsComponent.h
+++ b/rsComponent.h
@@ -48,6 +48,10 @@
     bool getIsSigned() const {return mIsSigned;}
     uint32_t getBits() const {return mBits;}
 
+    // Helpers for reading / writing this class out
+    void serialize(OStream *stream) const;
+    void loadFromStream(IStream *stream);
+
 protected:
     RsDataType mType;
     RsDataKind mKind;
diff --git a/rsContextHostStub.h b/rsContextHostStub.h
new file mode 100644
index 0000000..be1fff6
--- /dev/null
+++ b/rsContextHostStub.h
@@ -0,0 +1,153 @@
+/*
+ * 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_CONTEXT_HOST_STUB_H
+#define ANDROID_RS_CONTEXT_HOST_STUB_H
+
+#include "rsUtils.h"
+//#include "rsMutex.h"
+
+//#include "rsThreadIO.h"
+#include "rsType.h"
+#include "rsMatrix.h"
+#include "rsAllocation.h"
+#include "rsSimpleMesh.h"
+#include "rsMesh.h"
+//#include "rsDevice.h"
+#include "rsScriptC.h"
+#include "rsAllocation.h"
+#include "rsAdapter.h"
+#include "rsSampler.h"
+#include "rsLight.h"
+#include "rsProgramFragment.h"
+#include "rsProgramStore.h"
+#include "rsProgramRaster.h"
+#include "rsProgramVertex.h"
+#include "rsShaderCache.h"
+#include "rsVertexArray.h"
+
+//#include "rsgApiStructs.h"
+//#include "rsLocklessFifo.h"
+
+//#include <ui/egl/android_natives.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+namespace renderscript {
+
+class Device;
+
+class Context
+{
+public:
+    Context(Device *, bool isGraphics, bool useDepth) {
+        mObjHead = NULL;
+    }
+    ~Context() {
+    }
+
+
+    //StructuredAllocationContext mStateAllocation;
+    ElementState mStateElement;
+    TypeState mStateType;
+    SamplerState mStateSampler;
+    //ProgramFragmentState mStateFragment;
+    ProgramStoreState mStateFragmentStore;
+    //ProgramRasterState mStateRaster;
+    //ProgramVertexState mStateVertex;
+    LightState mStateLight;
+    VertexArrayState mStateVertexArray;
+
+    //ScriptCState mScriptC;
+    ShaderCache mShaderCache;
+
+
+    //bool setupCheck();
+    bool checkDriver() const {return false;}
+
+    ProgramFragment * getDefaultProgramFragment() const {
+        return NULL;
+    }
+    ProgramVertex * getDefaultProgramVertex() const {
+        return NULL;
+    }
+    ProgramStore * getDefaultProgramStore() const {
+        return NULL;
+    }
+    ProgramRaster * getDefaultProgramRaster() const {
+        return NULL;
+    }
+
+    uint32_t getWidth() const {return 0;}
+    uint32_t getHeight() const {return 0;}
+
+    // Timers
+    enum Timers {
+        RS_TIMER_IDLE,
+        RS_TIMER_INTERNAL,
+        RS_TIMER_SCRIPT,
+        RS_TIMER_CLEAR_SWAP,
+        _RS_TIMER_TOTAL
+    };
+
+    bool checkVersion1_1() const {return false; }
+    bool checkVersion2_0() const {return false; }
+
+    struct {
+        bool mLogTimes;
+        bool mLogScripts;
+        bool mLogObjects;
+        bool mLogShaders;
+    } props;
+
+    void dumpDebug() const {    }
+    void checkError(const char *) const {  };
+    void setError(RsError e, const char *msg = NULL) {  }
+
+    mutable const ObjectBase * mObjHead;
+
+    bool ext_OES_texture_npot() const {return mGL.OES_texture_npot;}
+
+protected:
+
+    struct {
+        const uint8_t * mVendor;
+        const uint8_t * mRenderer;
+        const uint8_t * mVersion;
+        const uint8_t * mExtensions;
+
+        uint32_t mMajorVersion;
+        uint32_t mMinorVersion;
+
+        int32_t mMaxVaryingVectors;
+        int32_t mMaxTextureImageUnits;
+
+        int32_t mMaxFragmentTextureImageUnits;
+        int32_t mMaxFragmentUniformVectors;
+
+        int32_t mMaxVertexAttribs;
+        int32_t mMaxVertexUniformVectors;
+        int32_t mMaxVertexTextureUnits;
+
+        bool OES_texture_npot;
+    } mGL;
+
+};
+
+}
+}
+#endif
diff --git a/rsDevice.cpp b/rsDevice.cpp
index b670ad4..a96b114 100644
--- a/rsDevice.cpp
+++ b/rsDevice.cpp
@@ -15,7 +15,11 @@
  */
 
 #include "rsDevice.h"
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
+#else
+#include "rsContextHostStub.h"
+#endif
 
 using namespace android;
 using namespace android::renderscript;
@@ -33,7 +37,7 @@
 
 void Device::addContext(Context *rsc)
 {
-    mContexts.add(rsc);
+    mContexts.push(rsc);
 }
 
 void Device::removeContext(Context *rsc)
diff --git a/rsElement.cpp b/rsElement.cpp
index 6288bc4..3b18c98 100644
--- a/rsElement.cpp
+++ b/rsElement.cpp
@@ -14,9 +14,14 @@
  * limitations under the License.
  */
 
-#include "rsContext.h"
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
+#include "rsContext.h"
 #include <GLES/gl.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#endif
 
 using namespace android;
 using namespace android::renderscript;
@@ -83,6 +88,90 @@
     }
 }
 
+void Element::serialize(OStream *stream) const
+{
+    // Need to identify ourselves
+    stream->addU32((uint32_t)getClassId());
+
+    String8 name(getName());
+    stream->addString(&name);
+
+    mComponent.serialize(stream);
+
+    // Now serialize all the fields
+    stream->addU32(mFieldCount);
+    for(uint32_t ct = 0; ct < mFieldCount; ct++) {
+        stream->addString(&mFields[ct].name);
+        mFields[ct].e->serialize(stream);
+    }
+}
+
+Element *Element::createFromStream(Context *rsc, IStream *stream)
+{
+    // First make sure we are reading the correct object
+    A3DClassID classID = (A3DClassID)stream->loadU32();
+    if(classID != A3D_CLASS_ID_ELEMENT) {
+        LOGE("element loading skipped due to invalid class id\n");
+        return NULL;
+    }
+
+    String8 name;
+    stream->loadString(&name);
+
+    Element *elem = new Element(rsc);
+    elem->mComponent.loadFromStream(stream);
+    elem->mBits = elem->mComponent.getBits();
+
+    elem->mFieldCount = stream->loadU32();
+    if(elem->mFieldCount) {
+        elem->mFields = new ElementField_t [elem->mFieldCount];
+        for(uint32_t ct = 0; ct < elem->mFieldCount; ct ++) {
+            stream->loadString(&elem->mFields[ct].name);
+            Element *fieldElem = Element::createFromStream(rsc, stream);
+            elem->mFields[ct].e.set(fieldElem);
+        }
+    }
+
+    // We need to check if this already exists
+    for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
+        Element *ee = rsc->mStateElement.mElements[ct];
+
+        if (!ee->getFieldCount() ) {
+
+            if((ee->getComponent().getType() == elem->getComponent().getType()) &&
+               (ee->getComponent().getKind() == elem->getComponent().getKind()) &&
+               (ee->getComponent().getIsNormalized() == elem->getComponent().getIsNormalized()) &&
+               (ee->getComponent().getVectorSize() == elem->getComponent().getVectorSize())) {
+                // Match
+                delete elem;
+                ee->incUserRef();
+                return ee;
+            }
+
+        } else if (ee->getFieldCount() == elem->mFieldCount) {
+
+            bool match = true;
+            for (uint32_t i=0; i < elem->mFieldCount; i++) {
+                if ((ee->mFields[i].e.get() != elem->mFields[i].e.get()) ||
+                    (ee->mFields[i].name.length() != elem->mFields[i].name.length()) ||
+                    (ee->mFields[i].name != elem->mFields[i].name)) {
+                    match = false;
+                    break;
+                }
+            }
+            if (match) {
+                delete elem;
+                ee->incUserRef();
+                return ee;
+            }
+
+        }
+    }
+
+    rsc->mStateElement.mElements.push(elem);
+    return elem;
+}
+
 
 const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
                             bool isNorm, uint32_t vecSize)
diff --git a/rsElement.h b/rsElement.h
index 02a1ca2..a302553 100644
--- a/rsElement.h
+++ b/rsElement.h
@@ -59,6 +59,9 @@
     String8 getGLSLType(uint32_t indent=0) const;
 
     void dumpLOGV(const char *prefix) const;
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_ELEMENT; }
+    static Element *createFromStream(Context *rsc, IStream *stream);
 
     static const Element * create(Context *rsc, RsDataType dt, RsDataKind dk,
                             bool isNorm, uint32_t vecSize);
@@ -90,7 +93,7 @@
     ~ElementState();
 
     // Cache of all existing elements.
-    Vector<const Element *> mElements;
+    Vector<Element *> mElements;
 };
 
 
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 {
diff --git a/rsFileA3D.h b/rsFileA3D.h
index 9ee08ec..e744291 100644
--- a/rsFileA3D.h
+++ b/rsFileA3D.h
@@ -22,6 +22,7 @@
 #include "rsMesh.h"
 
 #include <utils/String8.h>
+#include "rsStream.h"
 #include <stdio.h>
 
 // ---------------------------------------------------------------------------
@@ -42,76 +43,31 @@
 
     struct A3DIndexEntry {
         String8 mID;
-        A3DChunkType mType;
+        A3DClassID mType;
         uint64_t mOffset;
         void * mRsObj;
     };
 
     bool load(Context *rsc, FILE *f);
+    size_t getNumLoadedEntries() const;
+    const A3DIndexEntry* getLoadedEntry(size_t index) const;
+    ObjectBase *initializeFromEntry(const A3DIndexEntry *entry);
+
+    void appendToFile(ObjectBase *obj);
+    bool writeFile(const char *filename);
 
 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;
+    OStream *mWriteStream;
+    Vector<A3DIndexEntry*> mWriteIndex;
 
+    IStream *mReadStream;
+    Vector<A3DIndexEntry*> mIndex;
 };
 
 
diff --git a/rsFileA3DDecls.h b/rsFileA3DDecls.h
index 2a08bd3..b752442 100644
--- a/rsFileA3DDecls.h
+++ b/rsFileA3DDecls.h
@@ -23,16 +23,23 @@
 namespace android {
 namespace renderscript {
 
-    enum A3DChunkType {
-        CHUNK_EMPTY,
-
-        CHUNK_ELEMENT,
-        CHUNK_ELEMENT_SOURCE,
-        CHUNK_VERTICIES,
-        CHUNK_MESH,
-        CHUNK_PRIMITIVE,
-
-        CHUNK_LAST
+    enum A3DClassID {
+        A3D_CLASS_ID_UNKNOWN,
+        A3D_CLASS_ID_MESH,
+        A3D_CLASS_ID_SIMPLE_MESH,
+        A3D_CLASS_ID_TYPE,
+        A3D_CLASS_ID_ELEMENT,
+        A3D_CLASS_ID_ALLOCATION,
+        A3D_CLASS_ID_PROGRAM_VERTEX,
+        A3D_CLASS_ID_PROGRAM_RASTER,
+        A3D_CLASS_ID_PROGRAM_FRAGMENT,
+        A3D_CLASS_ID_PROGRAM_STORE,
+        A3D_CLASS_ID_SAMPLER,
+        A3D_CLASS_ID_ANIMATION,
+        A3D_CLASS_ID_LIGHT,
+        A3D_CLASS_ID_ADAPTER_1D,
+        A3D_CLASS_ID_ADAPTER_2D,
+        A3D_CLASS_ID_SCRIPT_C
     };
 
 
diff --git a/rsLight.cpp b/rsLight.cpp
index 6f2cf3e..eab9a07 100644
--- a/rsLight.cpp
+++ b/rsLight.cpp
@@ -14,9 +14,13 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-
 #include <GLES/gl.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#endif //ANDROID_RS_BUILD_FOR_HOST
 
 using namespace android;
 using namespace android::renderscript;
@@ -65,6 +69,16 @@
     glLightfv(GL_LIGHT0 + num, GL_POSITION, mPosition);
 }
 
+void Light::serialize(OStream *stream) const
+{
+    
+}
+
+Light *Light::createFromStream(Context *rsc, IStream *stream)
+{
+    return NULL;
+}
+
 ////////////////////////////////////////////
 
 LightState::LightState()
diff --git a/rsLight.h b/rsLight.h
index d8796e6..4216052 100644
--- a/rsLight.h
+++ b/rsLight.h
@@ -37,6 +37,9 @@
     void setColor(float r, float g, float b);
 
     void setupGL(uint32_t num) const;
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_LIGHT; }
+    static Light *createFromStream(Context *rsc, IStream *stream);
 
 protected:
     float mColor[4];
diff --git a/rsMesh.cpp b/rsMesh.cpp
index d595b4e..b51e28a 100644
--- a/rsMesh.cpp
+++ b/rsMesh.cpp
@@ -14,14 +14,23 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
 
+#include <GLES/gl.h>
+#include <GLES2/gl2.h>
+#include <GLES/glext.h>
+#else
+#include "rsContextHostStub.h"
+
+#include <OpenGL/gl.h>
+#include <OpenGl/glext.h>
+#endif
+
+
 using namespace android;
 using namespace android::renderscript;
 
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
 Mesh::Mesh(Context *rsc) : ObjectBase(rsc)
 {
     mAllocFile = __FILE__;
@@ -36,6 +45,162 @@
 {
 }
 
+void Mesh::serialize(OStream *stream) const
+{
+    // Need to identify ourselves
+    stream->addU32((uint32_t)getClassId());
+
+    String8 name(getName());
+    stream->addString(&name);
+
+    stream->addU32(mVerticiesCount);
+
+    for(uint32_t vCount = 0; vCount < mVerticiesCount; vCount ++) {
+        Verticies_t *verts = mVerticies[vCount];
+
+        stream->addU32(verts->mAllocationCount);
+
+        for (uint32_t aCount = 0; aCount < verts->mAllocationCount; aCount++) {
+            verts->mAllocations[aCount]->serialize(stream);
+        }
+        stream->addU32(verts->mVertexDataSize);
+
+        stream->addU32(verts->mOffsetCoord);
+        stream->addU32(verts->mOffsetTex);
+        stream->addU32(verts->mOffsetNorm);
+
+        stream->addU32(verts->mSizeCoord);
+        stream->addU32(verts->mSizeTex);
+        stream->addU32(verts->mSizeNorm );
+    }
+
+    stream->addU32(mPrimitivesCount);
+    // Store the primitives
+    for (uint32_t pCount = 0; pCount < mPrimitivesCount; pCount ++) {
+        Primitive_t * prim = mPrimitives[pCount];
+
+        stream->addU8((uint8_t)prim->mType);
+
+        // We store the index to the vertices
+        // So iterate over our vertices to find which one we point to
+        uint32_t vertexIndex = 0;
+        for(uint32_t vCount = 0; vCount < mVerticiesCount; vCount ++) {
+            if(prim->mVerticies == mVerticies[vCount]) {
+                vertexIndex = vCount;
+                break;
+            }
+        }
+        stream->addU32(vertexIndex);
+
+        stream->addU32(prim->mIndexCount);
+        for (uint32_t ct = 0; ct < prim->mIndexCount; ct++) {
+            stream->addU16(prim->mIndicies[ct]);
+        }
+
+        stream->addU32(prim->mRestartCounts);
+        for (uint32_t ct = 0; ct < prim->mRestartCounts; ct++) {
+            stream->addU16(prim->mRestarts[ct]);
+        }
+    }
+}
+
+Mesh *Mesh::createFromStream(Context *rsc, IStream *stream)
+{
+    // First make sure we are reading the correct object
+    A3DClassID classID = (A3DClassID)stream->loadU32();
+    if(classID != A3D_CLASS_ID_MESH) {
+        LOGE("mesh loading skipped due to invalid class id");
+        return NULL;
+    }
+
+    Mesh * mesh = new Mesh(rsc);
+
+    String8 name;
+    stream->loadString(&name);
+    mesh->setName(name.string(), name.size());
+
+    mesh->mVerticiesCount = stream->loadU32();
+    if(mesh->mVerticiesCount) {
+        mesh->mVerticies = new Verticies_t *[mesh->mVerticiesCount];
+    }
+    else {
+        mesh->mVerticies = NULL;
+    }
+
+    for(uint32_t vCount = 0; vCount < mesh->mVerticiesCount; vCount ++) {
+        Verticies_t *verts = new Verticies_t();
+        // Store our vertices one the mesh
+        mesh->mVerticies[vCount] = verts;
+
+        verts->mAllocationCount = stream->loadU32();
+        verts->mAllocations = new Allocation *[verts->mAllocationCount];
+
+        LOGE("processChunk_Verticies count %i", verts->mAllocationCount);
+        for (uint32_t aCount = 0; aCount < verts->mAllocationCount; aCount++) {
+            verts->mAllocations[aCount] = Allocation::createFromStream(rsc, stream);
+        }
+        verts->mVertexDataSize = stream->loadU32();
+
+        verts->mOffsetCoord = stream->loadU32();
+        verts->mOffsetTex = stream->loadU32();
+        verts->mOffsetNorm = stream->loadU32();
+
+        verts->mSizeCoord = stream->loadU32();
+        verts->mSizeTex = stream->loadU32();
+        verts->mSizeNorm = stream->loadU32();
+    }
+
+    mesh->mPrimitivesCount = stream->loadU32();
+    if(mesh->mPrimitivesCount) {
+        mesh->mPrimitives = new Primitive_t *[mesh->mPrimitivesCount];
+    }
+    else {
+        mesh->mPrimitives = NULL;
+    }
+
+    // load all primitives
+    for (uint32_t pCount = 0; pCount < mesh->mPrimitivesCount; pCount ++) {
+        Primitive_t * prim = new Primitive_t;
+        mesh->mPrimitives[pCount] = prim;
+
+        prim->mType = (RsPrimitive)stream->loadU8();
+
+        // We store the index to the vertices
+        uint32_t vertexIndex = stream->loadU32();
+        if(vertexIndex < mesh->mVerticiesCount) {
+            prim->mVerticies = mesh->mVerticies[vertexIndex];
+        }
+        else {
+            prim->mVerticies = NULL;
+        }
+
+        prim->mIndexCount = stream->loadU32();
+        if(prim->mIndexCount){
+            prim->mIndicies = new uint16_t[prim->mIndexCount];
+            for (uint32_t ct = 0; ct < prim->mIndexCount; ct++) {
+                prim->mIndicies[ct] = stream->loadU16();
+            }
+        }
+        else {
+            prim->mIndicies = NULL;
+        }
+
+        prim->mRestartCounts = stream->loadU32();
+        if (prim->mRestartCounts) {
+            prim->mRestarts = new uint16_t[prim->mRestartCounts];
+            for (uint32_t ct = 0; ct < prim->mRestartCounts; ct++) {
+                prim->mRestarts[ct] = stream->loadU16();
+
+            }
+        }
+        else {
+            prim->mRestarts = NULL;
+        }
+
+    }
+
+    return mesh;
+}
 
 
 MeshContext::MeshContext()
diff --git a/rsMesh.h b/rsMesh.h
index 5201abd..e3edf52 100644
--- a/rsMesh.h
+++ b/rsMesh.h
@@ -62,15 +62,17 @@
         uint16_t *mRestarts;
     };
 
-    Verticies_t * mVerticies;
+    Verticies_t ** mVerticies;
     uint32_t mVerticiesCount;
 
     Primitive_t ** mPrimitives;
     uint32_t mPrimitivesCount;
 
-
-
     void analyzeElement();
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_MESH; }
+    static Mesh *createFromStream(Context *rsc, IStream *stream);
+    
 protected:
 };
 
diff --git a/rsObjectBase.cpp b/rsObjectBase.cpp
index 677413e..48f1fee 100644
--- a/rsObjectBase.cpp
+++ b/rsObjectBase.cpp
@@ -15,7 +15,12 @@
  */
 
 #include "rsObjectBase.h"
+
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
+#else
+#include "rsContextHostStub.h"
+#endif
 
 using namespace android;
 using namespace android::renderscript;
@@ -24,7 +29,6 @@
 {
     mUserRefCount = 0;
     mSysRefCount = 0;
-    mName = NULL;
     mRSC = NULL;
     mNext = NULL;
     mPrev = NULL;
@@ -39,14 +43,13 @@
     rsAssert(!mUserRefCount);
     rsAssert(!mSysRefCount);
     remove();
-    delete[] mName;
 }
 
 void ObjectBase::dumpLOGV(const char *op) const
 {
-    if (mName) {
+    if (mName.size()) {
         LOGV("%s RSobj %p, name %s, refs %i,%i  from %s,%i links %p,%p,%p",
-             op, this, mName, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
+             op, this, mName.string(), mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
     } else {
         LOGV("%s RSobj %p, no-name, refs %i,%i  from %s,%i links %p,%p,%p",
              op, this, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
@@ -113,18 +116,12 @@
 
 void ObjectBase::setName(const char *name)
 {
-    setName(name, strlen(name));
+    mName.setTo(name);
 }
 
 void ObjectBase::setName(const char *name, uint32_t len)
 {
-    delete mName;
-    mName = NULL;
-    if (name) {
-        mName = new char[len + 1];
-        memcpy(mName, name, len);
-        mName[len] = 0;
-    }
+    mName.setTo(name, len);
 }
 
 void ObjectBase::add() const
diff --git a/rsObjectBase.h b/rsObjectBase.h
index bb03b87..f423232 100644
--- a/rsObjectBase.h
+++ b/rsObjectBase.h
@@ -24,6 +24,7 @@
 namespace renderscript {
 
 class Context;
+class OStream;
 
 // An element is a group of Components that occupies one cell in a structure.
 class ObjectBase
@@ -40,7 +41,7 @@
     bool zeroUserRef() const;
 
     const char * getName() const {
-        return mName;
+        return mName.string();
     }
     void setName(const char *);
     void setName(const char *, uint32_t len);
@@ -52,6 +53,8 @@
     static void dumpAll(Context *rsc);
 
     virtual void dumpLOGV(const char *prefix) const;
+    virtual void serialize(OStream *stream) const = 0;
+    virtual A3DClassID getClassId() const = 0;
 
 protected:
     const char *mAllocFile;
@@ -64,7 +67,7 @@
 
     bool checkDelete() const;
 
-    char * mName;
+    String8 mName;
     mutable int32_t mSysRefCount;
     mutable int32_t mUserRefCount;
 
diff --git a/rsProgram.cpp b/rsProgram.cpp
index 70e2868..c4f8b2e 100644
--- a/rsProgram.cpp
+++ b/rsProgram.cpp
@@ -14,11 +14,17 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include "rsProgram.h"
-
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#endif //ANDROID_RS_BUILD_FOR_HOST
+
+#include "rsProgram.h"
 
 using namespace android;
 using namespace android::renderscript;
diff --git a/rsProgramFragment.cpp b/rsProgramFragment.cpp
index c3fd5c5..8151f06 100644
--- a/rsProgramFragment.cpp
+++ b/rsProgramFragment.cpp
@@ -14,13 +14,19 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include "rsProgramFragment.h"
-
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#endif //ANDROID_RS_BUILD_FOR_HOST
+
+#include "rsProgramFragment.h"
 
 using namespace android;
 using namespace android::renderscript;
@@ -83,12 +89,15 @@
 
         glEnable(GL_TEXTURE_2D);
         if (rsc->checkVersion1_1()) {
+#ifndef ANDROID_RS_BUILD_FOR_HOST // These are GLES only
             if (mPointSpriteEnable) {
                 glEnable(GL_POINT_SPRITE_OES);
             } else {
                 glDisable(GL_POINT_SPRITE_OES);
             }
             glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
+#endif //ANDROID_RS_BUILD_FOR_HOST
+            
         }
         mTextures[ct]->uploadCheck(rsc);
         glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
@@ -289,6 +298,16 @@
     createShader();
 }
 
+void ProgramFragment::serialize(OStream *stream) const
+{
+    
+}
+
+ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream)
+{
+    return NULL;
+}
+
 ProgramFragmentState::ProgramFragmentState()
 {
     mPF = NULL;
diff --git a/rsProgramFragment.h b/rsProgramFragment.h
index db91524..68593b5 100644
--- a/rsProgramFragment.h
+++ b/rsProgramFragment.h
@@ -40,6 +40,9 @@
     virtual void createShader();
     virtual void loadShader(Context *rsc);
     virtual void init(Context *rsc);
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_PROGRAM_FRAGMENT; }
+    static ProgramFragment *createFromStream(Context *rsc, IStream *stream);
 
 protected:
     // Hacks to create a program for now
diff --git a/rsProgramRaster.cpp b/rsProgramRaster.cpp
index c095635..66f6ef8 100644
--- a/rsProgramRaster.cpp
+++ b/rsProgramRaster.cpp
@@ -14,11 +14,17 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include "rsProgramRaster.h"
-
 #include <GLES/gl.h>
 #include <GLES/glext.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#include <OpenGl/glext.h>
+#endif //ANDROID_RS_BUILD_FOR_HOST
+
+#include "rsProgramRaster.h"
 
 using namespace android;
 using namespace android::renderscript;
@@ -76,11 +82,13 @@
     }
 
     if (rsc->checkVersion1_1()) {
+#ifndef ANDROID_RS_BUILD_FOR_HOST
         if (mPointSprite) {
             glEnable(GL_POINT_SPRITE_OES);
         } else {
             glDisable(GL_POINT_SPRITE_OES);
         }
+#endif //ANDROID_RS_BUILD_FOR_HOST
     }
 }
 
@@ -92,7 +100,15 @@
     state->mLast.set(this);
 }
 
+void ProgramRaster::serialize(OStream *stream) const
+{
+    
+}
 
+ProgramRaster *ProgramRaster::createFromStream(Context *rsc, IStream *stream)
+{
+    return NULL;
+}
 
 ProgramRasterState::ProgramRasterState()
 {
diff --git a/rsProgramRaster.h b/rsProgramRaster.h
index 04eaaa8..477208c 100644
--- a/rsProgramRaster.h
+++ b/rsProgramRaster.h
@@ -36,6 +36,9 @@
 
     virtual void setupGL(const Context *, ProgramRasterState *);
     virtual void setupGL2(const Context *, ProgramRasterState *);
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_PROGRAM_RASTER; }
+    static ProgramRaster *createFromStream(Context *rsc, IStream *stream);
 
     void setLineWidth(float w);
     void setPointSize(float s);
diff --git a/rsProgramStore.cpp b/rsProgramStore.cpp
index ff70509..e741c0a 100644
--- a/rsProgramStore.cpp
+++ b/rsProgramStore.cpp
@@ -14,11 +14,17 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include "rsProgramStore.h"
-
 #include <GLES/gl.h>
 #include <GLES/glext.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#include <OpenGl/glext.h>
+#endif //ANDROID_RS_BUILD_FOR_HOST
+
+#include "rsProgramStore.h"
 
 using namespace android;
 using namespace android::renderscript;
@@ -126,6 +132,17 @@
     mDitherEnable = enable;
 }
 
+void ProgramStore::serialize(OStream *stream) const
+{
+
+}
+
+ProgramStore *ProgramStore::createFromStream(Context *rsc, IStream *stream)
+{
+    return NULL;
+}
+
+
 void ProgramStore::setDepthFunc(RsDepthFunc func)
 {
     mDepthTestEnable = true;
diff --git a/rsProgramStore.h b/rsProgramStore.h
index d686aa8..c6c312f 100644
--- a/rsProgramStore.h
+++ b/rsProgramStore.h
@@ -18,6 +18,7 @@
 #define ANDROID_RS_PROGRAM_FRAGMENT_STORE_H
 
 #include "rsProgram.h"
+#include "rsStream.h"
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -42,6 +43,10 @@
 
     void setDitherEnable(bool);
 
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_PROGRAM_STORE; }
+    static ProgramStore *createFromStream(Context *rsc, IStream *stream);
+
 protected:
     bool mDitherEnable;
 
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
index c3264ae..d4c29c8 100644
--- a/rsProgramVertex.cpp
+++ b/rsProgramVertex.cpp
@@ -14,13 +14,19 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include "rsProgramVertex.h"
-
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#endif //ANDROID_RS_BUILD_FOR_HOST
+
+#include "rsProgramVertex.h"
 
 using namespace android;
 using namespace android::renderscript;
@@ -81,9 +87,12 @@
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     if (mLightCount) {
+#ifndef ANDROID_RS_BUILD_FOR_HOST // GLES Only
         int v = 0;
         glEnable(GL_LIGHTING);
+
         glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v);
+
         for (uint32_t ct = 0; ct < mLightCount; ct++) {
             const Light *l = mLights[ct].get();
             glEnable(GL_LIGHT0 + ct);
@@ -92,6 +101,7 @@
         for (uint32_t ct = mLightCount; ct < MAX_LIGHTS; ct++) {
             glDisable(GL_LIGHT0 + ct);
         }
+#endif //ANDROID_RS_BUILD_FOR_HOST
     } else {
         glDisable(GL_LIGHTING);
     }
@@ -351,6 +361,16 @@
     createShader();
 }
 
+void ProgramVertex::serialize(OStream *stream) const
+{
+
+}
+
+ProgramVertex *ProgramVertex::createFromStream(Context *rsc, IStream *stream)
+{
+    return NULL;
+}
+
 
 ///////////////////////////////////////////////////////////////////////
 
@@ -364,6 +384,7 @@
 
 void ProgramVertexState::init(Context *rsc)
 {
+#ifndef ANDROID_RS_BUILD_FOR_HOST
     RsElement e = (RsElement) Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
 
     rsi_TypeBegin(rsc, e);
@@ -372,6 +393,7 @@
 
     ProgramVertex *pv = new ProgramVertex(rsc, false);
     Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get());
+
     mDefaultAlloc.set(alloc);
     mDefault.set(pv);
     pv->init(rsc);
@@ -383,6 +405,8 @@
     color[3] = 1.f;
 
     updateSize(rsc);
+#endif //ANDROID_RS_BUILD_FOR_HOST
+
 }
 
 void ProgramVertexState::updateSize(Context *rsc)
diff --git a/rsProgramVertex.h b/rsProgramVertex.h
index bdac978..734fabd 100644
--- a/rsProgramVertex.h
+++ b/rsProgramVertex.h
@@ -52,6 +52,9 @@
     virtual void loadShader(Context *);
     virtual void init(Context *);
 
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_PROGRAM_VERTEX; }
+    static ProgramVertex *createFromStream(Context *rsc, IStream *stream);
 
 protected:
     uint32_t mLightCount;
diff --git a/rsSampler.cpp b/rsSampler.cpp
index 71f508f..f41f295 100644
--- a/rsSampler.cpp
+++ b/rsSampler.cpp
@@ -14,10 +14,16 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include <GLES/gl.h>
 #include <GLES/glext.h>
-
 #include "rsContext.h"
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#endif //ANDROID_RS_BUILD_FOR_HOST
+
 #include "rsSampler.h"
 
 
@@ -94,6 +100,17 @@
     mBoundSlot = -1;
     ss->mSamplers[slot].clear();
 }
+
+void Sampler::serialize(OStream *stream) const
+{
+    
+}
+
+Sampler *Sampler::createFromStream(Context *rsc, IStream *stream)
+{
+    return NULL;
+}
+
 /*
 void SamplerState::setupGL()
 {
diff --git a/rsSampler.h b/rsSampler.h
index 0506081..1742111 100644
--- a/rsSampler.h
+++ b/rsSampler.h
@@ -45,6 +45,10 @@
 
     void bindToContext(SamplerState *, uint32_t slot);
     void unbindFromContext(SamplerState *);
+    
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_SAMPLER; }
+    static Sampler *createFromStream(Context *rsc, IStream *stream);
 
 protected:
     RsSamplerValue mMagFilter;
diff --git a/rsScriptC.h b/rsScriptC.h
index 1ee13e1..216c6f2 100644
--- a/rsScriptC.h
+++ b/rsScriptC.h
@@ -21,8 +21,6 @@
 
 #include "RenderScriptEnv.h"
 
-#include <utils/KeyedVector.h>
-
 struct BCCscript;
 
 // ---------------------------------------------------------------------------
@@ -61,6 +59,10 @@
 
     virtual void setupScript();
     virtual uint32_t run(Context *, uint32_t launchID);
+    
+    virtual void serialize(OStream *stream) const {    }
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_SCRIPT_C; }
+    static Type *createFromStream(Context *rsc, IStream *stream) { return NULL; }
 };
 
 class ScriptCState
diff --git a/rsShaderCache.cpp b/rsShaderCache.cpp
index 4711d1b..0218dc5 100644
--- a/rsShaderCache.cpp
+++ b/rsShaderCache.cpp
@@ -14,10 +14,14 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-
 #include <GLES/gl.h>
 #include <GLES2/gl2.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#endif //ANDROID_RS_BUILD_FOR_HOST
 
 using namespace android;
 using namespace android::renderscript;
diff --git a/rsSimpleMesh.cpp b/rsSimpleMesh.cpp
index 53ce5cd..170b792 100644
--- a/rsSimpleMesh.cpp
+++ b/rsSimpleMesh.cpp
@@ -14,13 +14,24 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
 
+#include <GLES/gl.h>
+#include <GLES2/gl2.h>
+#include <GLES/glext.h>
+#else
+#include "rsContextHostStub.h"
+
+#include <OpenGL/gl.h>
+#include <OpenGl/glext.h>
+#endif
+
 using namespace android;
 using namespace android::renderscript;
 
-#include <GLES/gl.h>
-#include <GLES/glext.h>
+
+
 
 SimpleMesh::SimpleMesh(Context *rsc) : ObjectBase(rsc)
 {
@@ -101,6 +112,95 @@
     rsc->checkError("SimpleMesh::uploadAll");
 }
 
+void SimpleMesh::updateGLPrimitive()
+{
+    switch(mPrimitive) {
+        case RS_PRIMITIVE_POINT:          mGLPrimitive = GL_POINTS; break;
+        case RS_PRIMITIVE_LINE:           mGLPrimitive = GL_LINES; break;
+        case RS_PRIMITIVE_LINE_STRIP:     mGLPrimitive = GL_LINE_STRIP; break;
+        case RS_PRIMITIVE_TRIANGLE:       mGLPrimitive = GL_TRIANGLES; break;
+        case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitive = GL_TRIANGLE_STRIP; break;
+        case RS_PRIMITIVE_TRIANGLE_FAN:   mGLPrimitive = GL_TRIANGLE_FAN; break;
+    }
+}
+
+void SimpleMesh::serialize(OStream *stream) const
+{
+    // Need to identify ourselves
+    stream->addU32((uint32_t)getClassId());
+
+    String8 name(getName());
+    stream->addString(&name);
+
+    // Add primitive type
+    stream->addU8((uint8_t)mPrimitive);
+
+    // And now serialize the allocations
+    mIndexBuffer->serialize(stream);
+
+    // We need to indicate if the primitive buffer is present
+    if(mPrimitiveBuffer.get() != NULL) {
+        // Write if the primitive buffer is present
+        stream->addU32(1);
+        mPrimitiveBuffer->serialize(stream);
+    }
+    else {
+        // No buffer present, will need this when we read
+        stream->addU32(0);
+    }
+
+    // Store number of vertex streams
+    stream->addU32(mVertexTypeCount);
+    for(uint32_t vCount = 0; vCount < mVertexTypeCount; vCount ++) {
+        mVertexBuffers[vCount]->serialize(stream);
+    }
+}
+
+SimpleMesh *SimpleMesh::createFromStream(Context *rsc, IStream *stream)
+{
+    // First make sure we are reading the correct object
+    A3DClassID classID = (A3DClassID)stream->loadU32();
+    if(classID != A3D_CLASS_ID_SIMPLE_MESH) {
+        LOGE("simple mesh loading skipped due to invalid class id");
+        return NULL;
+    }
+
+    SimpleMesh * mesh = new SimpleMesh(rsc);
+
+    String8 name;
+    stream->loadString(&name);
+    mesh->setName(name.string(), name.size());
+
+    mesh->mPrimitive = (RsPrimitive)stream->loadU8();
+    mesh->updateGLPrimitive();
+
+    Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
+    const Type *indexType = indexAlloc->getType();
+    mesh->mIndexBuffer.set(indexAlloc);
+    mesh->mIndexType.set(indexType);
+
+    bool isPrimitivePresent = stream->loadU32() != 0;
+    if(isPrimitivePresent) {
+        mesh->mPrimitiveBuffer.set(Allocation::createFromStream(rsc, stream));
+        mesh->mPrimitiveType.set(mesh->mPrimitiveBuffer->getType());
+    }
+
+    mesh->mVertexTypeCount = stream->loadU32();
+    if(mesh->mVertexTypeCount) {
+        mesh->mVertexTypes = new ObjectBaseRef<const Type>[mesh->mVertexTypeCount];
+        mesh->mVertexBuffers = new ObjectBaseRef<Allocation>[mesh->mVertexTypeCount];
+
+        for(uint32_t vCount = 0; vCount < mesh->mVertexTypeCount; vCount ++) {
+            Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
+            const Type *vertexType = vertexAlloc->getType();
+            mesh->mVertexBuffers[vCount].set(vertexAlloc);
+            mesh->mVertexTypes[vCount].set(vertexType);
+        }
+    }
+
+    return mesh;
+}
+
 
 SimpleMeshContext::SimpleMeshContext()
 {
@@ -131,14 +231,7 @@
     }
 
     sm->mPrimitive = (RsPrimitive)primType;
-    switch(sm->mPrimitive) {
-    case RS_PRIMITIVE_POINT:          sm->mGLPrimitive = GL_POINTS; break;
-    case RS_PRIMITIVE_LINE:           sm->mGLPrimitive = GL_LINES; break;
-    case RS_PRIMITIVE_LINE_STRIP:     sm->mGLPrimitive = GL_LINE_STRIP; break;
-    case RS_PRIMITIVE_TRIANGLE:       sm->mGLPrimitive = GL_TRIANGLES; break;
-    case RS_PRIMITIVE_TRIANGLE_STRIP: sm->mGLPrimitive = GL_TRIANGLE_STRIP; break;
-    case RS_PRIMITIVE_TRIANGLE_FAN:   sm->mGLPrimitive = GL_TRIANGLE_FAN; break;
-    }
+    sm->updateGLPrimitive();
     return sm;
 }
 
diff --git a/rsSimpleMesh.h b/rsSimpleMesh.h
index 6defbda..94e6a26 100644
--- a/rsSimpleMesh.h
+++ b/rsSimpleMesh.h
@@ -48,7 +48,11 @@
     void render(Context *) const;
     void renderRange(Context *, uint32_t start, uint32_t len) const;
     void uploadAll(Context *);
-
+    void updateGLPrimitive();
+    
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_SIMPLE_MESH; }
+    static SimpleMesh *createFromStream(Context *rsc, IStream *stream);
 
 protected:
 };
diff --git a/rsStream.cpp b/rsStream.cpp
new file mode 100644
index 0000000..03827dc
--- /dev/null
+++ b/rsStream.cpp
@@ -0,0 +1,133 @@
+
+/*
+ * 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_BUILD_FOR_HOST
+#include "rsContext.h"
+#else
+#include "rsContextHostStub.h"
+#endif
+
+#include "rsStream.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+IStream::IStream(const uint8_t *buf, bool use64)
+{
+    mData = buf;
+    mPos = 0;
+    mUse64 = use64;
+}
+
+void IStream::loadByteArray(void *dest, size_t numBytes)
+{
+    memcpy(dest, mData + mPos, numBytes);
+    mPos += numBytes;
+}
+
+uint64_t IStream::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 IStream::loadString(String8 *s)
+{
+    LOGE("loadString");
+    uint32_t len = loadU32();
+    LOGE("loadString len %i", len);
+    s->setTo((const char *)&mData[mPos], len);
+    mPos += len;
+}
+
+
+// Output stream implementation
+
+OStream::OStream(uint64_t len, bool use64)
+{
+    mData = (uint8_t*)malloc(len);
+    mLength = len;
+    mPos = 0;
+    mUse64 = use64;
+}
+
+OStream::~OStream()
+{
+    free(mData);
+}
+
+void OStream::addByteArray(const void *src, size_t numBytes)
+{
+    // We need to potentially grow more than once if the number of byes we write is substantial
+    while(mPos + numBytes >= mLength) {
+        growSize();
+    }
+    memcpy(mData + mPos, src, numBytes);
+    mPos += numBytes;
+}
+
+void OStream::addOffset(uint64_t v)
+{
+    if (mUse64) {
+        mPos = (mPos + 7) & (~7);
+        if(mPos + sizeof(v) >= mLength) {
+            growSize();
+        }
+        mData[mPos++] = (uint8_t)(v & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 8) & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 16) & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 24) & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 32) & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 40) & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 48) & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 56) & 0xff);
+    }
+    else {
+        addU32(v);
+    }
+}
+
+void OStream::addString(String8 *s)
+{
+    uint32_t len = s->size();
+    addU32(len);
+    if(mPos + len*sizeof(char) >= mLength) {
+        growSize();
+    }
+    char *stringData = reinterpret_cast<char *>(&mData[mPos]);
+    for(uint32_t i = 0; i < len; i ++) {
+        stringData[i] = s->string()[i];
+    }
+    mPos += len*sizeof(char);
+}
+
+void OStream::growSize()
+{
+    uint8_t *newData = (uint8_t*)malloc(mLength*2);
+    memcpy(newData, mData, mLength*sizeof(uint8_t));
+    mLength = mLength * 2;
+    free(mData);
+    mData = newData;
+}
+
+
diff --git a/rsStream.h b/rsStream.h
new file mode 100644
index 0000000..5ccd6ca
--- /dev/null
+++ b/rsStream.h
@@ -0,0 +1,156 @@
+/*
+ * 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_STREAM_H
+#define ANDROID_RS_STREAM_H
+
+#include <utils/String8.h>
+#include <stdio.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class IStream
+{
+public:
+    IStream(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;
+    }
+    inline uint8_t loadU8() {
+        uint8_t tmp = reinterpret_cast<const uint8_t *>(&mData[mPos])[0];
+        mPos += sizeof(uint8_t);
+        return tmp;
+    }
+    void loadByteArray(void *dest, size_t numBytes);
+    uint64_t loadOffset();
+    void loadString(String8 *s);
+    uint64_t getPos() const {
+        return mPos;
+    }
+    void reset(uint64_t pos) {
+        mPos = pos;
+    }
+    void reset() {
+        mPos = 0;
+    }
+    
+    const uint8_t * getPtr() const {
+        return mData;
+    }
+protected:
+    const uint8_t * mData;
+    uint64_t mPos;
+    bool mUse64;
+};
+
+class OStream
+{
+public:
+    OStream(uint64_t length, bool use64);
+    ~OStream();
+    
+    void addF(float v) {
+        uint32_t uintV = *reinterpret_cast<uint32_t*> (&v);
+        addU32(uintV);
+    }
+    void addI32(int32_t v) {
+        mPos = (mPos + 3) & (~3);
+        if(mPos + sizeof(v) >= mLength) {
+            growSize();
+        }
+        mData[mPos++] = (uint8_t)(v & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 8) & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 16) & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 24) & 0xff);
+    }
+    void addU32(uint32_t v) {
+        mPos = (mPos + 3) & (~3);
+        if(mPos + sizeof(v) >= mLength) {
+            growSize();
+        }
+        mData[mPos++] = (uint8_t)(v & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 8) & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 16) & 0xff);
+        mData[mPos++] = (uint8_t)((v >> 24) & 0xff);
+    }
+    void addU16(uint16_t v) {
+        mPos = (mPos + 1) & (~1);
+        if(mPos + sizeof(v) >= mLength) {
+            growSize();
+        }
+        mData[mPos++] = (uint8_t)(v & 0xff);
+        mData[mPos++] = (uint8_t)(v >> 8);
+    }
+    inline void addU8(uint8_t v) {
+        if(mPos + 1 >= mLength) {
+            growSize();
+        }
+        reinterpret_cast<uint8_t *>(&mData[mPos])[0] = v;
+        mPos ++;
+    }
+    void addByteArray(const void *src, size_t numBytes);
+    void addOffset(uint64_t v);
+    void addString(String8 *s);
+    uint64_t getPos() const {
+        return mPos;
+    }
+    void reset(uint64_t pos) {
+        mPos = pos;
+    }
+    void reset() {
+        mPos = 0;
+    }
+    const uint8_t * getPtr() const {
+        return mData;
+    }
+protected:
+    void growSize();
+    uint8_t * mData;
+    uint64_t mLength;
+    uint64_t mPos;
+    bool mUse64;
+};
+    
+
+} // renderscript
+} // android
+#endif //ANDROID_RS_STREAM_H
+
+
diff --git a/rsType.cpp b/rsType.cpp
index c09e979..8f99209 100644
--- a/rsType.cpp
+++ b/rsType.cpp
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
 #include <GLES/gl.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#endif
 
 using namespace android;
 using namespace android::renderscript;
@@ -283,6 +288,57 @@
     mElement->dumpLOGV(buf);
 }
 
+void Type::serialize(OStream *stream) const
+{
+    // Need to identify ourselves
+    stream->addU32((uint32_t)getClassId());
+
+    String8 name(getName());
+    stream->addString(&name);
+
+    mElement->serialize(stream);
+
+    stream->addU32(mDimX);
+    stream->addU32(mDimY);
+    stream->addU32(mDimZ);
+
+    stream->addU8((uint8_t)(mDimLOD ? 1 : 0));
+    stream->addU8((uint8_t)(mFaces ? 1 : 0));
+}
+
+Type *Type::createFromStream(Context *rsc, IStream *stream)
+{
+    // First make sure we are reading the correct object
+    A3DClassID classID = (A3DClassID)stream->loadU32();
+    if(classID != A3D_CLASS_ID_TYPE) {
+        LOGE("type loading skipped due to invalid class id\n");
+        return NULL;
+    }
+
+    String8 name;
+    stream->loadString(&name);
+
+    Element *elem = Element::createFromStream(rsc, stream);
+    if(!elem) {
+        return NULL;
+    }
+
+    Type *type = new Type(rsc);
+    type->mDimX = stream->loadU32();
+    type->mDimY = stream->loadU32();
+    type->mDimZ = stream->loadU32();
+
+    uint8_t temp = stream->loadU8();
+    type->mDimLOD = temp != 0;
+
+    temp = stream->loadU8();
+    type->mFaces = temp != 0;
+
+    type->setElement(elem);
+
+    return type;
+}
+
 bool Type::getIsNp2() const
 {
     uint32_t x = getDimX();
diff --git a/rsType.h b/rsType.h
index c25577c..664f343 100644
--- a/rsType.h
+++ b/rsType.h
@@ -74,6 +74,9 @@
     void enableGLVertexBuffer2(class VertexArray *) const;
 
     void dumpLOGV(const char *prefix) const;
+    virtual void serialize(OStream *stream) const;
+    virtual A3DClassID getClassId() const { return A3D_CLASS_ID_TYPE; }
+    static Type *createFromStream(Context *rsc, IStream *stream);
 
 protected:
     struct LOD {
diff --git a/rsUtils.h b/rsUtils.h
index adddf49..7ea3b61 100644
--- a/rsUtils.h
+++ b/rsUtils.h
@@ -19,15 +19,23 @@
 
 #define LOG_NDEBUG 0
 #define LOG_TAG "RenderScript"
+
 #include <utils/Log.h>
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
+
+#include "rsStream.h"
+#include "rsFileA3DDecls.h"
+
 #include <utils/String8.h>
+#include <utils/Vector.h>
+
 #include <stdlib.h>
 #include <pthread.h>
 #include <time.h>
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include <EGL/egl.h>
+#endif
+
 #include <math.h>
 
 #include "RenderScript.h"
diff --git a/rsVertexArray.cpp b/rsVertexArray.cpp
index 6c2002d..b42d1c4 100644
--- a/rsVertexArray.cpp
+++ b/rsVertexArray.cpp
@@ -14,10 +14,15 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-
 #include <GLES/gl.h>
 #include <GLES2/gl2.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#endif
+
 
 using namespace android;
 using namespace android::renderscript;
@@ -77,7 +82,7 @@
 
 void VertexArray::addUser(const Attrib &a, uint32_t stride)
 {
-    assert(mCount < RS_MAX_ATTRIBS);
+    rsAssert(mCount < RS_MAX_ATTRIBS);
     mAttribs[mCount].set(a);
     mAttribs[mCount].buffer = mActiveBuffer;
     mAttribs[mCount].stride = stride;
@@ -87,7 +92,7 @@
 
 void VertexArray::addLegacy(uint32_t type, uint32_t size, uint32_t stride, RsDataKind kind, bool normalized, uint32_t offset)
 {
-    assert(mCount < RS_MAX_ATTRIBS);
+    rsAssert(mCount < RS_MAX_ATTRIBS);
     mAttribs[mCount].clear();
     mAttribs[mCount].type = type;
     mAttribs[mCount].size = size;
@@ -117,7 +122,9 @@
     glDisableClientState(GL_NORMAL_ARRAY);
     glDisableClientState(GL_COLOR_ARRAY);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+#ifndef ANDROID_RS_BUILD_FOR_HOST // GLES only
     glDisableClientState(GL_POINT_SIZE_ARRAY_OES);
+#endif //ANDROID_RS_BUILD_FOR_HOST
 
     for (uint32_t ct=0; ct < mCount; ct++) {
         switch(mAttribs[ct].kind) {
@@ -160,7 +167,7 @@
                               mAttribs[ct].stride,
                               (void *)mAttribs[ct].offset);
             break;
-
+#ifndef ANDROID_RS_BUILD_FOR_HOST // GLES only
         case RS_KIND_POINT_SIZE:
             //logAttrib(POINT_SIZE);
             glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
@@ -169,6 +176,7 @@
                                   mAttribs[ct].stride,
                                   (void *)mAttribs[ct].offset);
             break;
+#endif //ANDROID_RS_BUILD_FOR_HOST
 
         default:
             rsAssert(0);