diff --git a/Allocation.cpp b/Allocation.cpp
new file mode 100644
index 0000000..46df171
--- /dev/null
+++ b/Allocation.cpp
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2008-2012 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 <utils/Log.h>
+#include <malloc.h>
+
+#include "RenderScript.h"
+#include "Element.h"
+#include "Type.h"
+#include "Allocation.h"
+
+
+void * Allocation::getIDSafe() const {
+    //if (mAdaptedAllocation != NULL) {
+        //return mAdaptedAllocation.getID();
+    //}
+    return getID();
+}
+
+void Allocation::updateCacheInfo(const Type *t) {
+    mCurrentDimX = t->getX();
+    mCurrentDimY = t->getY();
+    mCurrentDimZ = t->getZ();
+    mCurrentCount = mCurrentDimX;
+    if (mCurrentDimY > 1) {
+        mCurrentCount *= mCurrentDimY;
+    }
+    if (mCurrentDimZ > 1) {
+        mCurrentCount *= mCurrentDimZ;
+    }
+}
+
+Allocation::Allocation(void *id, RenderScript *rs, const Type *t, uint32_t usage) : BaseObj(id, rs) {
+    if ((usage & ~(RS_ALLOCATION_USAGE_SCRIPT |
+                   RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
+                   RS_ALLOCATION_USAGE_GRAPHICS_VERTEX |
+                   RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS |
+                   RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET |
+                   RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
+                   RS_ALLOCATION_USAGE_IO_INPUT |
+                   RS_ALLOCATION_USAGE_IO_OUTPUT)) != 0) {
+        ALOGE("Unknown usage specified.");
+    }
+
+    if ((usage & (RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
+                  RS_ALLOCATION_USAGE_IO_INPUT)) != 0) {
+        mWriteAllowed = false;
+        if ((usage & ~(RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
+                       RS_ALLOCATION_USAGE_IO_INPUT |
+                       RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
+                       RS_ALLOCATION_USAGE_SCRIPT)) != 0) {
+            ALOGE("Invalid usage combination.");
+        }
+    }
+
+    mType = t;
+    mUsage = usage;
+
+    if (t != NULL) {
+        updateCacheInfo(t);
+    }
+}
+
+void Allocation::validateIsInt32() {
+    RsDataType dt = mType->getElement()->getDataType();
+    if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) {
+        return;
+    }
+    ALOGE("32 bit integer source does not match allocation type %i", dt);
+}
+
+void Allocation::validateIsInt16() {
+    RsDataType dt = mType->getElement()->getDataType();
+    if ((dt == RS_TYPE_SIGNED_16) || (dt == RS_TYPE_UNSIGNED_16)) {
+        return;
+    }
+    ALOGE("16 bit integer source does not match allocation type %i", dt);
+}
+
+void Allocation::validateIsInt8() {
+    RsDataType dt = mType->getElement()->getDataType();
+    if ((dt == RS_TYPE_SIGNED_8) || (dt == RS_TYPE_UNSIGNED_8)) {
+        return;
+    }
+    ALOGE("8 bit integer source does not match allocation type %i", dt);
+}
+
+void Allocation::validateIsFloat32() {
+    RsDataType dt = mType->getElement()->getDataType();
+    if (dt == RS_TYPE_FLOAT_32) {
+        return;
+    }
+    ALOGE("32 bit float source does not match allocation type %i", dt);
+}
+
+void Allocation::validateIsObject() {
+    RsDataType dt = mType->getElement()->getDataType();
+    if ((dt == RS_TYPE_ELEMENT) ||
+        (dt == RS_TYPE_TYPE) ||
+        (dt == RS_TYPE_ALLOCATION) ||
+        (dt == RS_TYPE_SAMPLER) ||
+        (dt == RS_TYPE_SCRIPT) ||
+        (dt == RS_TYPE_MESH) ||
+        (dt == RS_TYPE_PROGRAM_FRAGMENT) ||
+        (dt == RS_TYPE_PROGRAM_VERTEX) ||
+        (dt == RS_TYPE_PROGRAM_RASTER) ||
+        (dt == RS_TYPE_PROGRAM_STORE)) {
+        return;
+    }
+    ALOGE("Object source does not match allocation type %i", dt);
+}
+
+void Allocation::updateFromNative() {
+    BaseObj::updateFromNative();
+
+    const void *typeID = rsaAllocationGetType(mRS->mContext, getID());
+    if(typeID != NULL) {
+        const Type *old = mType;
+        Type *t = new Type((void *)typeID, mRS);
+        t->updateFromNative();
+        updateCacheInfo(t);
+        mType = t;
+        delete old;
+    }
+}
+
+void Allocation::syncAll(RsAllocationUsageType srcLocation) {
+    switch (srcLocation) {
+    case RS_ALLOCATION_USAGE_SCRIPT:
+    case RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS:
+    case RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE:
+    case RS_ALLOCATION_USAGE_GRAPHICS_VERTEX:
+        break;
+    default:
+        ALOGE("Source must be exactly one usage type.");
+    }
+    rsAllocationSyncAll(mRS->mContext, getIDSafe(), srcLocation);
+}
+
+void Allocation::ioSendOutput() {
+    if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) {
+        ALOGE("Can only send buffer if IO_OUTPUT usage specified.");
+    }
+    rsAllocationIoSend(mRS->mContext, getID());
+}
+
+void Allocation::ioGetInput() {
+    if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) {
+        ALOGE("Can only send buffer if IO_OUTPUT usage specified.");
+    }
+    rsAllocationIoReceive(mRS->mContext, getID());
+}
+
+/*
+void copyFrom(BaseObj[] d) {
+    mRS.validate();
+    validateIsObject();
+    if (d.length != mCurrentCount) {
+        ALOGE("Array size mismatch, allocation sizeX = " +
+                                             mCurrentCount + ", array length = " + d.length);
+    }
+    int i[] = new int[d.length];
+    for (int ct=0; ct < d.length; ct++) {
+        i[ct] = d[ct].getID();
+    }
+    copy1DRangeFromUnchecked(0, mCurrentCount, i);
+}
+*/
+
+
+/*
+void Allocation::setFromFieldPacker(int xoff, FieldPacker fp) {
+    mRS.validate();
+    int eSize = mType.mElement.getSizeBytes();
+    final byte[] data = fp.getData();
+
+    int count = data.length / eSize;
+    if ((eSize * count) != data.length) {
+        ALOGE("Field packer length " + data.length +
+                                           " not divisible by element size " + eSize + ".");
+    }
+    copy1DRangeFromUnchecked(xoff, count, data);
+}
+
+void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
+    mRS.validate();
+    if (component_number >= mType.mElement.mElements.length) {
+        ALOGE("Component_number " + component_number + " out of range.");
+    }
+    if(xoff < 0) {
+        ALOGE("Offset must be >= 0.");
+    }
+
+    final byte[] data = fp.getData();
+    int eSize = mType.mElement.mElements[component_number].getSizeBytes();
+    eSize *= mType.mElement.mArraySizes[component_number];
+
+    if (data.length != eSize) {
+        ALOGE("Field packer sizelength " + data.length +
+                                           " does not match component size " + eSize + ".");
+    }
+
+    mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
+                                 component_number, data, data.length);
+}
+*/
+
+void Allocation::generateMipmaps() {
+    rsAllocationGenerateMipmaps(mRS->mContext, getID());
+}
+
+void Allocation::copy1DRangeFromUnchecked(uint32_t off, size_t count, const void *data, size_t dataLen) {
+    if(count < 1) {
+        ALOGE("Count must be >= 1.");
+        return;
+    }
+    if((off + count) > mCurrentCount) {
+        ALOGE("Overflow, Available count %zu, got %zu at offset %zu.", mCurrentCount, count, off);
+        return;
+    }
+    if((count * mType->getElement()->getSizeBytes()) > dataLen) {
+        ALOGE("Array too small for allocation type.");
+        return;
+    }
+
+    rsAllocation1DData(mRS->mContext, getIDSafe(), off, mSelectedLOD, count, data, dataLen);
+}
+
+void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int32_t *d, size_t dataLen) {
+    validateIsInt32();
+    copy1DRangeFromUnchecked(off, count, d, dataLen);
+}
+
+void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int16_t *d, size_t dataLen) {
+    validateIsInt16();
+    copy1DRangeFromUnchecked(off, count, d, dataLen);
+}
+
+void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int8_t *d, size_t dataLen) {
+    validateIsInt8();
+    copy1DRangeFromUnchecked(off, count, d, dataLen);
+}
+
+void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const float *d, size_t dataLen) {
+    validateIsFloat32();
+    copy1DRangeFromUnchecked(off, count, d, dataLen);
+}
+
+void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const Allocation *data, uint32_t dataOff) {
+    rsAllocationCopy2DRange(mRS->mContext, getIDSafe(), off, 0,
+                            mSelectedLOD, mSelectedFace,
+                            count, 1, data->getIDSafe(), dataOff, 0,
+                            data->mSelectedLOD, data->mSelectedFace);
+}
+
+void Allocation::validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h) {
+    if (mAdaptedAllocation != NULL) {
+
+    } else {
+        if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
+            ALOGE("Updated region larger than allocation.");
+        }
+    }
+}
+
+void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                                 const int8_t *data, size_t dataLen) {
+    validate2DRange(xoff, yoff, w, h);
+    rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
+                       w, h, data, dataLen);
+}
+
+void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                                 const int16_t *data, size_t dataLen) {
+    validate2DRange(xoff, yoff, w, h);
+    rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
+                       w, h, data, dataLen);
+}
+
+void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                                 const int32_t *data, size_t dataLen) {
+    validate2DRange(xoff, yoff, w, h);
+    rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
+                       w, h, data, dataLen);
+}
+
+void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                                 const float *data, size_t dataLen) {
+    validate2DRange(xoff, yoff, w, h);
+    rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
+                       w, h, data, dataLen);
+}
+
+void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                                 const Allocation *data, size_t dataLen,
+                                 uint32_t dataXoff, uint32_t dataYoff) {
+    validate2DRange(xoff, yoff, w, h);
+    rsAllocationCopy2DRange(mRS->mContext, getIDSafe(), xoff, yoff,
+                            mSelectedLOD, mSelectedFace,
+                            w, h, data->getIDSafe(), dataXoff, dataYoff,
+                            data->mSelectedLOD, data->mSelectedFace);
+}
+
+/*
+void copyTo(byte[] d) {
+    validateIsInt8();
+    mRS.validate();
+    mRS.nAllocationRead(getID(), d);
+}
+
+void copyTo(short[] d) {
+    validateIsInt16();
+    mRS.validate();
+    mRS.nAllocationRead(getID(), d);
+}
+
+void copyTo(int[] d) {
+    validateIsInt32();
+    mRS.validate();
+    mRS.nAllocationRead(getID(), d);
+}
+
+void copyTo(float[] d) {
+    validateIsFloat32();
+    mRS.validate();
+    mRS.nAllocationRead(getID(), d);
+}
+
+void resize(int dimX) {
+    if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
+        throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
+    }
+    mRS.nAllocationResize1D(getID(), dimX);
+    mRS.finish();  // Necessary because resize is fifoed and update is async.
+
+    int typeID = mRS.nAllocationGetType(getID());
+    mType = new Type(typeID, mRS);
+    mType.updateFromNative();
+    updateCacheInfo(mType);
+}
+
+void resize(int dimX, int dimY) {
+    if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
+        throw new RSInvalidStateException(
+            "Resize only support for 2D allocations at this time.");
+    }
+    if (mType.getY() == 0) {
+        throw new RSInvalidStateException(
+            "Resize only support for 2D allocations at this time.");
+    }
+    mRS.nAllocationResize2D(getID(), dimX, dimY);
+    mRS.finish();  // Necessary because resize is fifoed and update is async.
+
+    int typeID = mRS.nAllocationGetType(getID());
+    mType = new Type(typeID, mRS);
+    mType.updateFromNative();
+    updateCacheInfo(mType);
+}
+*/
+
+
+Allocation *Allocation::createTyped(RenderScript *rs, const Type *type,
+                        RsAllocationMipmapControl mips, uint32_t usage) {
+    void *id = rsAllocationCreateTyped(rs->mContext, type->getID(), mips, usage, 0);
+    if (id == 0) {
+        ALOGE("Allocation creation failed.");
+        return NULL;
+    }
+    return new Allocation(id, rs, type, usage);
+}
+
+Allocation *Allocation::createTyped(RenderScript *rs, const Type *type,
+                                    RsAllocationMipmapControl mips, uint32_t usage, void *pointer) {
+    void *id = rsAllocationCreateTyped(rs->mContext, type->getID(), mips, usage, (uint32_t)pointer);
+    if (id == 0) {
+        ALOGE("Allocation creation failed.");
+    }
+    return new Allocation(id, rs, type, usage);
+}
+
+Allocation *Allocation::createTyped(RenderScript *rs, const Type *type, uint32_t usage) {
+    return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage);
+}
+
+Allocation *Allocation::createSized(RenderScript *rs, const Element *e, size_t count, uint32_t usage) {
+    Type::Builder b(rs, e);
+    b.setX(count);
+    const Type *t = b.create();
+
+    void *id = rsAllocationCreateTyped(rs->mContext, t->getID(), RS_ALLOCATION_MIPMAP_NONE, usage, 0);
+    if (id == 0) {
+        ALOGE("Allocation creation failed.");
+    }
+    return new Allocation(id, rs, t, usage);
+}
+
+
+/*
+SurfaceTexture getSurfaceTexture() {
+    if ((mUsage & USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) == 0) {
+        throw new RSInvalidStateException("Allocation is not a surface texture.");
+    }
+
+    int id = mRS.nAllocationGetSurfaceTextureID(getID());
+    return new SurfaceTexture(id);
+
+}
+
+void setSurfaceTexture(SurfaceTexture sur) {
+    if ((mUsage & USAGE_IO_OUTPUT) == 0) {
+        throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
+    }
+
+    mRS.validate();
+    mRS.nAllocationSetSurfaceTexture(getID(), sur);
+}
+
+
+static Allocation createFromBitmapResource(RenderScript rs,
+                                                  Resources res,
+                                                  int id,
+                                                  MipmapControl mips,
+                                                  int usage) {
+
+    rs.validate();
+    Bitmap b = BitmapFactory.decodeResource(res, id);
+    Allocation alloc = createFromBitmap(rs, b, mips, usage);
+    b.recycle();
+    return alloc;
+}
+
+static Allocation createFromBitmapResource(RenderScript rs,
+                                                  Resources res,
+                                                  int id) {
+    return createFromBitmapResource(rs, res, id,
+                                    MipmapControl.MIPMAP_NONE,
+                                    USAGE_GRAPHICS_TEXTURE);
+}
+
+static Allocation createFromString(RenderScript rs,
+                                          String str,
+                                          int usage) {
+    rs.validate();
+    byte[] allocArray = NULL;
+    try {
+        allocArray = str.getBytes("UTF-8");
+        Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
+        alloc.copyFrom(allocArray);
+        return alloc;
+    }
+    catch (Exception e) {
+        throw new RSRuntimeException("Could not convert string to utf-8.");
+    }
+}
+*/
+
diff --git a/Allocation.h b/Allocation.h
new file mode 100644
index 0000000..059e61d
--- /dev/null
+++ b/Allocation.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2008-2012 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 <pthread.h>
+#include <rs.h>
+
+#include "RenderScript.h"
+#include "Type.h"
+#include "Element.h"
+
+class Allocation : BaseObj {
+protected:
+    const Type *mType;
+    uint32_t mUsage;
+    Allocation *mAdaptedAllocation;
+
+    bool mConstrainedLOD;
+    bool mConstrainedFace;
+    bool mConstrainedY;
+    bool mConstrainedZ;
+    bool mReadAllowed;
+    bool mWriteAllowed;
+    uint32_t mSelectedY;
+    uint32_t mSelectedZ;
+    uint32_t mSelectedLOD;
+    RsAllocationCubemapFace mSelectedFace;
+
+    uint32_t mCurrentDimX;
+    uint32_t mCurrentDimY;
+    uint32_t mCurrentDimZ;
+    uint32_t mCurrentCount;
+
+
+    void * getIDSafe() const;
+    void updateCacheInfo(const Type *t);
+
+    Allocation(void *id, RenderScript *rs, const Type *t, uint32_t usage);
+
+    void validateIsInt32();
+    void validateIsInt16();
+    void validateIsInt8();
+    void validateIsFloat32();
+    void validateIsObject();
+
+    virtual void updateFromNative();
+
+    void validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h);
+
+public:
+    const Type * getType() {
+        return mType;
+    }
+
+    void syncAll(RsAllocationUsageType srcLocation);
+    void ioSendOutput();
+    void ioGetInput();
+
+    //void copyFrom(BaseObj[] d);
+    //void copyFromUnchecked(int[] d);
+    //void copyFromUnchecked(short[] d);
+    //void copyFromUnchecked(byte[] d);
+    //void copyFromUnchecked(float[] d);
+    //void copyFrom(int[] d);
+    //void copyFrom(short[] d);
+    //void copyFrom(byte[] d);
+    //void copyFrom(float[] d);
+    //void setFromFieldPacker(int xoff, FieldPacker fp);
+    //void setFromFieldPacker(int xoff, int component_number, FieldPacker fp);
+    void generateMipmaps();
+    void copy1DRangeFromUnchecked(uint32_t off, size_t count, const void *data, size_t dataLen);
+    void copy1DRangeFrom(uint32_t off, size_t count, const int32_t* d, size_t dataLen);
+    void copy1DRangeFrom(uint32_t off, size_t count, const int16_t* d, size_t dataLen);
+    void copy1DRangeFrom(uint32_t off, size_t count, const int8_t* d, size_t dataLen);
+    void copy1DRangeFrom(uint32_t off, size_t count, const float* d, size_t dataLen);
+    void copy1DRangeFrom(uint32_t off, size_t count, const Allocation *data, uint32_t dataOff);
+
+    void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                         const int32_t *data, size_t dataLen);
+    void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                         const int16_t *data, size_t dataLen);
+    void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                         const int8_t *data, size_t dataLen);
+    void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                         const float *data, size_t dataLen);
+    void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                         const Allocation *data, size_t dataLen,
+                         uint32_t dataXoff, uint32_t dataYoff);
+
+    //void copyTo(byte[] d);
+    //void copyTo(short[] d);
+    //void copyTo(int[] d);
+    //void copyTo(float[] d);
+    void resize(int dimX);
+    void resize(int dimX, int dimY);
+
+    static Allocation *createTyped(RenderScript *rs, const Type *type,
+                                   RsAllocationMipmapControl mips, uint32_t usage);
+    static Allocation *createTyped(RenderScript *rs, const Type *type,
+                                   RsAllocationMipmapControl mips, uint32_t usage, void * pointer);
+
+    static Allocation *createTyped(RenderScript *rs, const Type *type,
+                                   uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);
+    static Allocation *createSized(RenderScript *rs, const Element *e, size_t count,
+                                   uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);
+    //SurfaceTexture *getSurfaceTexture();
+    //void setSurfaceTexture(SurfaceTexture *sur);
+
+};
+
+
diff --git a/Android.mk b/Android.mk
index 9c5d06b..b7cc177 100644
--- a/Android.mk
+++ b/Android.mk
@@ -127,7 +127,12 @@
 	driver/rsdSampler.cpp \
 	driver/rsdShader.cpp \
 	driver/rsdShaderCache.cpp \
-	driver/rsdVertexArray.cpp
+	driver/rsdVertexArray.cpp \
+	RenderScript.cpp \
+	BaseObj.cpp \
+	Element.cpp \
+	Type.cpp \
+	Allocation.cpp
 
 LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc libbcinfo libgui
 
diff --git a/BaseObj.cpp b/BaseObj.cpp
new file mode 100644
index 0000000..b2f5450
--- /dev/null
+++ b/BaseObj.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008-2012 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 <rs.h>
+
+#include "RenderScript.h"
+#include "BaseObj.h"
+
+void * BaseObj::getID() const {
+    if (mID == NULL) {
+        ALOGE("Internal error: Object id 0.");
+    }
+    return mID;
+}
+
+BaseObj::BaseObj(void *id, RenderScript *rs) {
+    mRS = rs;
+    mID = id;
+}
+
+void BaseObj::checkValid() {
+    if (mID == 0) {
+        ALOGE("Invalid object.");
+    }
+}
+
+BaseObj::~BaseObj() {
+    rsObjDestroy(mRS->mContext, mID);
+    mRS = NULL;
+    mID = NULL;
+}
+
+void BaseObj::updateFromNative() {
+    const char *name = NULL;
+    rsaGetName(mRS, mID, &name);
+    mName = name;
+}
+
+bool BaseObj::equals(const BaseObj *obj) {
+    // Early-out check to see if both BaseObjs are actually the same
+    if (this == obj)
+        return true;
+    return mID == obj->mID;
+}
+
+
+
diff --git a/BaseObj.h b/BaseObj.h
new file mode 100644
index 0000000..91f3714
--- /dev/null
+++ b/BaseObj.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008-2012 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_BASE_OBJ_H__
+#define __ANDROID_BASE_OBJ_H__
+
+
+#include <pthread.h>
+#include <rs.h>
+
+#include "RenderScript.h"
+
+class BaseObj {
+protected:
+    friend class Element;
+    friend class Type;
+
+    void *mID;
+    RenderScript *mRS;
+    android::String8 mName;
+
+    void * getID() const;
+
+    BaseObj(void *id, RenderScript *rs);
+    void checkValid();
+
+public:
+
+    virtual ~BaseObj();
+    virtual void updateFromNative();
+    virtual bool equals(const BaseObj *obj);
+};
+
+#endif
diff --git a/Element.cpp b/Element.cpp
new file mode 100644
index 0000000..c621c82
--- /dev/null
+++ b/Element.cpp
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2008-2012 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 <utils/Log.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "RenderScript.h"
+#include "Element.h"
+
+
+const Element * Element::getSubElement(uint32_t index) {
+    if (!mVisibleElementMap.size()) {
+        ALOGE("Element contains no sub-elements");
+        return NULL;
+    }
+    if (index >= mVisibleElementMap.size()) {
+        ALOGE("Illegal sub-element index");
+    }
+    return mElements[mVisibleElementMap[index]];
+}
+
+const char * Element::getSubElementName(uint32_t index) {
+    if (!mVisibleElementMap.size()) {
+        ALOGE("Element contains no sub-elements");
+    }
+    if (index >= mVisibleElementMap.size()) {
+        ALOGE("Illegal sub-element index");
+    }
+    return mElementNames[mVisibleElementMap[index]];
+}
+
+size_t Element::getSubElementArraySize(uint32_t index) {
+    if (!mVisibleElementMap.size()) {
+        ALOGE("Element contains no sub-elements");
+    }
+    if (index >= mVisibleElementMap.size()) {
+        ALOGE("Illegal sub-element index");
+    }
+    return mArraySizes[mVisibleElementMap[index]];
+}
+
+uint32_t Element::getSubElementOffsetBytes(uint32_t index) {
+    if (mVisibleElementMap.size()) {
+        ALOGE("Element contains no sub-elements");
+    }
+    if (index >= mVisibleElementMap.size()) {
+        ALOGE("Illegal sub-element index");
+    }
+    return mOffsetInBytes[mVisibleElementMap[index]];
+}
+
+
+#define CREATE_USER(N, T) const Element * Element::N(RenderScript *rs) { \
+    return createUser(rs, RS_TYPE_##T); \
+}
+CREATE_USER(BOOLEAN, BOOLEAN);
+CREATE_USER(U8, UNSIGNED_8);
+CREATE_USER(I8, SIGNED_8);
+CREATE_USER(U16, UNSIGNED_16);
+CREATE_USER(I16, SIGNED_16);
+CREATE_USER(U32, UNSIGNED_32);
+CREATE_USER(I32, SIGNED_32);
+CREATE_USER(U64, UNSIGNED_64);
+CREATE_USER(I64, SIGNED_64);
+CREATE_USER(F32, FLOAT_32);
+CREATE_USER(F64, FLOAT_64);
+CREATE_USER(ELEMENT, ELEMENT);
+CREATE_USER(TYPE, TYPE);
+CREATE_USER(ALLOCATION, ALLOCATION);
+CREATE_USER(SAMPLER, SAMPLER);
+CREATE_USER(SCRIPT, SCRIPT);
+CREATE_USER(MESH, MESH);
+CREATE_USER(PROGRAM_FRAGMENT, PROGRAM_FRAGMENT);
+CREATE_USER(PROGRAM_VERTEX, PROGRAM_VERTEX);
+CREATE_USER(PROGRAM_RASTER, PROGRAM_RASTER);
+CREATE_USER(PROGRAM_STORE, PROGRAM_STORE);
+CREATE_USER(MATRIX_4X4, MATRIX_4X4);
+CREATE_USER(MATRIX_3X3, MATRIX_3X3);
+CREATE_USER(MATRIX_2X2, MATRIX_2X2);
+
+#define CREATE_PIXEL(N, T, K) const Element * Element::N(RenderScript *rs) { \
+    return createPixel(rs, RS_TYPE_##T, RS_KIND_##K); \
+}
+CREATE_PIXEL(A_8, UNSIGNED_8, PIXEL_A);
+CREATE_PIXEL(RGB_565, UNSIGNED_5_6_5, PIXEL_RGB);
+CREATE_PIXEL(RGB_888, UNSIGNED_8, PIXEL_RGB);
+CREATE_PIXEL(RGBA_4444, UNSIGNED_4_4_4_4, PIXEL_RGBA);
+CREATE_PIXEL(RGBA_8888, UNSIGNED_8, PIXEL_RGBA);
+
+#define CREATE_VECTOR(N, T) const Element * Element::N##_2(RenderScript *rs) { \
+    return createVector(rs, RS_TYPE_##T, 2); \
+} \
+const Element * Element::N##_3(RenderScript *rs) { \
+    return createVector(rs, RS_TYPE_##T, 3); \
+} \
+const Element * Element::N##_4(RenderScript *rs) { \
+    return createVector(rs, RS_TYPE_##T, 4); \
+}
+CREATE_VECTOR(U8, UNSIGNED_8);
+CREATE_VECTOR(I8, SIGNED_8);
+CREATE_VECTOR(U16, UNSIGNED_16);
+CREATE_VECTOR(I16, SIGNED_16);
+CREATE_VECTOR(U32, UNSIGNED_32);
+CREATE_VECTOR(I32, SIGNED_32);
+CREATE_VECTOR(U64, UNSIGNED_64);
+CREATE_VECTOR(I64, SIGNED_64);
+CREATE_VECTOR(F32, FLOAT_32);
+CREATE_VECTOR(F64, FLOAT_64);
+
+
+void Element::updateVisibleSubElements() {
+    if (!mElements.size()) {
+        return;
+    }
+    mVisibleElementMap.clear();
+
+    int noPaddingFieldCount = 0;
+    size_t fieldCount = mElementNames.size();
+    // Find out how many elements are not padding
+    for (size_t ct = 0; ct < fieldCount; ct ++) {
+        if (mElementNames[ct].string()[0] != '#') {
+            noPaddingFieldCount ++;
+        }
+    }
+
+    // Make a map that points us at non-padding elements
+    for (size_t ct = 0; ct < fieldCount; ct ++) {
+        if (mElementNames[ct].string()[0] != '#') {
+            mVisibleElementMap.push((uint32_t)ct);
+        }
+    }
+}
+
+Element::Element(void *id, RenderScript *rs,
+                 android::Vector<const Element *> &elements,
+                 android::Vector<android::String8> &elementNames,
+                 android::Vector<uint32_t> &arraySizes) : BaseObj(id, rs) {
+    mSizeBytes = 0;
+    mVectorSize = 1;
+    mElements = elements;
+    mArraySizes = arraySizes;
+    mElementNames = elementNames;
+
+    mType = RS_TYPE_NONE;
+    mKind = RS_KIND_USER;
+
+    for (size_t ct = 0; ct < mElements.size(); ct++ ) {
+        mOffsetInBytes.push(mSizeBytes);
+        mSizeBytes += mElements[ct]->mSizeBytes * mArraySizes[ct];
+    }
+    updateVisibleSubElements();
+}
+
+
+static uint32_t GetSizeInBytesForType(RsDataType dt) {
+    switch(dt) {
+    case RS_TYPE_NONE:
+        return 0;
+    case RS_TYPE_SIGNED_8:
+    case RS_TYPE_UNSIGNED_8:
+    case RS_TYPE_BOOLEAN:
+        return 1;
+
+    case RS_TYPE_FLOAT_16:
+    case RS_TYPE_SIGNED_16:
+    case RS_TYPE_UNSIGNED_16:
+    case RS_TYPE_UNSIGNED_5_6_5:
+    case RS_TYPE_UNSIGNED_5_5_5_1:
+    case RS_TYPE_UNSIGNED_4_4_4_4:
+        return 2;
+
+    case RS_TYPE_FLOAT_32:
+    case RS_TYPE_SIGNED_32:
+    case RS_TYPE_UNSIGNED_32:
+        return 4;
+
+    case RS_TYPE_FLOAT_64:
+    case RS_TYPE_SIGNED_64:
+    case RS_TYPE_UNSIGNED_64:
+        return 8;
+
+    case RS_TYPE_MATRIX_4X4:
+        return 16 * 4;
+    case RS_TYPE_MATRIX_3X3:
+        return 9 * 4;
+    case RS_TYPE_MATRIX_2X2:
+        return 4 * 4;
+
+    case RS_TYPE_TYPE:
+    case RS_TYPE_ALLOCATION:
+    case RS_TYPE_SAMPLER:
+    case RS_TYPE_SCRIPT:
+    case RS_TYPE_MESH:
+    case RS_TYPE_PROGRAM_FRAGMENT:
+    case RS_TYPE_PROGRAM_VERTEX:
+    case RS_TYPE_PROGRAM_RASTER:
+    case RS_TYPE_PROGRAM_STORE:
+        return 4;
+
+    default:
+        break;
+    }
+
+    ALOGE("Missing type %i", dt);
+    return 0;
+}
+
+Element::Element(void *id, RenderScript *rs,
+                 RsDataType dt, RsDataKind dk, bool norm, uint32_t size) :
+    BaseObj(id, rs)
+{
+    uint32_t tsize = GetSizeInBytesForType(dt);
+    if ((dt != RS_TYPE_UNSIGNED_5_6_5) &&
+        (dt != RS_TYPE_UNSIGNED_4_4_4_4) &&
+        (dt != RS_TYPE_UNSIGNED_5_5_5_1)) {
+        if (size == 3) {
+            mSizeBytes = tsize * 4;
+        } else {
+            mSizeBytes = tsize * size;
+        }
+    } else {
+        mSizeBytes = tsize;
+    }
+    mType = dt;
+    mKind = dk;
+    mNormalized = norm;
+    mVectorSize = size;
+}
+
+Element::~Element() {
+}
+
+   /*
+    Element(int id, RenderScript rs) {
+        super(id, rs);
+    }
+    */
+
+void Element::updateFromNative() {
+    BaseObj::updateFromNative();
+/*
+    // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
+    int[] dataBuffer = new int[5];
+    mRS.nElementGetNativeData(getID(), dataBuffer);
+
+    mNormalized = dataBuffer[2] == 1 ? true : false;
+    mVectorSize = dataBuffer[3];
+    mSize = 0;
+    for (DataType dt: DataType.values()) {
+        if(dt.mID == dataBuffer[0]){
+            mType = dt;
+            mSize = mType.mSize * mVectorSize;
+        }
+    }
+    for (DataKind dk: DataKind.values()) {
+        if(dk.mID == dataBuffer[1]){
+            mKind = dk;
+        }
+    }
+
+    int numSubElements = dataBuffer[4];
+    if(numSubElements > 0) {
+        mElements = new Element[numSubElements];
+        mElementNames = new String[numSubElements];
+        mArraySizes = new int[numSubElements];
+        mOffsetInBytes = new int[numSubElements];
+
+        int[] subElementIds = new int[numSubElements];
+        mRS.nElementGetSubElements(getID(), subElementIds, mElementNames, mArraySizes);
+        for(int i = 0; i < numSubElements; i ++) {
+            mElements[i] = new Element(subElementIds[i], mRS);
+            mElements[i].updateFromNative();
+            mOffsetInBytes[i] = mSize;
+            mSize += mElements[i].mSize * mArraySizes[i];
+        }
+    }
+    */
+    updateVisibleSubElements();
+}
+
+const Element * Element::createUser(RenderScript *rs, RsDataType dt) {
+    ALOGE("createUser %p %i", rs, dt);
+    void * id = rsElementCreate(rs->mContext, dt, RS_KIND_USER, false, 1);
+    return new Element(id, rs, dt, RS_KIND_USER, false, 1);
+}
+
+const Element * Element::createVector(RenderScript *rs, RsDataType dt, uint32_t size) {
+    if (size < 2 || size > 4) {
+        ALOGE("Vector size out of range 2-4.");
+        return NULL;
+    }
+    void *id = rsElementCreate(rs->mContext, dt, RS_KIND_USER, false, size);
+    return new Element(id, rs, dt, RS_KIND_USER, false, size);
+}
+
+const Element * Element::createPixel(RenderScript *rs, RsDataType dt, RsDataKind dk) {
+    ALOGE("createPixel %p %i %i", rs, dt, dk);
+    if (!(dk == RS_KIND_PIXEL_L ||
+          dk == RS_KIND_PIXEL_A ||
+          dk == RS_KIND_PIXEL_LA ||
+          dk == RS_KIND_PIXEL_RGB ||
+          dk == RS_KIND_PIXEL_RGBA ||
+          dk == RS_KIND_PIXEL_DEPTH)) {
+        ALOGE("Unsupported DataKind");
+        return NULL;
+    }
+    if (!(dt == RS_TYPE_UNSIGNED_8 ||
+          dt == RS_TYPE_UNSIGNED_16 ||
+          dt == RS_TYPE_UNSIGNED_5_6_5 ||
+          dt == RS_TYPE_UNSIGNED_4_4_4_4 ||
+          dt == RS_TYPE_UNSIGNED_5_5_5_1)) {
+        ALOGE("Unsupported DataType");
+        return NULL;
+    }
+    if (dt == RS_TYPE_UNSIGNED_5_6_5 && dk != RS_KIND_PIXEL_RGB) {
+        ALOGE("Bad kind and type combo");
+        return NULL;
+    }
+    if (dt == RS_TYPE_UNSIGNED_5_5_5_1 && dk != RS_KIND_PIXEL_RGBA) {
+        ALOGE("Bad kind and type combo");
+        return NULL;
+    }
+    if (dt == RS_TYPE_UNSIGNED_4_4_4_4 && dk != RS_KIND_PIXEL_RGBA) {
+        ALOGE("Bad kind and type combo");
+        return NULL;
+    }
+    if (dt == RS_TYPE_UNSIGNED_16 && dk != RS_KIND_PIXEL_DEPTH) {
+        ALOGE("Bad kind and type combo");
+        return NULL;
+    }
+
+    int size = 1;
+    switch (dk) {
+    case RS_KIND_PIXEL_LA:
+        size = 2;
+        break;
+    case RS_KIND_PIXEL_RGB:
+        size = 3;
+        break;
+    case RS_KIND_PIXEL_RGBA:
+        size = 4;
+        break;
+    case RS_KIND_PIXEL_DEPTH:
+        size = 2;
+        break;
+    default:
+        break;
+    }
+
+    void * id = rsElementCreate(rs->mContext, dt, dk, true, size);
+    return new Element(id, rs, dt, dk, true, size);
+}
+
+bool Element::isCompatible(const Element *e) {
+    // Try strict BaseObj equality to start with.
+    if (this == e) {
+        return true;
+    }
+
+    // Ignore mKind because it is allowed to be different (user vs. pixel).
+    // We also ignore mNormalized because it can be different. The mType
+    // field must be non-null since we require name equivalence for
+    // user-created Elements.
+    return ((mSizeBytes == e->mSizeBytes) &&
+            (mType != NULL) &&
+            (mType == e->mType) &&
+            (mVectorSize == e->mVectorSize));
+}
+
+Element::Builder::Builder(RenderScript *rs) {
+    mRS = rs;
+    mSkipPadding = false;
+}
+
+void Element::Builder::add(const Element *e, android::String8 &name, uint32_t arraySize) {
+    // Skip padding fields after a vector 3 type.
+    if (mSkipPadding) {
+        const char *s1 = "#padding_";
+        const char *s2 = name;
+        size_t len = strlen(s1);
+        if (strlen(s2) >= len) {
+            if (!memcmp(s1, s2, len)) {
+                mSkipPadding = false;
+                return;
+            }
+        }
+    }
+
+    if (e->mVectorSize == 3) {
+        mSkipPadding = true;
+    } else {
+        mSkipPadding = false;
+    }
+
+    mElements.add(e);
+    mElementNames.add(name);
+    mArraySizes.add(arraySize);
+}
+
+const Element * Element::Builder::create() {
+    size_t fieldCount = mElements.size();
+    const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *));
+    size_t* sizeArray = (size_t*)calloc(fieldCount, sizeof(size_t));
+
+    for (size_t ct = 0; ct < fieldCount; ct++) {
+        nameArray[ct] = mElementNames[ct].string();
+        sizeArray[ct] = mElementNames[ct].length();
+    }
+
+    void *id = rsElementCreate2(mRS->mContext,
+                                (RsElement *)mElements.array(), fieldCount,
+                                nameArray, fieldCount * sizeof(size_t),  sizeArray,
+                                (const uint32_t *)mArraySizes.array(), fieldCount);
+
+
+    free(nameArray);
+    free(sizeArray);
+
+    Element *e = new Element(id, mRS, mElements, mElementNames, mArraySizes);
+    return e;
+}
+
diff --git a/Element.h b/Element.h
new file mode 100644
index 0000000..a579dc3
--- /dev/null
+++ b/Element.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2008-2012 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_ELEMENT_H__
+#define __ANDROID_ELEMENT_H__
+
+#include <rs.h>
+#include "RenderScript.h"
+#include "BaseObj.h"
+
+class Element : public BaseObj {
+public:
+    /**
+     * Return if a element is too complex for use as a data source for a Mesh or
+     * a Program.
+     *
+     * @return boolean
+     */
+    bool isComplex();
+
+    /**
+    * @hide
+    * @return number of sub-elements in this element
+    */
+    size_t getSubElementCount() {
+        return mVisibleElementMap.size();
+    }
+
+    /**
+    * @hide
+    * @param index index of the sub-element to return
+    * @return sub-element in this element at given index
+    */
+    const Element * getSubElement(uint32_t index);
+
+    /**
+    * @hide
+    * @param index index of the sub-element
+    * @return sub-element in this element at given index
+    */
+    const char * getSubElementName(uint32_t index);
+
+    /**
+    * @hide
+    * @param index index of the sub-element
+    * @return array size of sub-element in this element at given index
+    */
+    size_t getSubElementArraySize(uint32_t index);
+
+    /**
+    * @hide
+    * @param index index of the sub-element
+    * @return offset in bytes of sub-element in this element at given index
+    */
+    uint32_t getSubElementOffsetBytes(uint32_t index);
+
+    /**
+    * @hide
+    * @return element data type
+    */
+    RsDataType getDataType() const {
+        return mType;
+    }
+
+    /**
+    * @hide
+    * @return element data kind
+    */
+    RsDataKind getDataKind() const {
+        return mKind;
+    }
+
+    size_t getSizeBytes() const {
+        return mSizeBytes;
+    }
+
+
+    static const Element * BOOLEAN(RenderScript *rs);
+    static const Element * U8(RenderScript *rs);
+    static const Element * I8(RenderScript *rs);
+    static const Element * U16(RenderScript *rs);
+    static const Element * I16(RenderScript *rs);
+    static const Element * U32(RenderScript *rs);
+    static const Element * I32(RenderScript *rs);
+    static const Element * U64(RenderScript *rs);
+    static const Element * I64(RenderScript *rs);
+    static const Element * F32(RenderScript *rs);
+    static const Element * F64(RenderScript *rs);
+    static const Element * ELEMENT(RenderScript *rs);
+    static const Element * TYPE(RenderScript *rs);
+    static const Element * ALLOCATION(RenderScript *rs);
+    static const Element * SAMPLER(RenderScript *rs);
+    static const Element * SCRIPT(RenderScript *rs);
+    static const Element * MESH(RenderScript *rs);
+    static const Element * PROGRAM_FRAGMENT(RenderScript *rs);
+    static const Element * PROGRAM_VERTEX(RenderScript *rs);
+    static const Element * PROGRAM_RASTER(RenderScript *rs);
+    static const Element * PROGRAM_STORE(RenderScript *rs);
+
+    static const Element * A_8(RenderScript *rs);
+    static const Element * RGB_565(RenderScript *rs);
+    static const Element * RGB_888(RenderScript *rs);
+    static const Element * RGBA_5551(RenderScript *rs);
+    static const Element * RGBA_4444(RenderScript *rs);
+    static const Element * RGBA_8888(RenderScript *rs);
+
+    static const Element * F32_2(RenderScript *rs);
+    static const Element * F32_3(RenderScript *rs);
+    static const Element * F32_4(RenderScript *rs);
+    static const Element * F64_2(RenderScript *rs);
+    static const Element * F64_3(RenderScript *rs);
+    static const Element * F64_4(RenderScript *rs);
+    static const Element * U8_2(RenderScript *rs);
+    static const Element * U8_3(RenderScript *rs);
+    static const Element * U8_4(RenderScript *rs);
+    static const Element * I8_2(RenderScript *rs);
+    static const Element * I8_3(RenderScript *rs);
+    static const Element * I8_4(RenderScript *rs);
+    static const Element * U16_2(RenderScript *rs);
+    static const Element * U16_3(RenderScript *rs);
+    static const Element * U16_4(RenderScript *rs);
+    static const Element * I16_2(RenderScript *rs);
+    static const Element * I16_3(RenderScript *rs);
+    static const Element * I16_4(RenderScript *rs);
+    static const Element * U32_2(RenderScript *rs);
+    static const Element * U32_3(RenderScript *rs);
+    static const Element * U32_4(RenderScript *rs);
+    static const Element * I32_2(RenderScript *rs);
+    static const Element * I32_3(RenderScript *rs);
+    static const Element * I32_4(RenderScript *rs);
+    static const Element * U64_2(RenderScript *rs);
+    static const Element * U64_3(RenderScript *rs);
+    static const Element * U64_4(RenderScript *rs);
+    static const Element * I64_2(RenderScript *rs);
+    static const Element * I64_3(RenderScript *rs);
+    static const Element * I64_4(RenderScript *rs);
+    static const Element * MATRIX_4X4(RenderScript *rs);
+    static const Element * MATRIX_3X3(RenderScript *rs);
+    static const Element * MATRIX_2X2(RenderScript *rs);
+
+    Element(void *id, RenderScript *rs,
+            android::Vector<const Element *> &elements,
+            android::Vector<android::String8> &elementNames,
+            android::Vector<uint32_t> &arraySizes);
+    Element(void *id, RenderScript *rs, RsDataType dt, RsDataKind dk, bool norm, uint32_t size);
+    Element(RenderScript *rs);
+    virtual ~Element();
+
+    void updateFromNative();
+    static const Element * createUser(RenderScript *rs, RsDataType dt);
+    static const Element * createVector(RenderScript *rs, RsDataType dt, uint32_t size);
+    static const Element * createPixel(RenderScript *rs, RsDataType dt, RsDataKind dk);
+    bool isCompatible(const Element *e);
+
+    class Builder {
+    private:
+        RenderScript *mRS;
+        android::Vector<const Element *> mElements;
+        android::Vector<android::String8> mElementNames;
+        android::Vector<uint32_t> mArraySizes;
+        bool mSkipPadding;
+
+    public:
+        Builder(RenderScript *rs);
+        ~Builder();
+        void add(const Element *, android::String8 &name, uint32_t arraySize = 1);
+        const Element * create();
+    };
+
+private:
+    void updateVisibleSubElements();
+
+    android::Vector<const Element *> mElements;
+    android::Vector<android::String8> mElementNames;
+    android::Vector<uint32_t> mArraySizes;
+    android::Vector<uint32_t> mVisibleElementMap;
+    android::Vector<uint32_t> mOffsetInBytes;
+
+    RsDataType mType;
+    RsDataKind mKind;
+    bool mNormalized;
+    size_t mSizeBytes;
+    size_t mVectorSize;
+};
+
+#endif
diff --git a/RenderScript.cpp b/RenderScript.cpp
new file mode 100644
index 0000000..58d1ce1
--- /dev/null
+++ b/RenderScript.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2008-2012 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 <utils/Log.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "RenderScript.h"
+
+bool RenderScript::gInitialized = false;
+pthread_mutex_t RenderScript::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
+
+RenderScript::RenderScript() {
+    mDev = NULL;
+    mContext = NULL;
+    mErrorFunc = NULL;
+    mMessageFunc = NULL;
+    mMessageRun = false;
+
+    memset(&mElements, 0, sizeof(mElements));
+}
+
+RenderScript::~RenderScript() {
+    mMessageRun = false;
+
+    rsContextDeinitToClient(mContext);
+
+    void *res = NULL;
+    int status = pthread_join(mMessageThreadId, &res);
+
+    rsContextDestroy(mContext);
+    mContext = NULL;
+    rsDeviceDestroy(mDev);
+    mDev = NULL;
+}
+
+bool RenderScript::init(int targetApi) {
+    mDev = rsDeviceCreate();
+    if (mDev == 0) {
+        ALOGE("Device creation failed");
+        return false;
+    }
+
+    mContext = rsContextCreate(mDev, 0, targetApi);
+    if (mContext == 0) {
+        ALOGE("Context creation failed");
+        return false;
+    }
+
+
+    pid_t mNativeMessageThreadId;
+
+    int status = pthread_create(&mMessageThreadId, NULL, threadProc, this);
+    if (status) {
+        ALOGE("Failed to start RenderScript message thread.");
+        return false;
+    }
+    // Wait for the message thread to be active.
+    while (!mMessageRun) {
+        usleep(1000);
+    }
+
+    return true;
+}
+
+void * RenderScript::threadProc(void *vrsc) {
+    RenderScript *rs = static_cast<RenderScript *>(vrsc);
+    size_t rbuf_size = 256;
+    void * rbuf = malloc(rbuf_size);
+
+    rsContextInitToClient(rs->mContext);
+    rs->mMessageRun = true;
+
+    while (rs->mMessageRun) {
+        size_t receiveLen = 0;
+        uint32_t usrID = 0;
+        uint32_t subID = 0;
+        RsMessageToClientType r = rsContextPeekMessage(rs->mContext,
+                                                       &receiveLen, sizeof(receiveLen),
+                                                       &usrID, sizeof(usrID));
+
+        if (receiveLen >= rbuf_size) {
+            rbuf_size = receiveLen + 32;
+            rbuf = realloc(rbuf, rbuf_size);
+        }
+        if (!rbuf) {
+            ALOGE("RenderScript::message handler realloc error %zu", rbuf_size);
+            // No clean way to recover now?
+        }
+        rsContextGetMessage(rs->mContext, rbuf, rbuf_size, &receiveLen, sizeof(receiveLen),
+                            &subID, sizeof(subID));
+
+        switch(r) {
+        case RS_MESSAGE_TO_CLIENT_ERROR:
+            ALOGE("RS Error %s", (const char *)rbuf);
+
+            if(rs->mMessageFunc != NULL) {
+                rs->mErrorFunc(usrID, (const char *)rbuf);
+            }
+            break;
+        case RS_MESSAGE_TO_CLIENT_EXCEPTION:
+            // teardown. But we want to avoid starving other threads during
+            // teardown by yielding until the next line in the destructor can
+            // execute to set mRun = false
+            usleep(1000);
+            break;
+        case RS_MESSAGE_TO_CLIENT_USER:
+            if(rs->mMessageFunc != NULL) {
+                rs->mMessageFunc(usrID, rbuf, receiveLen);
+            } else {
+                ALOGE("Received a message from the script with no message handler installed.");
+            }
+            break;
+
+        default:
+            ALOGE("RenderScript unknown message type %i", r);
+        }
+    }
+
+    if (rbuf) {
+        free(rbuf);
+    }
+    ALOGE("RenderScript Message thread exiting.");
+    return NULL;
+}
+
+void RenderScript::setErrorHandler(ErrorHandlerFunc_t func) {
+    mErrorFunc = func;
+}
+
+void RenderScript::setMessageHandler(MessageHandlerFunc_t func) {
+    mMessageFunc  = func;
+}
+
+void RenderScript::contextDump() {
+}
+
+void RenderScript::finish() {
+
+}
+
+
diff --git a/RenderScript.h b/RenderScript.h
new file mode 100644
index 0000000..2d352be
--- /dev/null
+++ b/RenderScript.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2008-2012 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_RENDERSCRIPT_H
+#define ANDROID_RENDERSCRIPT_H
+
+
+#include <pthread.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+#include "rs.h"
+
+class Element;
+class Type;
+class Allocation;
+
+class RenderScript {
+    friend class BaseObj;
+    friend class Allocation;
+    friend class Element;
+    friend class Type;
+
+public:
+    RenderScript();
+    virtual ~RenderScript();
+
+    typedef void (*ErrorHandlerFunc_t)(uint32_t errorNum, const char *errorText);
+    typedef void (*MessageHandlerFunc_t)(uint32_t msgNum, const void *msgData, size_t msgLen);
+
+
+    void setErrorHandler(ErrorHandlerFunc_t func);
+    ErrorHandlerFunc_t getErrorHandler() {return mErrorFunc;}
+
+    void setMessageHandler(MessageHandlerFunc_t func);
+    MessageHandlerFunc_t getMessageHandler() {return mMessageFunc;}
+
+    bool init(int targetApi);
+    void contextDump();
+    void finish();
+
+private:
+    static bool gInitialized;
+    static pthread_mutex_t gInitMutex;
+
+    pthread_t mMessageThreadId;
+    pid_t mNativeMessageThreadId;
+    bool mMessageRun;
+
+    RsDevice mDev;
+    RsContext mContext;
+
+    ErrorHandlerFunc_t mErrorFunc;
+    MessageHandlerFunc_t mMessageFunc;
+
+    struct {
+        Element *U8;
+        Element *I8;
+        Element *U16;
+        Element *I16;
+        Element *U32;
+        Element *I32;
+        Element *U64;
+        Element *I64;
+        Element *F32;
+        Element *F64;
+        Element *BOOLEAN;
+
+        Element *ELEMENT;
+        Element *TYPE;
+        Element *ALLOCATION;
+        Element *SAMPLER;
+        Element *SCRIPT;
+        Element *MESH;
+        Element *PROGRAM_FRAGMENT;
+        Element *PROGRAM_VERTEX;
+        Element *PROGRAM_RASTER;
+        Element *PROGRAM_STORE;
+
+        Element *A_8;
+        Element *RGB_565;
+        Element *RGB_888;
+        Element *RGBA_5551;
+        Element *RGBA_4444;
+        Element *RGBA_8888;
+
+        Element *FLOAT_2;
+        Element *FLOAT_3;
+        Element *FLOAT_4;
+
+        Element *DOUBLE_2;
+        Element *DOUBLE_3;
+        Element *DOUBLE_4;
+
+        Element *UCHAR_2;
+        Element *UCHAR_3;
+        Element *UCHAR_4;
+
+        Element *CHAR_2;
+        Element *CHAR_3;
+        Element *CHAR_4;
+
+        Element *USHORT_2;
+        Element *USHORT_3;
+        Element *USHORT_4;
+
+        Element *SHORT_2;
+        Element *SHORT_3;
+        Element *SHORT_4;
+
+        Element *UINT_2;
+        Element *UINT_3;
+        Element *UINT_4;
+
+        Element *INT_2;
+        Element *INT_3;
+        Element *INT_4;
+
+        Element *ULONG_2;
+        Element *ULONG_3;
+        Element *ULONG_4;
+
+        Element *LONG_2;
+        Element *LONG_3;
+        Element *LONG_4;
+
+        Element *MATRIX_4X4;
+        Element *MATRIX_3X3;
+        Element *MATRIX_2X2;
+    } mElements;
+
+
+
+
+    static void * threadProc(void *);
+
+};
+
+#endif
+
diff --git a/Type.cpp b/Type.cpp
new file mode 100644
index 0000000..3249f97
--- /dev/null
+++ b/Type.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2008 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 <utils/Log.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "RenderScript.h"
+#include "Element.h"
+#include "Type.h"
+
+void Type::calcElementCount() {
+    bool hasLod = hasMipmaps();
+    uint32_t x = getX();
+    uint32_t y = getY();
+    uint32_t z = getZ();
+    uint32_t faces = 1;
+    if (hasFaces()) {
+        faces = 6;
+    }
+    if (x == 0) {
+        x = 1;
+    }
+    if (y == 0) {
+        y = 1;
+    }
+    if (z == 0) {
+        z = 1;
+    }
+
+    uint32_t count = x * y * z * faces;
+    while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
+        if(x > 1) {
+            x >>= 1;
+        }
+        if(y > 1) {
+            y >>= 1;
+        }
+        if(z > 1) {
+            z >>= 1;
+        }
+
+        count += x * y * z * faces;
+    }
+    mElementCount = count;
+}
+
+
+Type::Type(void *id, RenderScript *rs) : BaseObj(id, rs) {
+    mDimX = 0;
+    mDimY = 0;
+    mDimZ = 0;
+    mDimMipmaps = false;
+    mDimFaces = false;
+    mElement = NULL;
+}
+
+void Type::updateFromNative() {
+    // We have 6 integer to obtain mDimX; mDimY; mDimZ;
+    // mDimLOD; mDimFaces; mElement;
+
+    /*
+    int[] dataBuffer = new int[6];
+    mRS.nTypeGetNativeData(getID(), dataBuffer);
+
+    mDimX = dataBuffer[0];
+    mDimY = dataBuffer[1];
+    mDimZ = dataBuffer[2];
+    mDimMipmaps = dataBuffer[3] == 1 ? true : false;
+    mDimFaces = dataBuffer[4] == 1 ? true : false;
+
+    int elementID = dataBuffer[5];
+    if(elementID != 0) {
+        mElement = new Element(elementID, mRS);
+        mElement.updateFromNative();
+    }
+    calcElementCount();
+    */
+}
+
+Type::Builder::Builder(RenderScript *rs, const Element *e) {
+    mRS = rs;
+    mElement = e;
+    mDimX = 0;
+    mDimY = 0;
+    mDimZ = 0;
+    mDimMipmaps = false;
+    mDimFaces = false;
+}
+
+void Type::Builder::setX(uint32_t value) {
+    if(value < 1) {
+        ALOGE("Values of less than 1 for Dimension X are not valid.");
+    }
+    mDimX = value;
+}
+
+void Type::Builder::setY(int value) {
+    if(value < 1) {
+        ALOGE("Values of less than 1 for Dimension Y are not valid.");
+    }
+    mDimY = value;
+}
+
+void Type::Builder::setMipmaps(bool value) {
+    mDimMipmaps = value;
+}
+
+void Type::Builder::setFaces(bool value) {
+    mDimFaces = value;
+}
+
+const Type * Type::Builder::create() {
+    ALOGE(" %i %i %i %i %i", mDimX, mDimY, mDimZ, mDimFaces, mDimMipmaps);
+    if (mDimZ > 0) {
+        if ((mDimX < 1) || (mDimY < 1)) {
+            ALOGE("Both X and Y dimension required when Z is present.");
+        }
+        if (mDimFaces) {
+            ALOGE("Cube maps not supported with 3D types.");
+        }
+    }
+    if (mDimY > 0) {
+        if (mDimX < 1) {
+            ALOGE("X dimension required when Y is present.");
+        }
+    }
+    if (mDimFaces) {
+        if (mDimY < 1) {
+            ALOGE("Cube maps require 2D Types.");
+        }
+    }
+
+    void * id = rsTypeCreate(mRS->mContext, mElement->getID(), mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces);
+    Type *t = new Type(id, mRS);
+    t->mElement = mElement;
+    t->mDimX = mDimX;
+    t->mDimY = mDimY;
+    t->mDimZ = mDimZ;
+    t->mDimMipmaps = mDimMipmaps;
+    t->mDimFaces = mDimFaces;
+
+    t->calcElementCount();
+    return t;
+}
+
diff --git a/Type.h b/Type.h
new file mode 100644
index 0000000..fb4e8b1
--- /dev/null
+++ b/Type.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 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_TYPE_H__
+#define __ANDROID_TYPE_H__
+
+#include <rs.h>
+#include "RenderScript.h"
+#include "BaseObj.h"
+
+class Type : public BaseObj {
+protected:
+    friend class Allocation;
+
+    uint32_t mDimX;
+    uint32_t mDimY;
+    uint32_t mDimZ;
+    bool mDimMipmaps;
+    bool mDimFaces;
+    size_t mElementCount;
+    const Element *mElement;
+
+    void calcElementCount();
+    virtual void updateFromNative();
+
+public:
+
+    const Element* getElement() const {
+        return mElement;
+    }
+
+    uint32_t getX() const {
+        return mDimX;
+    }
+
+    uint32_t getY() const {
+        return mDimY;
+    }
+
+    uint32_t getZ() const {
+        return mDimZ;
+    }
+
+    bool hasMipmaps() const {
+        return mDimMipmaps;
+    }
+
+    bool hasFaces() const {
+        return mDimFaces;
+    }
+
+    size_t getCount() const {
+        return mElementCount;
+    }
+
+    size_t getSizeBytes() const {
+        return mElementCount * mElement->getSizeBytes();
+    }
+
+
+    Type(void *id, RenderScript *rs);
+
+
+    class Builder {
+    protected:
+        RenderScript *mRS;
+        uint32_t mDimX;
+        uint32_t mDimY;
+        uint32_t mDimZ;
+        bool mDimMipmaps;
+        bool mDimFaces;
+        const Element *mElement;
+
+    public:
+        Builder(RenderScript *rs, const Element *e);
+
+        void setX(uint32_t value);
+        void setY(int value);
+        void setMipmaps(bool value);
+        void setFaces(bool value);
+        const Type * create();
+    };
+
+};
+
+#endif
diff --git a/tests/Android.mk b/tests/Android.mk
new file mode 100644
index 0000000..a773e84
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,29 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	compute.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libRS \
+	libz \
+	libcutils \
+	libutils \
+	libEGL \
+	libGLESv1_CM \
+	libGLESv2 \
+	libui \
+	libbcc \
+	libbcinfo \
+	libgui
+
+LOCAL_MODULE:= rstest-compute
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_C_INCLUDES +=  .. \
+	frameworks/base/libs/rs \
+	out/target/product/stingray/obj/SHARED_LIBRARIES/libRS_intermediates	
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/tests/compute.cpp b/tests/compute.cpp
new file mode 100644
index 0000000..702b974
--- /dev/null
+++ b/tests/compute.cpp
@@ -0,0 +1,41 @@
+
+#include "RenderScript.h"
+#include "Element.h"
+#include "Type.h"
+#include "Allocation.h"
+
+int main(int argc, char** argv)
+{
+
+    RenderScript *rs = new RenderScript();
+    printf("New RS %p\n", rs);
+
+    //usleep(100000);
+
+    bool r = rs->init(16);
+    printf("Init returned %i\n", r);
+
+    const Element *e = Element::RGBA_8888(rs);
+    printf("Element %p\n", e);
+
+    Type::Builder tb(rs, e);
+    tb.setX(128);
+    tb.setY(128);
+    const Type *t = tb.create();
+    printf("Type %p\n", t);
+
+
+    const Allocation *a1 = Allocation::createSized(rs, e, 1000);
+    printf("Allocation %p\n", a1);
+
+
+    //usleep(1000000);
+
+
+    printf("Deleting stuff\n");
+    delete t;
+    delete a1;
+    delete e;
+    delete rs;
+    printf("Delete OK\n");
+}
