diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 37a270e..6539ff3 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -534,6 +534,7 @@
      * @param fp
      */
     public void setFromFieldPacker(int xoff, FieldPacker fp) {
+        mRS.validate();
         int eSize = mType.mElement.getSizeBytes();
         final byte[] data = fp.getData();
 
@@ -554,6 +555,7 @@
      * @param fp
      */
     public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
+        mRS.validate();
         if (component_number >= mType.mElement.mElements.length) {
             throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
         }
diff --git a/libs/rs/Allocation.cpp b/libs/rs/Allocation.cpp
new file mode 100644
index 0000000..46df171
--- /dev/null
+++ b/libs/rs/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/libs/rs/Allocation.h b/libs/rs/Allocation.h
new file mode 100644
index 0000000..059e61d
--- /dev/null
+++ b/libs/rs/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/libs/rs/Android.mk b/libs/rs/Android.mk
index 9c5d06b..b7cc177 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/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/libs/rs/BaseObj.cpp b/libs/rs/BaseObj.cpp
new file mode 100644
index 0000000..b2f5450
--- /dev/null
+++ b/libs/rs/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/libs/rs/BaseObj.h b/libs/rs/BaseObj.h
new file mode 100644
index 0000000..91f3714
--- /dev/null
+++ b/libs/rs/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/libs/rs/Element.cpp b/libs/rs/Element.cpp
new file mode 100644
index 0000000..c621c82
--- /dev/null
+++ b/libs/rs/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/libs/rs/Element.h b/libs/rs/Element.h
new file mode 100644
index 0000000..a579dc3
--- /dev/null
+++ b/libs/rs/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/libs/rs/RenderScript.cpp b/libs/rs/RenderScript.cpp
new file mode 100644
index 0000000..58d1ce1
--- /dev/null
+++ b/libs/rs/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/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
new file mode 100644
index 0000000..2d352be
--- /dev/null
+++ b/libs/rs/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/libs/rs/Type.cpp b/libs/rs/Type.cpp
new file mode 100644
index 0000000..3249f97
--- /dev/null
+++ b/libs/rs/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/libs/rs/Type.h b/libs/rs/Type.h
new file mode 100644
index 0000000..fb4e8b1
--- /dev/null
+++ b/libs/rs/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/libs/rs/tests/Android.mk b/libs/rs/tests/Android.mk
new file mode 100644
index 0000000..a773e84
--- /dev/null
+++ b/libs/rs/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/libs/rs/tests/compute.cpp b/libs/rs/tests/compute.cpp
new file mode 100644
index 0000000..702b974
--- /dev/null
+++ b/libs/rs/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");
+}
