Merge commit 'f5ecac92' into manualmerge

Conflicts:
	driver/rsdBcc.cpp

Change-Id: I04a06c157165a77f3c5edffa637b9e42a02ef617
diff --git a/cpp/Allocation.cpp b/cpp/Allocation.cpp
index d6f79b0..121d88d 100644
--- a/cpp/Allocation.cpp
+++ b/cpp/Allocation.cpp
@@ -14,23 +14,12 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "libRS_cpp"
-
-#include <utils/Log.h>
-#include <malloc.h>
-
 #include "RenderScript.h"
-#include "Element.h"
-#include "Type.h"
-#include "Allocation.h"
 
 using namespace android;
-using namespace renderscriptCpp;
+using namespace RSC;
 
 void * Allocation::getIDSafe() const {
-    //if (mAdaptedAllocation != NULL) {
-        //return mAdaptedAllocation.getID();
-    //}
     return getID();
 }
 
@@ -47,8 +36,9 @@
     }
 }
 
-Allocation::Allocation(void *id, RenderScript *rs, sp<const Type> t, uint32_t usage) :
-        BaseObj(id, rs) {
+Allocation::Allocation(void *id, sp<RS> rs, sp<const Type> t, uint32_t usage) :
+    BaseObj(id, rs), mSelectedY(0), mSelectedZ(0), mSelectedLOD(0),
+    mSelectedFace(RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X) {
 
     if ((usage & ~(RS_ALLOCATION_USAGE_SCRIPT |
                    RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
@@ -129,7 +119,7 @@
 void Allocation::updateFromNative() {
     BaseObj::updateFromNative();
 
-    const void *typeID = rsaAllocationGetType(mRS->mContext, getID());
+    const void *typeID = rsaAllocationGetType(mRS->getContext(), getID());
     if(typeID != NULL) {
         sp<const Type> old = mType;
         sp<Type> t = new Type((void *)typeID, mRS);
@@ -149,82 +139,28 @@
     default:
         ALOGE("Source must be exactly one usage type.");
     }
-    rsAllocationSyncAll(mRS->mContext, getIDSafe(), srcLocation);
+    rsAllocationSyncAll(mRS->getContext(), 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());
+    rsAllocationIoSend(mRS->getContext(), 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());
+    rsAllocationIoReceive(mRS->getContext(), 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());
+    rsAllocationGenerateMipmaps(mRS->getContext(), getID());
 }
 
-void Allocation::copy1DRangeFromUnchecked(uint32_t off, size_t count, const void *data,
+void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const void *data,
         size_t dataLen) {
 
     if(count < 1) {
@@ -240,33 +176,29 @@
         return;
     }
 
-    rsAllocation1DData(mRS->mContext, getIDSafe(), off, mSelectedLOD, count, data, dataLen);
+    rsAllocation1DData(mRS->getContext(), 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::copy1DRangeTo(uint32_t off, size_t count, 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;
+    }
+    rsAllocation1DRead(mRS->getContext(), getIDSafe(), off, mSelectedLOD, count, data, 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, sp<const Allocation> data,
+                                 uint32_t dataOff) {
 
-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,
+    rsAllocationCopy2DRange(mRS->getContext(), getIDSafe(), off, 0,
                             mSelectedLOD, mSelectedFace,
                             count, 1, data->getIDSafe(), dataOff, 0,
                             data->mSelectedLOD, data->mSelectedFace);
@@ -283,68 +215,23 @@
 }
 
 void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
-                                 const int8_t *data, size_t dataLen) {
+                                 const void *data, size_t dataLen) {
     validate2DRange(xoff, yoff, w, h);
-    rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
+    rsAllocation2DData(mRS->getContext(), 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,
+                                 sp<const Allocation> data, size_t dataLen,
                                  uint32_t dataXoff, uint32_t dataYoff) {
     validate2DRange(xoff, yoff, w, h);
-    rsAllocationCopy2DRange(mRS->mContext, getIDSafe(), xoff, yoff,
+    rsAllocationCopy2DRange(mRS->getContext(), 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.");
@@ -378,9 +265,9 @@
 */
 
 
-android::sp<Allocation> Allocation::createTyped(RenderScript *rs, sp<const Type> type,
-                        RsAllocationMipmapControl mips, uint32_t usage) {
-    void *id = rsAllocationCreateTyped(rs->mContext, type->getID(), mips, usage, 0);
+android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
+                                                RsAllocationMipmapControl mips, uint32_t usage) {
+    void *id = rsAllocationCreateTyped(rs->getContext(), type->getID(), mips, usage, 0);
     if (id == 0) {
         ALOGE("Allocation creation failed.");
         return NULL;
@@ -388,92 +275,37 @@
     return new Allocation(id, rs, type, usage);
 }
 
-android::sp<Allocation> Allocation::createTyped(RenderScript *rs, sp<const Type> type,
-                                    RsAllocationMipmapControl mips, uint32_t usage, void *pointer) {
-    void *id = rsAllocationCreateTyped(rs->mContext, type->getID(), mips, usage, (uint32_t)pointer);
+android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
+                                                RsAllocationMipmapControl mips, uint32_t usage,
+                                                void *pointer) {
+    void *id = rsAllocationCreateTyped(rs->getContext(), type->getID(), mips, usage,
+                                       (uint32_t)pointer);
     if (id == 0) {
         ALOGE("Allocation creation failed.");
     }
     return new Allocation(id, rs, type, usage);
 }
 
-android::sp<Allocation> Allocation::createTyped(RenderScript *rs, sp<const Type> type,
-        uint32_t usage) {
+android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
+                                                uint32_t usage) {
     return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage);
 }
 
-android::sp<Allocation> Allocation::createSized(RenderScript *rs, sp<const Element> e,
-        size_t count, uint32_t usage) {
-
+android::sp<Allocation> Allocation::createSized(sp<RS> rs, sp<const Element> e,
+                                                size_t count, uint32_t usage) {
     Type::Builder b(rs, e);
     b.setX(count);
     sp<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);
+    return createTyped(rs, t, usage);
 }
 
+android::sp<Allocation> Allocation::createSized2D(sp<RS> rs, sp<const Element> e,
+                                                  size_t x, size_t y, uint32_t usage) {
+    Type::Builder b(rs, e);
+    b.setX(x);
+    b.setY(y);
+    sp<const Type> t = b.create();
 
-/*
-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);
-
+    return createTyped(rs, t, usage);
 }
-
-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/cpp/Allocation.h b/cpp/Allocation.h
deleted file mode 100644
index 7a893f8..0000000
--- a/cpp/Allocation.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 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_ALLOCATION_H__
-#define __ANDROID_ALLOCATION_H__
-
-#include <pthread.h>
-#include <rs.h>
-
-#include "RenderScript.h"
-#include "Type.h"
-#include "Element.h"
-
-namespace android {
-namespace renderscriptCpp {
-
-class Allocation : public BaseObj {
-protected:
-    android::sp<const Type> mType;
-    uint32_t mUsage;
-    android::sp<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(sp<const Type> t);
-
-    Allocation(void *id, RenderScript *rs, sp<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:
-    android::sp<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 sp<Allocation> createTyped(RenderScript *rs, sp<const Type> type,
-                                   RsAllocationMipmapControl mips, uint32_t usage);
-    static sp<Allocation> createTyped(RenderScript *rs, sp<const Type> type,
-                                   RsAllocationMipmapControl mips, uint32_t usage, void * pointer);
-
-    static sp<Allocation> createTyped(RenderScript *rs, sp<const Type> type,
-                                   uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);
-    static sp<Allocation> createSized(RenderScript *rs, sp<const Element> e, size_t count,
-                                   uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);
-    //SurfaceTexture *getSurfaceTexture();
-    //void setSurfaceTexture(SurfaceTexture *sur);
-
-};
-
-}
-}
-
-#endif
diff --git a/cpp/Android.mk b/cpp/Android.mk
index ada2866..1fba998 100644
--- a/cpp/Android.mk
+++ b/cpp/Android.mk
@@ -1,6 +1,18 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
+ifeq "REL" "$(PLATFORM_VERSION_CODENAME)"
+  RS_VERSION := $(PLATFORM_SDK_VERSION)
+else
+  # Increment by 1 whenever this is not a final release build, since we want to
+  # be able to see the RS version number change during development.
+  # See build/core/version_defaults.mk for more information about this.
+  RS_VERSION := "(1 + $(PLATFORM_SDK_VERSION))"
+endif
+local_cflags_for_rs_cpp += -DRS_VERSION=$(RS_VERSION)
+
+LOCAL_CFLAGS += $(local_cflags_for_rs_cpp)
+
 LOCAL_SRC_FILES:= \
 	RenderScript.cpp \
 	BaseObj.cpp \
@@ -8,7 +20,8 @@
 	Type.cpp \
 	Allocation.cpp \
 	Script.cpp \
-	ScriptC.cpp
+	ScriptC.cpp \
+	ScriptIntrinsics.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libRS \
diff --git a/cpp/BaseObj.cpp b/cpp/BaseObj.cpp
index a370e8d..bb92bce 100644
--- a/cpp/BaseObj.cpp
+++ b/cpp/BaseObj.cpp
@@ -16,13 +16,10 @@
 
 #define LOG_TAG "libRS_cpp"
 
-#include <rs.h>
-
 #include "RenderScript.h"
-#include "BaseObj.h"
 
 using namespace android;
-using namespace renderscriptCpp;
+using namespace RSC;
 
 void * BaseObj::getID() const {
     if (mID == NULL) {
@@ -36,7 +33,7 @@
 }
 
 
-BaseObj::BaseObj(void *id, RenderScript *rs) {
+BaseObj::BaseObj(void *id, sp<RS> rs) {
     mRS = rs;
     mID = id;
 }
@@ -48,14 +45,14 @@
 }
 
 BaseObj::~BaseObj() {
-    rsObjDestroy(mRS->mContext, mID);
+    rsObjDestroy(mRS->getContext(), mID);
     mRS = NULL;
     mID = NULL;
 }
 
 void BaseObj::updateFromNative() {
     const char *name = NULL;
-    rsaGetName(mRS, mID, &name);
+    rsaGetName(mRS->getContext(), mID, &name);
     mName = name;
 }
 
@@ -65,6 +62,3 @@
         return true;
     return mID == obj->mID;
 }
-
-
-
diff --git a/cpp/BaseObj.h b/cpp/BaseObj.h
deleted file mode 100644
index 23ae85c..0000000
--- a/cpp/BaseObj.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 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 "utils/RefBase.h"
-#include <pthread.h>
-#include <rs.h>
-
-#include "RenderScript.h"
-
-namespace android {
-namespace renderscriptCpp {
-
-
-class BaseObj : public android::LightRefBase<BaseObj> {
-protected:
-    friend class Element;
-    friend class Type;
-    friend class Allocation;
-    friend class Script;
-    friend class ScriptC;
-
-    void *mID;
-    RenderScript *mRS;
-    android::String8 mName;
-
-    void * getID() const;
-
-    BaseObj(void *id, RenderScript *rs);
-    void checkValid();
-
-    static void * getObjID(sp<const BaseObj> o);
-
-public:
-
-    virtual ~BaseObj();
-    virtual void updateFromNative();
-    virtual bool equals(const BaseObj *obj);
-};
-
-}
-}
-#endif
diff --git a/cpp/Element.cpp b/cpp/Element.cpp
index 2be4166..198aac8 100644
--- a/cpp/Element.cpp
+++ b/cpp/Element.cpp
@@ -14,17 +14,13 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "libRS_cpp"
-
-#include <utils/Log.h>
 #include <malloc.h>
 #include <string.h>
 
 #include "RenderScript.h"
-#include "Element.h"
 
 using namespace android;
-using namespace renderscriptCpp;
+using namespace RSC;
 
 sp<const Element> Element::getSubElement(uint32_t index) {
     if (!mVisibleElementMap.size()) {
@@ -67,7 +63,7 @@
 }
 
 
-#define CREATE_USER(N, T) sp<const Element> Element::N(RenderScript *rs) { \
+#define CREATE_USER(N, T) sp<const Element> Element::N(sp<RS> rs) { \
     return createUser(rs, RS_TYPE_##T); \
 }
 CREATE_USER(BOOLEAN, BOOLEAN);
@@ -95,7 +91,7 @@
 CREATE_USER(MATRIX_3X3, MATRIX_3X3);
 CREATE_USER(MATRIX_2X2, MATRIX_2X2);
 
-#define CREATE_PIXEL(N, T, K) sp<const Element> Element::N(RenderScript *rs) { \
+#define CREATE_PIXEL(N, T, K) sp<const Element> Element::N(sp<RS> rs) { \
     return createPixel(rs, RS_TYPE_##T, RS_KIND_##K); \
 }
 CREATE_PIXEL(A_8, UNSIGNED_8, PIXEL_A);
@@ -104,13 +100,13 @@
 CREATE_PIXEL(RGBA_4444, UNSIGNED_4_4_4_4, PIXEL_RGBA);
 CREATE_PIXEL(RGBA_8888, UNSIGNED_8, PIXEL_RGBA);
 
-#define CREATE_VECTOR(N, T) sp<const Element> Element::N##_2(RenderScript *rs) { \
+#define CREATE_VECTOR(N, T) sp<const Element> Element::N##_2(sp<RS> rs) { \
     return createVector(rs, RS_TYPE_##T, 2); \
 } \
-sp<const Element> Element::N##_3(RenderScript *rs) { \
+sp<const Element> Element::N##_3(sp<RS> rs) { \
     return createVector(rs, RS_TYPE_##T, 3); \
 } \
-sp<const Element> Element::N##_4(RenderScript *rs) { \
+sp<const Element> Element::N##_4(sp<RS> rs) { \
     return createVector(rs, RS_TYPE_##T, 4); \
 }
 CREATE_VECTOR(U8, UNSIGNED_8);
@@ -148,8 +144,8 @@
     }
 }
 
-Element::Element(void *id, RenderScript *rs,
-                 android::Vector<sp</*const*/ Element> > &elements,
+Element::Element(void *id, sp<RS> rs,
+                 android::Vector<sp<Element> > &elements,
                  android::Vector<android::String8> &elementNames,
                  android::Vector<uint32_t> &arraySizes) : BaseObj(id, rs) {
     mSizeBytes = 0;
@@ -222,7 +218,7 @@
     return 0;
 }
 
-Element::Element(void *id, RenderScript *rs,
+Element::Element(void *id, sp<RS> rs,
                  RsDataType dt, RsDataKind dk, bool norm, uint32_t size) :
     BaseObj(id, rs)
 {
@@ -247,68 +243,25 @@
 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();
 }
 
-sp<const Element> Element::createUser(RenderScript *rs, RsDataType dt) {
-    void * id = rsElementCreate(rs->mContext, dt, RS_KIND_USER, false, 1);
+sp<const Element> Element::createUser(sp<RS> rs, RsDataType dt) {
+    void * id = rsElementCreate(rs->getContext(), dt, RS_KIND_USER, false, 1);
     return new Element(id, rs, dt, RS_KIND_USER, false, 1);
 }
 
-sp<const Element> Element::createVector(RenderScript *rs, RsDataType dt, uint32_t size) {
+sp<const Element> Element::createVector(sp<RS> rs, RsDataType dt, uint32_t size) {
     if (size < 2 || size > 4) {
         rs->throwError("Vector size out of range 2-4.");
     }
-    void *id = rsElementCreate(rs->mContext, dt, RS_KIND_USER, false, size);
+    void *id = rsElementCreate(rs->getContext(), dt, RS_KIND_USER, false, size);
     return new Element(id, rs, dt, RS_KIND_USER, false, size);
 }
 
-sp<const Element> Element::createPixel(RenderScript *rs, RsDataType dt, RsDataKind dk) {
+sp<const Element> Element::createPixel(sp<RS> rs, RsDataType dt, RsDataKind dk) {
     if (!(dk == RS_KIND_PIXEL_L ||
           dk == RS_KIND_PIXEL_A ||
           dk == RS_KIND_PIXEL_LA ||
@@ -355,7 +308,7 @@
         break;
     }
 
-    void * id = rsElementCreate(rs->mContext, dt, dk, true, size);
+    void * id = rsElementCreate(rs->getContext(), dt, dk, true, size);
     return new Element(id, rs, dt, dk, true, size);
 }
 
@@ -375,7 +328,7 @@
             (mVectorSize == e->mVectorSize));
 }
 
-Element::Builder::Builder(RenderScript *rs) {
+Element::Builder::Builder(sp<RS> rs) {
     mRS = rs;
     mSkipPadding = false;
 }
@@ -417,7 +370,7 @@
         sizeArray[ct] = mElementNames[ct].length();
     }
 
-    void *id = rsElementCreate2(mRS->mContext,
+    void *id = rsElementCreate2(mRS->getContext(),
                                 (RsElement *)elementArray, fieldCount,
                                 nameArray, fieldCount * sizeof(size_t),  sizeArray,
                                 (const uint32_t *)mArraySizes.array(), fieldCount);
diff --git a/cpp/Element.h b/cpp/Element.h
deleted file mode 100644
index dea3570..0000000
--- a/cpp/Element.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 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"
-
-namespace android {
-namespace renderscriptCpp {
-
-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
-    */
-    sp<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 sp<const Element> BOOLEAN(RenderScript *rs);
-    static sp<const Element> U8(RenderScript *rs);
-    static sp<const Element> I8(RenderScript *rs);
-    static sp<const Element> U16(RenderScript *rs);
-    static sp<const Element> I16(RenderScript *rs);
-    static sp<const Element> U32(RenderScript *rs);
-    static sp<const Element> I32(RenderScript *rs);
-    static sp<const Element> U64(RenderScript *rs);
-    static sp<const Element> I64(RenderScript *rs);
-    static sp<const Element> F32(RenderScript *rs);
-    static sp<const Element> F64(RenderScript *rs);
-    static sp<const Element> ELEMENT(RenderScript *rs);
-    static sp<const Element> TYPE(RenderScript *rs);
-    static sp<const Element> ALLOCATION(RenderScript *rs);
-    static sp<const Element> SAMPLER(RenderScript *rs);
-    static sp<const Element> SCRIPT(RenderScript *rs);
-    static sp<const Element> MESH(RenderScript *rs);
-    static sp<const Element> PROGRAM_FRAGMENT(RenderScript *rs);
-    static sp<const Element> PROGRAM_VERTEX(RenderScript *rs);
-    static sp<const Element> PROGRAM_RASTER(RenderScript *rs);
-    static sp<const Element> PROGRAM_STORE(RenderScript *rs);
-
-    static sp<const Element> A_8(RenderScript *rs);
-    static sp<const Element> RGB_565(RenderScript *rs);
-    static sp<const Element> RGB_888(RenderScript *rs);
-    static sp<const Element> RGBA_5551(RenderScript *rs);
-    static sp<const Element> RGBA_4444(RenderScript *rs);
-    static sp<const Element> RGBA_8888(RenderScript *rs);
-
-    static sp<const Element> F32_2(RenderScript *rs);
-    static sp<const Element> F32_3(RenderScript *rs);
-    static sp<const Element> F32_4(RenderScript *rs);
-    static sp<const Element> F64_2(RenderScript *rs);
-    static sp<const Element> F64_3(RenderScript *rs);
-    static sp<const Element> F64_4(RenderScript *rs);
-    static sp<const Element> U8_2(RenderScript *rs);
-    static sp<const Element> U8_3(RenderScript *rs);
-    static sp<const Element> U8_4(RenderScript *rs);
-    static sp<const Element> I8_2(RenderScript *rs);
-    static sp<const Element> I8_3(RenderScript *rs);
-    static sp<const Element> I8_4(RenderScript *rs);
-    static sp<const Element> U16_2(RenderScript *rs);
-    static sp<const Element> U16_3(RenderScript *rs);
-    static sp<const Element> U16_4(RenderScript *rs);
-    static sp<const Element> I16_2(RenderScript *rs);
-    static sp<const Element> I16_3(RenderScript *rs);
-    static sp<const Element> I16_4(RenderScript *rs);
-    static sp<const Element> U32_2(RenderScript *rs);
-    static sp<const Element> U32_3(RenderScript *rs);
-    static sp<const Element> U32_4(RenderScript *rs);
-    static sp<const Element> I32_2(RenderScript *rs);
-    static sp<const Element> I32_3(RenderScript *rs);
-    static sp<const Element> I32_4(RenderScript *rs);
-    static sp<const Element> U64_2(RenderScript *rs);
-    static sp<const Element> U64_3(RenderScript *rs);
-    static sp<const Element> U64_4(RenderScript *rs);
-    static sp<const Element> I64_2(RenderScript *rs);
-    static sp<const Element> I64_3(RenderScript *rs);
-    static sp<const Element> I64_4(RenderScript *rs);
-    static sp<const Element> MATRIX_4X4(RenderScript *rs);
-    static sp<const Element> MATRIX_3X3(RenderScript *rs);
-    static sp<const Element> MATRIX_2X2(RenderScript *rs);
-
-    Element(void *id, RenderScript *rs,
-            android::Vector<sp</*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 sp<const Element> createUser(RenderScript *rs, RsDataType dt);
-    static sp<const Element> createVector(RenderScript *rs, RsDataType dt, uint32_t size);
-    static sp<const Element> createPixel(RenderScript *rs, RsDataType dt, RsDataKind dk);
-    bool isCompatible(sp<const Element>e);
-
-    class Builder {
-    private:
-        RenderScript *mRS;
-        android::Vector<sp</*const*/ Element> > mElements;
-        android::Vector<android::String8> mElementNames;
-        android::Vector<uint32_t> mArraySizes;
-        bool mSkipPadding;
-
-    public:
-        Builder(RenderScript *rs);
-        ~Builder();
-        void add(sp</*const*/ Element>, android::String8 &name, uint32_t arraySize = 1);
-        sp<const Element> create();
-    };
-
-private:
-    void updateVisibleSubElements();
-
-    android::Vector<sp</*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/cpp/RenderScript.cpp b/cpp/RenderScript.cpp
index 889f27b..ffc0ce6 100644
--- a/cpp/RenderScript.cpp
+++ b/cpp/RenderScript.cpp
@@ -19,17 +19,18 @@
 #include <utils/Log.h>
 #include <malloc.h>
 #include <string.h>
+#include <pthread.h>
 
 #include "RenderScript.h"
 #include "rs.h"
 
 using namespace android;
-using namespace renderscriptCpp;
+using namespace RSC;
 
-bool RenderScript::gInitialized = false;
-pthread_mutex_t RenderScript::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
+bool RS::gInitialized = false;
+pthread_mutex_t RS::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
 
-RenderScript::RenderScript() {
+RS::RS() {
     mDev = NULL;
     mContext = NULL;
     mErrorFunc = NULL;
@@ -39,7 +40,7 @@
     memset(&mElements, 0, sizeof(mElements));
 }
 
-RenderScript::~RenderScript() {
+RS::~RS() {
     mMessageRun = false;
 
     rsContextDeinitToClient(mContext);
@@ -53,25 +54,28 @@
     mDev = NULL;
 }
 
-bool RenderScript::init(int targetApi) {
+bool RS::init(bool forceCpu) {
+    return RS::init(RS_VERSION, forceCpu);
+}
+
+bool RS::init(int targetApi, bool forceCpu) {
     mDev = rsDeviceCreate();
     if (mDev == 0) {
         ALOGE("Device creation failed");
         return false;
     }
 
-    mContext = rsContextCreate(mDev, 0, targetApi);
+    mContext = rsContextCreate(mDev, 0, targetApi, forceCpu);
     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.");
+        ALOGE("Failed to start RS message thread.");
         return false;
     }
     // Wait for the message thread to be active.
@@ -82,15 +86,15 @@
     return true;
 }
 
-void RenderScript::throwError(const char *err) const {
+void RS::throwError(const char *err) const {
     ALOGE("RS CPP error: %s", err);
     int * v = NULL;
     v[0] = 0;
 }
 
 
-void * RenderScript::threadProc(void *vrsc) {
-    RenderScript *rs = static_cast<RenderScript *>(vrsc);
+void * RS::threadProc(void *vrsc) {
+    RS *rs = static_cast<RS *>(vrsc);
     size_t rbuf_size = 256;
     void * rbuf = malloc(rbuf_size);
 
@@ -110,7 +114,7 @@
             rbuf = realloc(rbuf, rbuf_size);
         }
         if (!rbuf) {
-            ALOGE("RenderScript::message handler realloc error %zu", rbuf_size);
+            ALOGE("RS::message handler realloc error %zu", rbuf_size);
             // No clean way to recover now?
         }
         rsContextGetMessage(rs->mContext, rbuf, rbuf_size, &receiveLen, sizeof(receiveLen),
@@ -139,30 +143,25 @@
             break;
 
         default:
-            ALOGE("RenderScript unknown message type %i", r);
+            ALOGE("RS unknown message type %i", r);
         }
     }
 
     if (rbuf) {
         free(rbuf);
     }
-    ALOGE("RenderScript Message thread exiting.");
+    ALOGE("RS Message thread exiting.");
     return NULL;
 }
 
-void RenderScript::setErrorHandler(ErrorHandlerFunc_t func) {
+void RS::setErrorHandler(ErrorHandlerFunc_t func) {
     mErrorFunc = func;
 }
 
-void RenderScript::setMessageHandler(MessageHandlerFunc_t func) {
+void RS::setMessageHandler(MessageHandlerFunc_t func) {
     mMessageFunc  = func;
 }
 
-void RenderScript::contextDump() {
+void RS::finish() {
+    rsContextFinish(mContext);
 }
-
-void RenderScript::finish() {
-
-}
-
-
diff --git a/cpp/RenderScript.h b/cpp/RenderScript.h
index e6e7279..9e74922 100644
--- a/cpp/RenderScript.h
+++ b/cpp/RenderScript.h
@@ -17,145 +17,7 @@
 #ifndef ANDROID_RENDERSCRIPT_H
 #define ANDROID_RENDERSCRIPT_H
 
-
-#include <pthread.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
-
 #include "rsDefines.h"
+#include "rsCppStructs.h"
 
-namespace android {
-namespace renderscriptCpp {
-
-class Element;
-class Type;
-class Allocation;
-
-class RenderScript {
-    friend class BaseObj;
-    friend class Allocation;
-    friend class Element;
-    friend class Type;
-    friend class Script;
-    friend class ScriptC;
-
-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;
-
-
-
-    void throwError(const char *err) const;
-
-    static void * threadProc(void *);
-
-};
-
-}
-}
 #endif
-
diff --git a/cpp/Script.cpp b/cpp/Script.cpp
index 63d5fab..09d541d 100644
--- a/cpp/Script.cpp
+++ b/cpp/Script.cpp
@@ -14,22 +14,16 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "libRS_cpp"
-
 #include <utils/Log.h>
 #include <malloc.h>
 
 #include "RenderScript.h"
-#include "Element.h"
-#include "Type.h"
-#include "Allocation.h"
-#include "Script.h"
 
 using namespace android;
-using namespace renderscriptCpp;
+using namespace RSC;
 
 void Script::invoke(uint32_t slot, const void *v, size_t len) const {
-    rsScriptInvokeV(mRS->mContext, getID(), slot, v, len);
+    rsScriptInvokeV(mRS->getContext(), getID(), slot, v, len);
 }
 
 void Script::forEach(uint32_t slot, sp<const Allocation> ain, sp<const Allocation> aout,
@@ -39,34 +33,28 @@
     }
     void *in_id = BaseObj::getObjID(ain);
     void *out_id = BaseObj::getObjID(aout);
-    rsScriptForEach(mRS->mContext, getID(), slot, in_id, out_id, usr, usrLen);
+    rsScriptForEach(mRS->getContext(), getID(), slot, in_id, out_id, usr, usrLen);
 }
 
 
-Script::Script(void *id, RenderScript *rs) : BaseObj(id, rs) {
+Script::Script(void *id, sp<RS> rs) : BaseObj(id, rs) {
 }
 
 
 void Script::bindAllocation(sp<Allocation> va, uint32_t slot) const {
-    rsScriptBindAllocation(mRS->mContext, getID(), BaseObj::getObjID(va), slot);
+    rsScriptBindAllocation(mRS->getContext(), getID(), BaseObj::getObjID(va), slot);
 }
 
 
 void Script::setVar(uint32_t index, sp<const BaseObj> o) const {
-    rsScriptSetVarObj(mRS->mContext, getID(), index, (o == NULL) ? 0 : o->getID());
+    rsScriptSetVarObj(mRS->getContext(), getID(), index, (o == NULL) ? 0 : o->getID());
 }
 
 void Script::setVar(uint32_t index, const void *v, size_t len) const {
-    rsScriptSetVarV(mRS->mContext, getID(), index, v, len);
+    rsScriptSetVarV(mRS->getContext(), getID(), index, v, len);
 }
 
-
-
-void Script::FieldBase::init(RenderScript *rs, uint32_t dimx, uint32_t usages) {
+void Script::FieldBase::init(sp<RS> rs, uint32_t dimx, uint32_t usages) {
     mAllocation = Allocation::createSized(rs, mElement, dimx, RS_ALLOCATION_USAGE_SCRIPT | usages);
 }
 
-//Script::FieldBase::FieldBase() {
-//}
-
-
diff --git a/cpp/Script.h b/cpp/Script.h
deleted file mode 100644
index 235560a..0000000
--- a/cpp/Script.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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_SCRIPT_H__
-#define __ANDROID_SCRIPT_H__
-
-#include <pthread.h>
-#include <rs.h>
-
-#include "RenderScript.h"
-#include "Allocation.h"
-
-namespace android {
-namespace renderscriptCpp {
-
-
-class Type;
-class Element;
-class Allocation;
-
-class Script : public BaseObj {
-private:
-
-protected:
-    Script(void *id, RenderScript *rs);
-    void forEach(uint32_t slot, sp<const Allocation> in, sp<const Allocation> out,
-            const void *v, size_t) const;
-    void bindAllocation(sp<Allocation> va, uint32_t slot) const;
-    void setVar(uint32_t index, const void *, size_t len) const;
-    void setVar(uint32_t index, sp<const BaseObj> o) const;
-    void invoke(uint32_t slot, const void *v, size_t len) const;
-
-
-    void invoke(uint32_t slot) const {
-        invoke(slot, NULL, 0);
-    }
-    void setVar(uint32_t index, float v) const {
-        setVar(index, &v, sizeof(v));
-    }
-    void setVar(uint32_t index, double v) const {
-        setVar(index, &v, sizeof(v));
-    }
-    void setVar(uint32_t index, int32_t v) const {
-        setVar(index, &v, sizeof(v));
-    }
-    void setVar(uint32_t index, int64_t v) const {
-        setVar(index, &v, sizeof(v));
-    }
-    void setVar(uint32_t index, bool v) const {
-        setVar(index, &v, sizeof(v));
-    }
-
-public:
-    class FieldBase {
-    protected:
-        sp<const Element> mElement;
-        sp<Allocation> mAllocation;
-
-        void init(RenderScript *rs, uint32_t dimx, uint32_t usages = 0);
-
-    public:
-        sp<const Element> getElement() {
-            return mElement;
-        }
-
-        sp<const Type> getType() {
-            return mAllocation->getType();
-        }
-
-        sp<const Allocation> getAllocation() {
-            return mAllocation;
-        }
-
-        //void updateAllocation();
-    };
-};
-
-}
-}
-#endif
diff --git a/cpp/ScriptC.cpp b/cpp/ScriptC.cpp
index 39b17d4..bc7ca0e 100644
--- a/cpp/ScriptC.cpp
+++ b/cpp/ScriptC.cpp
@@ -14,22 +14,20 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "libRS_cpp"
-
 #include <utils/Log.h>
 #include <malloc.h>
 
-#include "ScriptC.h"
+#include "RenderScript.h"
 
 using namespace android;
-using namespace renderscriptCpp;
+using namespace RSC;
 
-ScriptC::ScriptC(RenderScript *rs,
+ScriptC::ScriptC(sp<RS> rs,
                  const void *codeTxt, size_t codeLength,
                  const char *cachedName, size_t cachedNameLength,
                  const char *cacheDir, size_t cacheDirLength)
 : Script(NULL, rs) {
-    mID = rsScriptCCreate(rs->mContext, cachedName, cachedNameLength,
+    mID = rsScriptCCreate(rs->getContext(), cachedName, cachedNameLength,
                           cacheDir, cacheDirLength, (const char *)codeTxt, codeLength);
 }
 
diff --git a/cpp/ScriptC.h b/cpp/ScriptC.h
deleted file mode 100644
index 8711b8d..0000000
--- a/cpp/ScriptC.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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_SCRIPTC_H__
-#define __ANDROID_SCRIPTC_H__
-
-#include <pthread.h>
-#include <rs.h>
-
-#include "Script.h"
-
-namespace android {
-namespace renderscriptCpp {
-
-class ScriptC : public Script {
-protected:
-    ScriptC(RenderScript *rs,
-            const void *codeTxt, size_t codeLength,
-            const char *cachedName, size_t cachedNameLength,
-            const char *cacheDir, size_t cacheDirLength);
-
-};
-
-
-}
-}
-#endif
diff --git a/cpp/ScriptIntrinsics.cpp b/cpp/ScriptIntrinsics.cpp
new file mode 100644
index 0000000..1284736
--- /dev/null
+++ b/cpp/ScriptIntrinsics.cpp
@@ -0,0 +1,110 @@
+/*
+ * 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 "rsDefines.h"
+
+using namespace android;
+using namespace RSC;
+
+ScriptIntrinsic::ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e)
+    : Script(NULL, rs) {
+    mID = rsScriptIntrinsicCreate(rs->getContext(), id, e->getID());
+}
+
+ScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e)
+    : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) {
+
+}
+
+void ScriptIntrinsicBlend::blendClear(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(0, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendSrc(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(1, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendDst(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(2, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendSrcOver(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(3, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendDstOver(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(4, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendSrcIn(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(5, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendDstIn(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(6, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendSrcOut(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(7, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendDstOut(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(8, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendSrcAtop(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(9, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendDstAtop(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(10, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendXor(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(11, in, out, NULL, 0);
+}
+
+// Numbering jumps here
+void ScriptIntrinsicBlend::blendMultiply(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(14, in, out, NULL, 0);
+}
+
+// Numbering jumps here
+void ScriptIntrinsicBlend::blendAdd(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(34, in, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlend::blendSubtract(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(35, in, out, NULL, 0);
+}
+
+ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e)
+    : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) {
+
+}
+
+void ScriptIntrinsicBlur::blur(sp<Allocation> in, sp<Allocation> out) {
+    Script::setVar(1, in);
+    Script::forEach(0, NULL, out, NULL, 0);
+}
+
+void ScriptIntrinsicBlur::setRadius(float radius) {
+    Script::setVar(0, &radius, sizeof(float));
+}
diff --git a/cpp/Type.cpp b/cpp/Type.cpp
index 23327b0..6b9ac40 100644
--- a/cpp/Type.cpp
+++ b/cpp/Type.cpp
@@ -21,11 +21,9 @@
 #include <string.h>
 
 #include "RenderScript.h"
-#include "Element.h"
-#include "Type.h"
 
 using namespace android;
-using namespace renderscriptCpp;
+using namespace RSC;
 
 void Type::calcElementCount() {
     bool hasLod = hasMipmaps();
@@ -64,7 +62,7 @@
 }
 
 
-Type::Type(void *id, RenderScript *rs) : BaseObj(id, rs) {
+Type::Type(void *id, sp<RS> rs) : BaseObj(id, rs) {
     mDimX = 0;
     mDimY = 0;
     mDimZ = 0;
@@ -96,7 +94,7 @@
     */
 }
 
-Type::Builder::Builder(RenderScript *rs, sp<const Element> e) {
+Type::Builder::Builder(sp<RS> rs, sp<const Element> e) {
     mRS = rs;
     mElement = e;
     mDimX = 0;
@@ -148,7 +146,7 @@
         }
     }
 
-    void * id = rsTypeCreate(mRS->mContext, mElement->getID(), mDimX, mDimY, mDimZ,
+    void * id = rsTypeCreate(mRS->getContext(), mElement->getID(), mDimX, mDimY, mDimZ,
             mDimMipmaps, mDimFaces);
     Type *t = new Type(id, mRS);
     t->mElement = mElement;
diff --git a/cpp/Type.h b/cpp/Type.h
deleted file mode 100644
index 0890c04..0000000
--- a/cpp/Type.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 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_TYPE_H__
-#define __ANDROID_TYPE_H__
-
-#include <rs.h>
-#include "RenderScript.h"
-#include "Element.h"
-
-namespace android {
-namespace renderscriptCpp {
-
-class Type : public BaseObj {
-protected:
-    friend class Allocation;
-
-    uint32_t mDimX;
-    uint32_t mDimY;
-    uint32_t mDimZ;
-    bool mDimMipmaps;
-    bool mDimFaces;
-    size_t mElementCount;
-    sp<const Element> mElement;
-
-    void calcElementCount();
-    virtual void updateFromNative();
-
-public:
-
-    sp<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;
-        sp<const Element> mElement;
-
-    public:
-        Builder(RenderScript *rs, sp<const Element> e);
-
-        void setX(uint32_t value);
-        void setY(int value);
-        void setMipmaps(bool value);
-        void setFaces(bool value);
-        sp<const Type> create();
-    };
-
-};
-
-}
-}
-#endif
diff --git a/cpp/rsCppStructs.h b/cpp/rsCppStructs.h
new file mode 100644
index 0000000..3598367
--- /dev/null
+++ b/cpp/rsCppStructs.h
@@ -0,0 +1,630 @@
+/*
+ * Copyright (C) 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_RSCPPSTRUCTS_H
+#define ANDROID_RSCPPSTRUCTS_H
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include "utils/RefBase.h"
+
+#include <rs.h>
+
+namespace android {
+namespace RSC {
+
+typedef void (*ErrorHandlerFunc_t)(uint32_t errorNum, const char *errorText);
+typedef void (*MessageHandlerFunc_t)(uint32_t msgNum, const void *msgData, size_t msgLen);
+
+class RS;
+class BaseObj;
+class Element;
+class Type;
+class Allocation;
+class Script;
+class ScriptC;
+
+class RS : public android::LightRefBase<RS> {
+
+ public:
+    RS();
+    virtual ~RS();
+
+    bool init() { return init(false); }
+    bool init(bool forceCpu);
+
+    void setErrorHandler(ErrorHandlerFunc_t func);
+    ErrorHandlerFunc_t getErrorHandler() { return mErrorFunc; }
+
+    void setMessageHandler(MessageHandlerFunc_t func);
+    MessageHandlerFunc_t getMessageHandler() { return mMessageFunc; }
+
+    void throwError(const char *err) const;
+
+    RsContext getContext() { return mContext; }
+
+    void finish();
+
+ private:
+    bool init(int targetApi, bool forceCpu);
+    static void * threadProc(void *);
+
+    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;
+
+};
+
+class BaseObj : public android::LightRefBase<BaseObj> {
+protected:
+    void *mID;
+    sp<RS> mRS;
+    String8 mName;
+
+    BaseObj(void *id, sp<RS> rs);
+    void checkValid();
+
+    static void * getObjID(sp<const BaseObj> o);
+
+public:
+
+    void * getID() const;
+    virtual ~BaseObj();
+    virtual void updateFromNative();
+    virtual bool equals(const BaseObj *obj);
+};
+
+
+class Allocation : public BaseObj {
+protected:
+    android::sp<const Type> mType;
+    uint32_t mUsage;
+    android::sp<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(sp<const Type> t);
+
+    Allocation(void *id, sp<RS> rs, sp<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:
+    android::sp<const Type> getType() {
+        return mType;
+    }
+
+    void syncAll(RsAllocationUsageType srcLocation);
+    void ioSendOutput();
+    void ioGetInput();
+
+    void generateMipmaps();
+
+    void copy1DRangeFrom(uint32_t off, size_t count, const void *data, size_t dataLen);
+    void copy1DRangeTo(uint32_t off, size_t count, void *data, size_t dataLen);
+
+    void copy1DRangeFrom(uint32_t off, size_t count, sp<const Allocation> data, uint32_t dataOff);
+
+    void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                         const void *data, size_t dataLen);
+    //TODO: add copy2DRangeTo
+
+    void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                         sp<const Allocation> data, size_t dataLen,
+                         uint32_t dataXoff, uint32_t dataYoff);
+
+    void resize(int dimX);
+    void resize(int dimX, int dimY);
+
+    static sp<Allocation> createTyped(sp<RS> rs, sp<const Type> type,
+                                   RsAllocationMipmapControl mips, uint32_t usage);
+    static sp<Allocation> createTyped(sp<RS> rs, sp<const Type> type,
+                                   RsAllocationMipmapControl mips, uint32_t usage, void * pointer);
+
+    static sp<Allocation> createTyped(sp<RS> rs, sp<const Type> type,
+                                   uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);
+    static sp<Allocation> createSized(sp<RS> rs, sp<const Element> e, size_t count,
+                                   uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);
+    static sp<Allocation> createSized2D(sp<RS> rs, sp<const Element> e,
+                                        size_t x, size_t y,
+                                        uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);
+
+
+};
+
+class Element : public BaseObj {
+public:
+    bool isComplex();
+    size_t getSubElementCount() {
+        return mVisibleElementMap.size();
+    }
+
+    sp<const Element> getSubElement(uint32_t index);
+    const char * getSubElementName(uint32_t index);
+    size_t getSubElementArraySize(uint32_t index);
+    uint32_t getSubElementOffsetBytes(uint32_t index);
+    RsDataType getDataType() const {
+        return mType;
+    }
+
+    RsDataKind getDataKind() const {
+        return mKind;
+    }
+
+    size_t getSizeBytes() const {
+        return mSizeBytes;
+    }
+
+    static sp<const Element> BOOLEAN(sp<RS> rs);
+    static sp<const Element> U8(sp<RS> rs);
+    static sp<const Element> I8(sp<RS> rs);
+    static sp<const Element> U16(sp<RS> rs);
+    static sp<const Element> I16(sp<RS> rs);
+    static sp<const Element> U32(sp<RS> rs);
+    static sp<const Element> I32(sp<RS> rs);
+    static sp<const Element> U64(sp<RS> rs);
+    static sp<const Element> I64(sp<RS> rs);
+    static sp<const Element> F32(sp<RS> rs);
+    static sp<const Element> F64(sp<RS> rs);
+    static sp<const Element> ELEMENT(sp<RS> rs);
+    static sp<const Element> TYPE(sp<RS> rs);
+    static sp<const Element> ALLOCATION(sp<RS> rs);
+    static sp<const Element> SAMPLER(sp<RS> rs);
+    static sp<const Element> SCRIPT(sp<RS> rs);
+    static sp<const Element> MESH(sp<RS> rs);
+    static sp<const Element> PROGRAM_FRAGMENT(sp<RS> rs);
+    static sp<const Element> PROGRAM_VERTEX(sp<RS> rs);
+    static sp<const Element> PROGRAM_RASTER(sp<RS> rs);
+    static sp<const Element> PROGRAM_STORE(sp<RS> rs);
+
+    static sp<const Element> A_8(sp<RS> rs);
+    static sp<const Element> RGB_565(sp<RS> rs);
+    static sp<const Element> RGB_888(sp<RS> rs);
+    static sp<const Element> RGBA_5551(sp<RS> rs);
+    static sp<const Element> RGBA_4444(sp<RS> rs);
+    static sp<const Element> RGBA_8888(sp<RS> rs);
+
+    static sp<const Element> F32_2(sp<RS> rs);
+    static sp<const Element> F32_3(sp<RS> rs);
+    static sp<const Element> F32_4(sp<RS> rs);
+    static sp<const Element> F64_2(sp<RS> rs);
+    static sp<const Element> F64_3(sp<RS> rs);
+    static sp<const Element> F64_4(sp<RS> rs);
+    static sp<const Element> U8_2(sp<RS> rs);
+    static sp<const Element> U8_3(sp<RS> rs);
+    static sp<const Element> U8_4(sp<RS> rs);
+    static sp<const Element> I8_2(sp<RS> rs);
+    static sp<const Element> I8_3(sp<RS> rs);
+    static sp<const Element> I8_4(sp<RS> rs);
+    static sp<const Element> U16_2(sp<RS> rs);
+    static sp<const Element> U16_3(sp<RS> rs);
+    static sp<const Element> U16_4(sp<RS> rs);
+    static sp<const Element> I16_2(sp<RS> rs);
+    static sp<const Element> I16_3(sp<RS> rs);
+    static sp<const Element> I16_4(sp<RS> rs);
+    static sp<const Element> U32_2(sp<RS> rs);
+    static sp<const Element> U32_3(sp<RS> rs);
+    static sp<const Element> U32_4(sp<RS> rs);
+    static sp<const Element> I32_2(sp<RS> rs);
+    static sp<const Element> I32_3(sp<RS> rs);
+    static sp<const Element> I32_4(sp<RS> rs);
+    static sp<const Element> U64_2(sp<RS> rs);
+    static sp<const Element> U64_3(sp<RS> rs);
+    static sp<const Element> U64_4(sp<RS> rs);
+    static sp<const Element> I64_2(sp<RS> rs);
+    static sp<const Element> I64_3(sp<RS> rs);
+    static sp<const Element> I64_4(sp<RS> rs);
+    static sp<const Element> MATRIX_4X4(sp<RS> rs);
+    static sp<const Element> MATRIX_3X3(sp<RS> rs);
+    static sp<const Element> MATRIX_2X2(sp<RS> rs);
+
+    Element(void *id, sp<RS> rs,
+            android::Vector<sp<Element> > &elements,
+            android::Vector<android::String8> &elementNames,
+            android::Vector<uint32_t> &arraySizes);
+    Element(void *id, sp<RS> rs, RsDataType dt, RsDataKind dk, bool norm, uint32_t size);
+    Element(sp<RS> rs);
+    virtual ~Element();
+
+    void updateFromNative();
+    static sp<const Element> createUser(sp<RS> rs, RsDataType dt);
+    static sp<const Element> createVector(sp<RS> rs, RsDataType dt, uint32_t size);
+    static sp<const Element> createPixel(sp<RS> rs, RsDataType dt, RsDataKind dk);
+    bool isCompatible(sp<const Element>e);
+
+    class Builder {
+    private:
+        sp<RS> mRS;
+        android::Vector<sp<Element> > mElements;
+        android::Vector<android::String8> mElementNames;
+        android::Vector<uint32_t> mArraySizes;
+        bool mSkipPadding;
+
+    public:
+        Builder(sp<RS> rs);
+        ~Builder();
+        void add(sp<Element>, android::String8 &name, uint32_t arraySize = 1);
+        sp<const Element> create();
+    };
+
+private:
+    void updateVisibleSubElements();
+
+    android::Vector<sp</*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;
+};
+
+class FieldPacker {
+protected:
+    unsigned char* mData;
+    size_t mPos;
+    size_t mLen;
+
+public:
+    FieldPacker(size_t len)
+        : mPos(0),
+          mLen(len) {
+        mData = new unsigned char[len];
+    }
+
+    virtual ~FieldPacker() {
+        delete [] mData;
+    }
+
+    void align(size_t v) {
+        if ((v & (v - 1)) != 0) {
+            ALOGE("Non-power-of-two alignment: %zu", v);
+            return;
+        }
+
+        while ((mPos & (v - 1)) != 0) {
+            mData[mPos++] = 0;
+        }
+    }
+
+    void reset() {
+        mPos = 0;
+    }
+
+    void reset(size_t i) {
+        if (i >= mLen) {
+            ALOGE("Out of bounds: i (%zu) >= len (%zu)", i, mLen);
+            return;
+        }
+        mPos = i;
+    }
+
+    void skip(size_t i) {
+        size_t res = mPos + i;
+        if (res > mLen) {
+            ALOGE("Exceeded buffer length: i (%zu) > len (%zu)", i, mLen);
+            return;
+        }
+        mPos = res;
+    }
+
+    void* getData() const {
+        return mData;
+    }
+
+    size_t getLength() const {
+        return mLen;
+    }
+
+    template <typename T>
+    void add(T t) {
+        align(sizeof(t));
+        if (mPos + sizeof(t) <= mLen) {
+            memcpy(&mData[mPos], &t, sizeof(t));
+            mPos += sizeof(t);
+        }
+    }
+};
+
+class Type : public BaseObj {
+protected:
+    friend class Allocation;
+
+    uint32_t mDimX;
+    uint32_t mDimY;
+    uint32_t mDimZ;
+    bool mDimMipmaps;
+    bool mDimFaces;
+    size_t mElementCount;
+    sp<const Element> mElement;
+
+    void calcElementCount();
+    virtual void updateFromNative();
+
+public:
+
+    sp<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, sp<RS> rs);
+
+
+    class Builder {
+    protected:
+        sp<RS> mRS;
+        uint32_t mDimX;
+        uint32_t mDimY;
+        uint32_t mDimZ;
+        bool mDimMipmaps;
+        bool mDimFaces;
+        sp<const Element> mElement;
+
+    public:
+        Builder(sp<RS> rs, sp<const Element> e);
+
+        void setX(uint32_t value);
+        void setY(int value);
+        void setMipmaps(bool value);
+        void setFaces(bool value);
+        sp<const Type> create();
+    };
+
+};
+
+class Script : public BaseObj {
+private:
+
+protected:
+    Script(void *id, sp<RS> rs);
+    void forEach(uint32_t slot, sp<const Allocation> in, sp<const Allocation> out,
+            const void *v, size_t) const;
+    void bindAllocation(sp<Allocation> va, uint32_t slot) const;
+    void setVar(uint32_t index, const void *, size_t len) const;
+    void setVar(uint32_t index, sp<const BaseObj> o) const;
+    void invoke(uint32_t slot, const void *v, size_t len) const;
+
+
+    void invoke(uint32_t slot) const {
+        invoke(slot, NULL, 0);
+    }
+    void setVar(uint32_t index, float v) const {
+        setVar(index, &v, sizeof(v));
+    }
+    void setVar(uint32_t index, double v) const {
+        setVar(index, &v, sizeof(v));
+    }
+    void setVar(uint32_t index, int32_t v) const {
+        setVar(index, &v, sizeof(v));
+    }
+    void setVar(uint32_t index, int64_t v) const {
+        setVar(index, &v, sizeof(v));
+    }
+    void setVar(uint32_t index, bool v) const {
+        setVar(index, &v, sizeof(v));
+    }
+
+public:
+    class FieldBase {
+    protected:
+        sp<const Element> mElement;
+        sp<Allocation> mAllocation;
+
+        void init(sp<RS> rs, uint32_t dimx, uint32_t usages = 0);
+
+    public:
+        sp<const Element> getElement() {
+            return mElement;
+        }
+
+        sp<const Type> getType() {
+            return mAllocation->getType();
+        }
+
+        sp<const Allocation> getAllocation() {
+            return mAllocation;
+        }
+
+        //void updateAllocation();
+    };
+};
+
+class ScriptC : public Script {
+protected:
+    ScriptC(sp<RS> rs,
+            const void *codeTxt, size_t codeLength,
+            const char *cachedName, size_t cachedNameLength,
+            const char *cacheDir, size_t cacheDirLength);
+
+};
+
+class ScriptIntrinsic : public Script {
+ protected:
+    ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e);
+};
+
+class ScriptIntrinsicBlend : public ScriptIntrinsic {
+ public:
+    ScriptIntrinsicBlend(sp<RS> rs, sp <const Element> e);
+    void blendClear(sp<Allocation> in, sp<Allocation> out);
+    void blendSrc(sp<Allocation> in, sp<Allocation> out);
+    void blendDst(sp<Allocation> in, sp<Allocation> out);
+    void blendSrcOver(sp<Allocation> in, sp<Allocation> out);
+    void blendDstOver(sp<Allocation> in, sp<Allocation> out);
+    void blendSrcIn(sp<Allocation> in, sp<Allocation> out);
+    void blendDstIn(sp<Allocation> in, sp<Allocation> out);
+    void blendSrcOut(sp<Allocation> in, sp<Allocation> out);
+    void blendDstOut(sp<Allocation> in, sp<Allocation> out);
+    void blendSrcAtop(sp<Allocation> in, sp<Allocation> out);
+    void blendDstAtop(sp<Allocation> in, sp<Allocation> out);
+    void blendXor(sp<Allocation> in, sp<Allocation> out);
+    void blendMultiply(sp<Allocation> in, sp<Allocation> out);
+    void blendAdd(sp<Allocation> in, sp<Allocation> out);
+    void blendSubtract(sp<Allocation> in, sp<Allocation> out);
+};
+
+class ScriptIntrinsicBlur : public ScriptIntrinsic {
+ public:
+    ScriptIntrinsicBlur(sp<RS> rs, sp <const Element> e);
+    void blur(sp<Allocation> in, sp<Allocation> out);
+    void setRadius(float radius);
+};
+
+}
+
+}
+
+#endif
diff --git a/driver/rsdBcc.cpp b/driver/rsdBcc.cpp
index 460967e..ddcaac8 100644
--- a/driver/rsdBcc.cpp
+++ b/driver/rsdBcc.cpp
@@ -90,7 +90,8 @@
 
     exec = drv->mCompilerDriver->build(*drv->mCompilerContext,
                                        cacheDir, resName,
-                                       (const char *)bitcode, bitcodeSize);
+                                       (const char *)bitcode, bitcodeSize,
+                                       NULL);
 
     if (exec == NULL) {
         ALOGE("bcc: FAILS to prepare executable for '%s'", resName);
@@ -176,6 +177,7 @@
     MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
     RsForEachStubParamStruct p;
     memcpy(&p, &mtls->fep, sizeof(p));
+    p.lid = idx;
     RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
     uint32_t sig = mtls->sig;
 
@@ -222,6 +224,7 @@
     MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
     RsForEachStubParamStruct p;
     memcpy(&p, &mtls->fep, sizeof(p));
+    p.lid = idx;
     RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
     uint32_t sig = mtls->sig;
 
@@ -328,8 +331,7 @@
 }
 
 void rsdScriptLaunchThreads(const Context *rsc,
-                            Script *s,
-                            uint32_t slot,
+                            bool isThreadable,
                             const Allocation * ain,
                             Allocation * aout,
                             const void * usr,
@@ -337,11 +339,10 @@
                             const RsScriptCall *sc,
                             MTLaunchStruct *mtls) {
 
-    Script * oldTLS = setTLS(s);
     Context *mrsc = (Context *)rsc;
     RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
 
-    if ((dc->mWorkers.mCount >= 1) && s->mHal.info.isThreadable && !dc->mInForEach) {
+    if ((dc->mWorkers.mCount >= 1) && isThreadable && !dc->mInForEach) {
         const size_t targetByteChunk = 16 * 1024;
         dc->mInForEach = true;
         if (mtls->fep.dimY > 1) {
@@ -405,8 +406,6 @@
             }
         }
     }
-
-    setTLS(oldTLS);
 }
 
 void rsdScriptInvokeForEach(const Context *rsc,
@@ -438,7 +437,9 @@
     }
 
 
-    rsdScriptLaunchThreads(rsc, s, slot, ain, aout, usr, usrLen, sc, &mtls);
+    Script * oldTLS = setTLS(s);
+    rsdScriptLaunchThreads(rsc, s->mHal.info.isThreadable, ain, aout, usr, usrLen, sc, &mtls);
+    setTLS(oldTLS);
 }
 
 
diff --git a/driver/rsdBcc.h b/driver/rsdBcc.h
index ab62f14..4a42eb5 100644
--- a/driver/rsdBcc.h
+++ b/driver/rsdBcc.h
@@ -161,8 +161,7 @@
 } MTLaunchStruct;
 
 void rsdScriptLaunchThreads(const android::renderscript::Context *rsc,
-                            android::renderscript::Script *s,
-                            uint32_t slot,
+                            bool isThreadable,
                             const android::renderscript::Allocation * ain,
                             android::renderscript::Allocation * aout,
                             const void * usr,
diff --git a/driver/rsdIntrinsicBlend.cpp b/driver/rsdIntrinsicBlend.cpp
index 22ad108..c35c379 100644
--- a/driver/rsdIntrinsicBlend.cpp
+++ b/driver/rsdIntrinsicBlend.cpp
@@ -103,9 +103,6 @@
     uint32_t x1 = xstart;
     uint32_t x2 = xend;
 
-    in += xstart;
-    out += xstart;
-
     switch (p->slot) {
     case BLEND_CLEAR:
         for (;x1 < x2; x1++, out++) {
diff --git a/driver/rsdIntrinsicBlur.cpp b/driver/rsdIntrinsicBlur.cpp
index 9c1fe68..b67e8d5 100644
--- a/driver/rsdIntrinsicBlur.cpp
+++ b/driver/rsdIntrinsicBlur.cpp
@@ -126,7 +126,7 @@
 #endif
 
     while(x2 > x1) {
-        const uchar *pi = ptrIn + x1 * 4;
+        const uchar *pi = ptrIn;
         float4 blurredPixel = 0;
         const float* gp = gPtr;
 
diff --git a/driver/rsdIntrinsicColorMatrix.cpp b/driver/rsdIntrinsicColorMatrix.cpp
index 8f6c70c..cfe0333 100644
--- a/driver/rsdIntrinsicColorMatrix.cpp
+++ b/driver/rsdIntrinsicColorMatrix.cpp
@@ -97,9 +97,6 @@
     uint32_t x1 = xstart;
     uint32_t x2 = xend;
 
-    in += xstart;
-    out += xstart;
-
     if(x2 > x1) {
 #if defined(ARCH_ARM_HAVE_NEON)
         int32_t len = (x2 - x1) >> 2;
diff --git a/driver/rsdIntrinsicLUT.cpp b/driver/rsdIntrinsicLUT.cpp
index a75534e..818a132 100644
--- a/driver/rsdIntrinsicLUT.cpp
+++ b/driver/rsdIntrinsicLUT.cpp
@@ -44,9 +44,6 @@
     uint32_t x1 = xstart;
     uint32_t x2 = xend;
 
-    in += xstart;
-    out += xstart;
-
     DrvAllocation *din = (DrvAllocation *)cp->lut->mHal.drv;
     const uchar *tr = (const uchar *)din->lod[0].mallocPtr;
     const uchar *tg = &tr[256];
diff --git a/driver/rsdIntrinsics_Convolve.S b/driver/rsdIntrinsics_Convolve.S
index beb7d14..04dd8b1 100644
--- a/driver/rsdIntrinsics_Convolve.S
+++ b/driver/rsdIntrinsics_Convolve.S
@@ -102,7 +102,7 @@
         vpop            {q4-q7}
         pop             {r4-r8, r10, r11, lr}
         bx              lr
-END(TestConvolveK)
+END(rsdIntrinsicConvolve3x3_K)
 
 /*
         r0 = dst
@@ -111,7 +111,6 @@
         r3 = length
 */
 ENTRY(rsdIntrinsicColorMatrix4x4_K)
-        .save           {r4, lr}
         stmfd           sp!, {r4, lr}
         vpush           {q4-q7}
 
@@ -179,7 +178,6 @@
         r3 = length
 */
 ENTRY(rsdIntrinsicColorMatrix3x3_K)
-        .save           {r4, lr}
         stmfd           sp!, {r4, lr}
         vpush           {q4-q7}
 
@@ -236,7 +234,6 @@
         r3 = length
 */
 ENTRY(rsdIntrinsicColorMatrixDot_K)
-        .save           {r4, lr}
         stmfd           sp!, {r4, lr}
         vpush           {q4-q7}
 
diff --git a/driver/rsdScriptGroup.cpp b/driver/rsdScriptGroup.cpp
index b19678d..f4f0f1c 100644
--- a/driver/rsdScriptGroup.cpp
+++ b/driver/rsdScriptGroup.cpp
@@ -25,6 +25,7 @@
 #include "rsScriptGroup.h"
 #include "rsdScriptGroup.h"
 #include "rsdBcc.h"
+#include "rsdAllocation.h"
 
 using namespace android;
 using namespace android::renderscript;
@@ -47,12 +48,88 @@
                              android::renderscript::Allocation *) {
 }
 
+struct ScriptList {
+    size_t count;
+    Allocation *const* ins;
+    bool const* inExts;
+    Allocation *const* outs;
+    bool const* outExts;
+    const void *const* usrPtrs;
+    size_t const *usrSizes;
+    uint32_t const *sigs;
+    const void *const* fnPtrs;
+
+    const ScriptKernelID *const* kernels;
+};
+
+typedef void (*ScriptGroupRootFunc_t)(const RsForEachStubParamStruct *p,
+                                      uint32_t xstart, uint32_t xend,
+                                      uint32_t instep, uint32_t outstep);
+
+static void ScriptGroupRoot(const RsForEachStubParamStruct *p,
+                            uint32_t xstart, uint32_t xend,
+                            uint32_t instep, uint32_t outstep) {
+
+    const ScriptList *sl = (const ScriptList *)p->usr;
+    RsForEachStubParamStruct *mp = (RsForEachStubParamStruct *)p;
+    const void *oldUsr = p->usr;
+
+    for(size_t ct=0; ct < sl->count; ct++) {
+        ScriptGroupRootFunc_t func;
+        func = (ScriptGroupRootFunc_t)sl->fnPtrs[ct];
+        mp->usr = sl->usrPtrs[ct];
+
+        mp->ptrIn = NULL;
+        mp->in = NULL;
+        mp->ptrOut = NULL;
+        mp->out = NULL;
+
+        if (sl->ins[ct]) {
+            DrvAllocation *drv = (DrvAllocation *)sl->ins[ct]->mHal.drv;
+            mp->ptrIn = (const uint8_t *)drv->lod[0].mallocPtr;
+            mp->in = mp->ptrIn;
+            if (sl->inExts[ct]) {
+                mp->in = mp->ptrIn + drv->lod[0].stride * p->y;
+            } else {
+                if (drv->lod[0].dimY > p->lid) {
+                    mp->in = mp->ptrIn + drv->lod[0].stride * p->lid;
+                }
+            }
+        }
+
+        if (sl->outs[ct]) {
+            DrvAllocation *drv = (DrvAllocation *)sl->outs[ct]->mHal.drv;
+            mp->ptrOut = (uint8_t *)drv->lod[0].mallocPtr;
+            mp->out = mp->ptrOut;
+            if (sl->outExts[ct]) {
+                mp->out = mp->ptrOut + drv->lod[0].stride * p->y;
+            } else {
+                if (drv->lod[0].dimY > p->lid) {
+                    mp->out = mp->ptrOut + drv->lod[0].stride * p->lid;
+                }
+            }
+        }
+
+        //ALOGE("kernel %i %p,%p  %p,%p", ct, mp->ptrIn, mp->in, mp->ptrOut, mp->out);
+        func(p, xstart, xend, instep, outstep);
+    }
+    //ALOGE("script group root");
+
+    //ConvolveParams *cp = (ConvolveParams *)p->usr;
+
+    mp->usr = oldUsr;
+}
+
+
 void rsdScriptGroupExecute(const android::renderscript::Context *rsc,
                            const android::renderscript::ScriptGroup *sg) {
 
     Vector<Allocation *> ins;
+    Vector<bool> inExts;
     Vector<Allocation *> outs;
+    Vector<bool> outExts;
     Vector<const ScriptKernelID *> kernels;
+    bool fieldDep = false;
 
     for (size_t ct=0; ct < sg->mNodes.size(); ct++) {
         ScriptGroup::Node *n = sg->mNodes[ct];
@@ -71,6 +148,8 @@
             const ScriptKernelID *k = n->mKernels[ct2];
             Allocation *ain = NULL;
             Allocation *aout = NULL;
+            bool inExt = false;
+            bool outExt = false;
 
             for (size_t ct3=0; ct3 < n->mInputs.size(); ct3++) {
                 if (n->mInputs[ct3]->mDstKernel.get() == k) {
@@ -81,6 +160,7 @@
             for (size_t ct3=0; ct3 < sg->mInputs.size(); ct3++) {
                 if (sg->mInputs[ct3]->mKernel == k) {
                     ain = sg->mInputs[ct3]->mAlloc.get();
+                    inExt = true;
                     //ALOGE(" io in %p", ain);
                 }
             }
@@ -88,12 +168,16 @@
             for (size_t ct3=0; ct3 < n->mOutputs.size(); ct3++) {
                 if (n->mOutputs[ct3]->mSource.get() == k) {
                     aout = n->mOutputs[ct3]->mAlloc.get();
+                    if(n->mOutputs[ct3]->mDstField.get() != NULL) {
+                        fieldDep = true;
+                    }
                     //ALOGE(" link out %p", aout);
                 }
             }
             for (size_t ct3=0; ct3 < sg->mOutputs.size(); ct3++) {
                 if (sg->mOutputs[ct3]->mKernel == k) {
                     aout = sg->mOutputs[ct3]->mAlloc.get();
+                    outExt = true;
                     //ALOGE(" io out %p", aout);
                 }
             }
@@ -101,7 +185,9 @@
             if ((k->mHasKernelOutput == (aout != NULL)) &&
                 (k->mHasKernelInput == (ain != NULL))) {
                 ins.add(ain);
+                inExts.add(inExt);
                 outs.add(aout);
+                outExts.add(outExt);
                 kernels.add(k);
             }
         }
@@ -110,33 +196,65 @@
 
     RsdHal * dc = (RsdHal *)rsc->mHal.drv;
     MTLaunchStruct mtls;
-    for (size_t ct=0; ct < ins.size(); ct++) {
 
-        Script *s = kernels[ct]->mScript;
-        DrvScript *drv = (DrvScript *)s->mHal.drv;
-        uint32_t slot = kernels[ct]->mSlot;
+    if(fieldDep) {
+        for (size_t ct=0; ct < ins.size(); ct++) {
+            Script *s = kernels[ct]->mScript;
+            DrvScript *drv = (DrvScript *)s->mHal.drv;
+            uint32_t slot = kernels[ct]->mSlot;
 
-        rsdScriptInvokeForEachMtlsSetup(rsc, ins[ct], outs[ct], NULL, 0, NULL, &mtls);
-        mtls.script = s;
-        mtls.fep.slot = slot;
+            rsdScriptInvokeForEachMtlsSetup(rsc, ins[ct], outs[ct], NULL, 0, NULL, &mtls);
+            mtls.script = s;
 
-        if (drv->mIntrinsicID) {
-            mtls.kernel = (void (*)())drv->mIntrinsicFuncs.root;
-            mtls.fep.usr = drv->mIntrinsicData;
-        } else {
-            mtls.kernel = reinterpret_cast<ForEachFunc_t>(
-                              drv->mExecutable->getExportForeachFuncAddrs()[slot]);
-            rsAssert(mtls.kernel != NULL);
-            mtls.sig = drv->mExecutable->getInfo().getExportForeachFuncs()[slot].second;
+            if (drv->mIntrinsicID) {
+                mtls.kernel = (void (*)())drv->mIntrinsicFuncs.root;
+                mtls.fep.usr = drv->mIntrinsicData;
+            } else {
+                mtls.kernel = reinterpret_cast<ForEachFunc_t>(
+                                  drv->mExecutable->getExportForeachFuncAddrs()[slot]);
+                rsAssert(mtls.kernel != NULL);
+                mtls.sig = drv->mExecutable->getInfo().getExportForeachFuncs()[slot].second;
+            }
+
+            rsdScriptLaunchThreads(rsc, s->mHal.info.isThreadable, ins[ct], outs[ct],
+                                   NULL, 0, NULL, &mtls);
         }
+    } else {
+        ScriptList sl;
+        sl.ins = ins.array();
+        sl.outs = outs.array();
+        sl.kernels = kernels.array();
+        sl.count = kernels.size();
 
-//        typedef void (*outer_foreach_t)(
-  //          const android::renderscript::RsForEachStubParamStruct *,
-    //        uint32_t x1, uint32_t x2,
-      //      uint32_t instep, uint32_t outstep);
-        //outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
+        Vector<const void *> usrPtrs;
+        Vector<const void *> fnPtrs;
+        Vector<uint32_t> sigs;
+        for (size_t ct=0; ct < kernels.size(); ct++) {
+            Script *s = kernels[ct]->mScript;
+            DrvScript *drv = (DrvScript *)s->mHal.drv;
 
-        rsdScriptLaunchThreads(rsc, s, slot, ins[ct], outs[ct], NULL, 0, NULL, &mtls);
+            if (drv->mIntrinsicID) {
+                fnPtrs.add((void *)drv->mIntrinsicFuncs.root);
+                usrPtrs.add(drv->mIntrinsicData);
+                sigs.add(0);
+            } else {
+                int slot = kernels[ct]->mSlot;
+                fnPtrs.add((void *)drv->mExecutable->getExportForeachFuncAddrs()[slot]);
+                usrPtrs.add(NULL);
+                sigs.add(drv->mExecutable->getInfo().getExportForeachFuncs()[slot].second);
+            }
+        }
+        sl.sigs = sigs.array();
+        sl.usrPtrs = usrPtrs.array();
+        sl.fnPtrs = fnPtrs.array();
+        sl.inExts = inExts.array();
+        sl.outExts = outExts.array();
+
+        rsdScriptInvokeForEachMtlsSetup(rsc, ins[0], outs[0], NULL, 0, NULL, &mtls);
+        mtls.script = NULL;
+        mtls.kernel = (void (*)())&ScriptGroupRoot;
+        mtls.fep.usr = &sl;
+        rsdScriptLaunchThreads(rsc, true, ins[0], outs[0], NULL, 0, NULL, &mtls);
     }
 
 }
diff --git a/rs.h b/rs.h
index 825b9b8..e6d3b12 100644
--- a/rs.h
+++ b/rs.h
@@ -52,6 +52,7 @@
 void rsDeviceDestroy(RsDevice dev);
 void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value);
 RsContext rsContextCreate(RsDevice dev, uint32_t version, uint32_t sdkVersion);
+RsContext rsContextCreate(RsDevice dev, uint32_t version, uint32_t sdkVersion, bool forceCpu);
 RsContext rsContextCreateGL(RsDevice dev, uint32_t version, uint32_t sdkVersion,
                             RsSurfaceConfig sc, uint32_t dpi);
 
diff --git a/rs.spec b/rs.spec
index a9ec6fb..bd0827a 100644
--- a/rs.spec
+++ b/rs.spec
@@ -221,6 +221,15 @@
     param void * data
     }
 
+Allocation1DRead {
+    param RsAllocation va
+    param uint32_t xoff
+    param uint32_t lod
+    param uint32_t count
+    param void *data
+    }
+
+
 AllocationSyncAll {
     param RsAllocation va
     param RsAllocationUsageType src
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index ca747e7..b1247d7 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -124,6 +124,12 @@
     rsc->mHal.funcs.allocation.read1D(rsc, this, xoff, lod, count, data, sizeBytes);
 }
 
+void Allocation::readUnchecked(Context *rsc, uint32_t xoff, uint32_t lod,
+                         uint32_t count, void *data, size_t sizeBytes) {
+    rsc->mHal.funcs.allocation.read1D(rsc, this, xoff, lod, count, data, sizeBytes);
+}
+
+
 void Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
              uint32_t w, uint32_t h, void *data, size_t sizeBytes) {
     const size_t eSize = mHal.state.elementSizeBytes;
@@ -660,6 +666,12 @@
     alloc->ioReceive(rsc);
 }
 
+void rsi_Allocation1DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
+                          uint32_t count, void *data, size_t sizeBytes) {
+    Allocation *a = static_cast<Allocation *>(va);
+    a->readUnchecked(rsc, xoff, lod, count, data, sizeBytes);
+}
+
 }
 }
 
diff --git a/rsAllocation.h b/rsAllocation.h
index 4fccf9d..c6b918f 100644
--- a/rsAllocation.h
+++ b/rsAllocation.h
@@ -99,6 +99,7 @@
                  uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes);
 
     void read(Context *rsc, uint32_t xoff, uint32_t lod, uint32_t count, void *data, size_t sizeBytes);
+    void readUnchecked(Context *rsc, uint32_t xoff, uint32_t lod, uint32_t count, void *data, size_t sizeBytes);
     void read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
                  uint32_t w, uint32_t h, void *data, size_t sizeBytes);
     void read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod, RsAllocationCubemapFace face,
diff --git a/rsContext.cpp b/rsContext.cpp
index 6830570..d3709ba 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -205,52 +205,16 @@
     mStateFont.setFontColor(oldR, oldG, oldB, oldA);
 }
 
-void * Context::threadProc(void *vrsc) {
-    Context *rsc = static_cast<Context *>(vrsc);
-#ifndef ANDROID_RS_SERIALIZE
-    rsc->mNativeThreadId = gettid();
-    setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
-    rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
-#endif //ANDROID_RS_SERIALIZE
-    rsc->props.mLogTimes = getProp("debug.rs.profile") != 0;
-    rsc->props.mLogScripts = getProp("debug.rs.script") != 0;
-    rsc->props.mLogObjects = getProp("debug.rs.object") != 0;
-    rsc->props.mLogShaders = getProp("debug.rs.shader") != 0;
-    rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes") != 0;
-    rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms") != 0;
-    rsc->props.mLogVisual = getProp("debug.rs.visual") != 0;
-    rsc->props.mDebugMaxThreads = getProp("debug.rs.max-threads");
+bool Context::loadRuntime(const char* filename, Context* rsc) {
 
+    // TODO: store the driverSO somewhere so we can dlclose later
     void *driverSO = NULL;
 
-    // Provide a mechanism for dropping in a different RS driver.
-#ifdef OVERRIDE_RS_DRIVER
-#define XSTR(S) #S
-#define STR(S) XSTR(S)
-#define OVERRIDE_RS_DRIVER_STRING STR(OVERRIDE_RS_DRIVER)
-    if (getProp("debug.rs.default-CPU-driver") != 0) {
-        ALOGE("Skipping override driver and loading default CPU driver");
-    } else {
-        driverSO = dlopen(OVERRIDE_RS_DRIVER_STRING, RTLD_LAZY);
-        if (driverSO == NULL) {
-            ALOGE("Failed loading %s: %s", OVERRIDE_RS_DRIVER_STRING,
-                  dlerror());
-            // Continue to attempt loading fallback driver
-        }
-    }
-
-#undef XSTR
-#undef STR
-#endif  // OVERRIDE_RS_DRIVER
-
-    // Attempt to load the reference RS driver (if necessary).
+    driverSO = dlopen(filename, RTLD_LAZY);
     if (driverSO == NULL) {
-        driverSO = dlopen("libRSDriver.so", RTLD_LAZY);
-        if (driverSO == NULL) {
-            rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed loading RS driver");
-            ALOGE("Failed loading RS driver: %s", dlerror());
-            return NULL;
-        }
+        rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed loading RS driver");
+        ALOGE("Failed loading RS driver: %s", dlerror());
+        return false;
     }
 
     // Need to call dlerror() to clear buffer before using it for dlsym().
@@ -269,15 +233,70 @@
         rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed to find rsdHalInit");
         dlclose(driverSO);
         ALOGE("Failed to find rsdHalInit: %s", dlerror());
-        return NULL;
+        return false;
     }
 
     if (!(*halInit)(rsc, 0, 0)) {
         rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed initializing RS Driver");
         dlclose(driverSO);
         ALOGE("Hal init failed");
-        return NULL;
+        return false;
     }
+
+    //validate HAL struct
+
+
+    return true;
+}
+
+void * Context::threadProc(void *vrsc) {
+    Context *rsc = static_cast<Context *>(vrsc);
+#ifndef ANDROID_RS_SERIALIZE
+    rsc->mNativeThreadId = gettid();
+    setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
+    rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
+#endif //ANDROID_RS_SERIALIZE
+    rsc->props.mLogTimes = getProp("debug.rs.profile") != 0;
+    rsc->props.mLogScripts = getProp("debug.rs.script") != 0;
+    rsc->props.mLogObjects = getProp("debug.rs.object") != 0;
+    rsc->props.mLogShaders = getProp("debug.rs.shader") != 0;
+    rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes") != 0;
+    rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms") != 0;
+    rsc->props.mLogVisual = getProp("debug.rs.visual") != 0;
+    rsc->props.mDebugMaxThreads = getProp("debug.rs.max-threads");
+
+    bool loadDefault = true;
+
+    // Provide a mechanism for dropping in a different RS driver.
+#ifdef OVERRIDE_RS_DRIVER
+#define XSTR(S) #S
+#define STR(S) XSTR(S)
+#define OVERRIDE_RS_DRIVER_STRING STR(OVERRIDE_RS_DRIVER)
+
+    if (getProp("debug.rs.default-CPU-driver") != 0) {
+        ALOGE("Skipping override driver and loading default CPU driver");
+    } else if (rsc->mForceCpu) {
+        ALOGV("Application requested CPU execution");
+    } else {
+        if (loadRuntime(OVERRIDE_RS_DRIVER_STRING, rsc)) {
+            ALOGE("Successfully loaded runtime: %s", OVERRIDE_RS_DRIVER_STRING);
+            loadDefault = false;
+        } else {
+            ALOGE("Failed to load runtime %s, loading default", OVERRIDE_RS_DRIVER_STRING);
+        }
+    }
+
+#undef XSTR
+#undef STR
+#endif  // OVERRIDE_RS_DRIVER
+
+    if (loadDefault) {
+        if (!loadRuntime("libRSDriver.so", rsc)) {
+            ALOGE("Failed to load default runtime!");
+            return NULL;
+        }
+    }
+
     rsc->mHal.funcs.setPriority(rsc, rsc->mThreadPriority);
 
     if (rsc->mIsGraphicsContext) {
@@ -424,11 +443,19 @@
     mDPI = 96;
     mIsContextLite = false;
     memset(&watchdog, 0, sizeof(watchdog));
+    mForceCpu = false;
 }
 
 Context * Context::createContext(Device *dev, const RsSurfaceConfig *sc) {
+    return createContext(dev, sc, false);
+}
+
+Context * Context::createContext(Device *dev, const RsSurfaceConfig *sc,
+                                 bool forceCpu) {
     Context * rsc = new Context();
 
+    rsc->mForceCpu = forceCpu;
+
     if (!rsc->initContext(dev, sc)) {
         delete rsc;
         return NULL;
@@ -792,9 +819,14 @@
 
 RsContext rsContextCreate(RsDevice vdev, uint32_t version,
                           uint32_t sdkVersion) {
+    return rsContextCreate(vdev, version, sdkVersion, false);
+}
+
+RsContext rsContextCreate(RsDevice vdev, uint32_t version,
+                          uint32_t sdkVersion, bool forceCpu) {
     ALOGV("rsContextCreate dev=%p", vdev);
     Device * dev = static_cast<Device *>(vdev);
-    Context *rsc = Context::createContext(dev, NULL);
+    Context *rsc = Context::createContext(dev, NULL, forceCpu);
     if (rsc) {
         rsc->setTargetSdkVersion(sdkVersion);
     }
diff --git a/rsContext.h b/rsContext.h
index 28ac52c..61218da 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -68,6 +68,7 @@
     Hal mHal;
 
     static Context * createContext(Device *, const RsSurfaceConfig *sc);
+    static Context * createContext(Device *, const RsSurfaceConfig *sc, bool forceCpu);
     static Context * createContextLite();
     ~Context();
 
@@ -223,6 +224,8 @@
     int32_t mThreadPriority;
     bool mIsGraphicsContext;
 
+    bool mForceCpu;
+
     bool mRunning;
     bool mExit;
     bool mPaused;
@@ -244,12 +247,12 @@
     Context();
     bool initContext(Device *, const RsSurfaceConfig *sc);
 
-
     bool initGLThread();
     void deinitEGL();
 
     uint32_t runRootScript();
 
+    static bool loadRuntime(const char* filename, Context* rsc);
     static void * threadProc(void *);
     static void * helperThreadProc(void *);
 
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index b291045..18e4af2 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -250,8 +250,14 @@
     bitcodeLen = BT->getTranslatedBitcodeSize();
 #endif
 
+    if (!cacheDir) {
+        // MUST BE FIXED BEFORE ANYTHING USING C++ API IS RELEASED
+        cacheDir = getenv("EXTERNAL_STORAGE");
+        ALOGV("Cache dir changed to %s", cacheDir);
+    }
+
     // ensure that cache dir exists
-    if (!createCacheDir(cacheDir)) {
+    if (cacheDir && !createCacheDir(cacheDir)) {
       return false;
     }
 
diff --git a/rs_hal.h b/rs_hal.h
index b0e10c9..f172fbf 100644
--- a/rs_hal.h
+++ b/rs_hal.h
@@ -58,6 +58,7 @@
     uint32_t lod;
     RsAllocationCubemapFace face;
     uint32_t ar[16];
+    uint32_t lid;
 
     uint32_t dimX;
     uint32_t dimY;
diff --git a/scriptc/rs_allocation.rsh b/scriptc/rs_allocation.rsh
index 42d27bc..a3a7778 100644
--- a/scriptc/rs_allocation.rsh
+++ b/scriptc/rs_allocation.rsh
@@ -204,7 +204,7 @@
 
 #undef GET_ELEMENT_AT
 
-// New API's
+// Jelly Bean
 #if (defined(RS_VERSION) && (RS_VERSION >= 16))
 
 /**
@@ -273,5 +273,20 @@
 
 #endif // (defined(RS_VERSION) && (RS_VERSION >= 16))
 
+#if (defined(RS_VERSION) && (RS_VERSION >= 18))
+
+/**
+ * Set single element of an allocation.
+ */
+extern void __attribute__((overloadable))
+    rsSetElementAt(rs_allocation a, void* ptr, uint32_t x);
+
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+    rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y);
+#endif // (defined(RS_VERSION) && (RS_VERSION >= 18))
+
 #endif
 
diff --git a/tests/ScriptC_mono.cpp b/tests/ScriptC_mono.cpp
deleted file mode 100644
index 966ecb4..0000000
--- a/tests/ScriptC_mono.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-
-/*
- * This file is auto-generated. DO NOT MODIFY!
- * The source Renderscript file: mono.rs
- */
-
-
-#include "ScriptC_mono.h"
-
-static const unsigned char __txt[] = {
-    0xde,0xc0,0x17,0x0b,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0xa8,0x04,0x00,0x00,
-    0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0x04,0x00,
-    0x78,0x05,0x00,0x00,0x02,0x40,0x04,0x00,0x03,0x00,0x00,0x00,0x42,0x43,0xc0,0xde,
-    0x21,0x0c,0x00,0x00,0x27,0x01,0x00,0x00,0x01,0x10,0x00,0x00,0x12,0x00,0x00,0x00,
-    0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,0x06,0x10,0x32,0x39,0x92,0x01,0x84,0x0c,
-    0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,0x80,0x14,0x45,0x02,0x42,0x92,0x0b,0x42,
-    0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,0x0a,0x32,0x44,0x24,0x48,0x0a,0x90,0x21,
-    0x23,0xc4,0x52,0x80,0x0c,0x19,0x21,0x72,0x24,0x07,0xc8,0x48,0x11,0x62,0xa8,0xa0,
-    0xa8,0x40,0xc6,0xf0,0x01,0x00,0x00,0x00,0x49,0x18,0x00,0x00,0x08,0x00,0x00,0x00,
-    0x0b,0x8c,0x00,0x04,0x41,0x10,0x04,0x09,0x01,0x04,0x41,0x10,0x04,0x89,0xff,0xff,
-    0xff,0xff,0x1f,0xc0,0x60,0x81,0xf0,0xff,0xff,0xff,0xff,0x03,0x18,0x00,0x00,0x00,
-    0x89,0x20,0x00,0x00,0x14,0x00,0x00,0x00,0x32,0x22,0x48,0x09,0x20,0x64,0x85,0x04,
-    0x93,0x22,0xa4,0x84,0x04,0x93,0x22,0xe3,0x84,0xa1,0x90,0x14,0x12,0x4c,0x8a,0x8c,
-    0x0b,0x84,0xa4,0x4c,0x10,0x54,0x73,0x04,0x60,0x40,0x60,0x06,0x80,0xc4,0x1c,0x01,
-    0x42,0x64,0x04,0x60,0x18,0x81,0x20,0xe8,0x94,0xc1,0x20,0x44,0x69,0x18,0x81,0x10,
-    0x8a,0xb0,0x0e,0xb1,0x61,0x84,0x41,0x28,0x83,0x70,0x8e,0x5e,0x11,0x8e,0xa3,0x38,
-    0x10,0x30,0x8c,0x30,0x00,0x00,0x00,0x00,0x13,0xb0,0x70,0x90,0x87,0x76,0xb0,0x87,
-    0x3b,0x68,0x03,0x77,0x78,0x07,0x77,0x28,0x87,0x36,0x60,0x87,0x74,0x70,0x87,0x7a,
-    0xc0,0x87,0x36,0x38,0x07,0x77,0xa8,0x87,0x72,0x08,0x07,0x71,0x48,0x87,0x0d,0xf2,
-    0x50,0x0e,0x6d,0x00,0x0f,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,
-    0x07,0x72,0xd0,0x06,0xe9,0x10,0x07,0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e,
-    0x78,0xa0,0x07,0x78,0xa0,0x07,0x78,0xd0,0x06,0xe9,0x10,0x07,0x76,0xa0,0x07,0x71,
-    0x60,0x07,0x7a,0x10,0x07,0x76,0xd0,0x06,0xe9,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,
-    0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,0xe9,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,
-    0x7a,0x60,0x07,0x74,0xd0,0x06,0xe6,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x7a,
-    0x30,0x07,0x72,0xd0,0x06,0xe6,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,
-    0x07,0x74,0xd0,0x06,0xf6,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,
-    0x74,0xd0,0x06,0xf6,0x10,0x07,0x72,0x80,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,0x71,
-    0x20,0x07,0x78,0xd0,0x06,0xe1,0x00,0x07,0x7a,0x00,0x07,0x7a,0x60,0x07,0x74,0xd0,
-    0x06,0xee,0x30,0x07,0x72,0xd0,0x06,0xb3,0x60,0x07,0x74,0xa0,0xf3,0x40,0x86,0x04,
-    0x32,0x42,0x44,0x04,0x60,0x20,0x30,0x57,0x81,0x59,0x09,0x34,0x44,0x51,0x00,0x00,
-    0x08,0x00,0x00,0x00,0x80,0x21,0x4a,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x0c,0x51,
-    0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x60,0x88,0x22,0x01,0x01,0x00,0x00,0x00,0x00,
-    0x00,0x59,0x20,0x00,0x08,0x00,0x00,0x00,0x32,0x1e,0x98,0x10,0x19,0x11,0x4c,0x90,
-    0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x02,0x85,0x40,0xa4,0x04,0x48,0x8c,0x11,0xe8,
-    0xac,0x39,0xe7,0x1f,0x00,0x00,0x00,0x00,0x79,0x18,0x00,0x00,0x5f,0x00,0x00,0x00,
-    0x43,0x88,0x29,0x98,0x84,0x05,0x87,0x3d,0x94,0x83,0x3c,0xcc,0x43,0x3a,0xbc,0x83,
-    0x3b,0x2c,0x08,0xe2,0x60,0x08,0x31,0x11,0x53,0xb1,0x20,0x52,0x87,0x70,0xb0,0x87,
-    0x70,0xf8,0x05,0x78,0x08,0x87,0x71,0x58,0x87,0x70,0x38,0x87,0x72,0xf8,0x05,0x77,
-    0x08,0x87,0x76,0x28,0x87,0x05,0x63,0x30,0x0e,0xef,0xd0,0x0e,0x6e,0x50,0x0e,0xf8,
-    0x10,0x0e,0xed,0x00,0x0f,0xec,0x50,0x0e,0x6e,0x10,0x0e,0xee,0x40,0x0e,0xf2,0xf0,
-    0x0e,0xe9,0x40,0x0e,0x6e,0x20,0x0f,0xf3,0xe0,0x06,0xe8,0x50,0x0e,0xec,0xc0,0x0e,
-    0xef,0x30,0x0e,0xef,0xd0,0x0e,0xf0,0x50,0x0f,0xf4,0x50,0x0e,0x43,0x88,0xe9,0x98,
-    0x90,0x05,0xc4,0x39,0xa4,0x82,0x3b,0xd0,0xc3,0x82,0xa0,0x0e,0x86,0x10,0x93,0x32,
-    0x09,0x0b,0x8c,0x71,0x30,0x05,0x76,0x78,0x87,0x70,0xa0,0x87,0x21,0xc4,0xc4,0x4c,
-    0xcd,0x82,0xe2,0x1c,0x44,0xe1,0x1d,0xde,0x81,0x1d,0x16,0x08,0x71,0x10,0x07,0x43,
-    0x84,0xe9,0x59,0x40,0xc8,0xc3,0x3b,0xbc,0x03,0x3d,0x0c,0x11,0xa6,0x68,0x41,0x30,
-    0x07,0x43,0x88,0x69,0x9a,0xa8,0x05,0xcf,0x3b,0xb4,0x83,0x3b,0xa4,0x03,0x3c,0xbc,
-    0x03,0x3d,0x94,0x83,0x3b,0xd0,0x03,0x18,0x8c,0x03,0x3a,0x84,0x83,0x3c,0x0c,0x21,
-    0xa6,0xca,0x00,0x16,0x44,0xb3,0x90,0x0e,0xed,0x00,0x0f,0xec,0x50,0x0e,0x60,0x30,
-    0x0a,0x6f,0x30,0x0a,0x6b,0xb0,0x06,0x60,0x40,0x0b,0xa2,0x10,0x0a,0xa1,0x30,0xe2,
-    0x18,0x03,0x78,0x90,0x87,0x70,0x38,0x87,0x76,0x08,0x87,0x29,0x02,0x30,0x8c,0x70,
-    0xc6,0x40,0x1e,0xe6,0xe1,0x17,0xca,0x01,0x1f,0xe0,0xe1,0x1d,0xe4,0x81,0x1e,0x7e,
-    0xc1,0x1e,0xc2,0x41,0x1e,0xa6,0x0c,0x46,0xb2,0x8c,0x80,0xc6,0x40,0x1e,0xe6,0xe1,
-    0x17,0xde,0x41,0x1c,0xd4,0xa1,0x1c,0xc6,0x81,0x1e,0x7e,0x61,0x1e,0xd8,0xe1,0x1d,
-    0xe8,0x61,0x1e,0xa6,0x00,0x23,0xae,0x31,0x90,0x87,0x79,0xf8,0x85,0x72,0xc0,0x07,
-    0x78,0x78,0x07,0x79,0xa0,0x87,0x5f,0x30,0x87,0x77,0x90,0x87,0x72,0x08,0x87,0x71,
-    0x40,0x87,0x5f,0x70,0x87,0x70,0x68,0x87,0x72,0x98,0x12,0x38,0x23,0xa4,0x31,0x90,
-    0x87,0x79,0xf8,0x85,0x72,0xc0,0x07,0x78,0x78,0x07,0x79,0xa0,0x87,0x5f,0x30,0x87,
-    0x77,0x90,0x87,0x72,0x08,0x87,0x71,0x40,0x87,0x29,0x01,0x04,0x79,0x18,0x00,0x00,
-    0x0b,0x00,0x00,0x00,0x33,0x08,0x80,0x1c,0xc4,0xe1,0x1c,0x66,0x14,0x01,0x3d,0x88,
-    0x43,0x38,0x84,0xc3,0x8c,0x42,0x80,0x07,0x79,0x78,0x07,0x73,0x98,0xb1,0x0c,0xe6,
-    0x00,0x0f,0xe1,0x30,0x0e,0xe3,0x50,0x0f,0xf2,0x10,0x0e,0xe3,0x90,0x0f,0x00,0x00,
-    0x71,0x20,0x00,0x00,0x13,0x00,0x00,0x00,0x06,0x40,0x18,0x62,0x33,0x99,0x40,0x61,
-    0x6c,0x8e,0xb3,0xd8,0x00,0x11,0x39,0xce,0x64,0x04,0x51,0x24,0xb9,0xcd,0x03,0x08,
-    0x0a,0xe7,0x2c,0x4e,0xc4,0xf3,0x3c,0x6f,0x05,0xcd,0x3f,0xdf,0x83,0x33,0x75,0xd5,
-    0xfd,0x17,0xec,0x6f,0x01,0x86,0xf0,0x2d,0x0e,0x30,0x99,0x81,0xf6,0xcf,0xf5,0x1e,
-    0x49,0x29,0x20,0x28,0x9c,0xb3,0x38,0x51,0xeb,0xf0,0x3c,0xcf,0x77,0xd5,0xfd,0x17,
-    0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00,0x21,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,
-    0x10,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x04,0x46,0x00,0x68,0xcd,0x00,0x90,0x9b,
-    0x01,0x18,0x6b,0x38,0xe9,0x52,0x4e,0x3f,0xb1,0x8d,0xd9,0xf8,0xab,0x4d,0x5f,0xf6,
-    0x3d,0xa2,0x63,0x0d,0x40,0x20,0x8c,0x00,0x00,0x00,0x00,0x00,0xa4,0x8c,0x11,0x03,
-    0x42,0x08,0x08,0x69,0x90,0x61,0x6a,0xa0,0x11,0x83,0x42,0x08,0x0a,0xea,0x99,0x63,
-    0x70,0x2a,0x66,0x90,0xc1,0x72,0xa2,0x11,0x03,0x42,0x08,0x8c,0x6b,0x30,0x62,0xc1,
-    0x06,0x00,0xc3,0x81,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0xa6,0x40,0x54,0x3f,
-    0xd2,0xd8,0x42,0x51,0xfd,0x0e,0x35,0x01,0x01,0x31,0x00,0x00,0x03,0x00,0x00,0x00,
-    0x5b,0x06,0x20,0x90,0xb6,0x0c,0x47,0x20,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-    0x00,0x00,0x00,0x00,
-};
-
-ScriptC_mono::ScriptC_mono(android::renderscriptCpp::RenderScript *rs, const char *cacheDir, size_t cacheDirLength) :
-        ScriptC(rs, __txt, sizeof(__txt), "mono.rs", 4, cacheDir, cacheDirLength) {
-}
-
-ScriptC_mono::~ScriptC_mono() {
-}
-
-void ScriptC_mono::forEach_root(android::sp<const android::renderscriptCpp::Allocation> ain, android::sp<const android::renderscriptCpp::Allocation> aout) const {
-    forEach(0, ain, aout, NULL, 0);
-}
-
diff --git a/tests/ScriptC_mono.h b/tests/ScriptC_mono.h
deleted file mode 100644
index 99912d1..0000000
--- a/tests/ScriptC_mono.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-
-/*
- * This file is auto-generated. DO NOT MODIFY!
- * The source Renderscript file: mono.rs
- */
-
-
-#include "ScriptC.h"
-
-class ScriptC_mono : public android::renderscriptCpp::ScriptC {
-private:
-    int32_t __gInt;
-    bool __gBool;
-public:
-    ScriptC_mono(android::renderscriptCpp::RenderScript *rs, const char *cacheDir, size_t cacheDirLength);
-    virtual ~ScriptC_mono();
-    
-    void set_gInt(int32_t v) {
-        setVar(0, v);
-        __gInt = v;
-    }
-    int32_t get_gInt() const {
-        return __gInt;
-    }
-    
-    float get_cFloat() const {
-        return 1.2f;
-    }
-    
-    void set_gBool(bool v) {
-        setVar(2, v);
-        __gBool = v;
-    }
-    bool get_gBool() const {
-        return __gBool;
-    }
-    
-    void forEach_root(android::sp<const android::renderscriptCpp::Allocation> ain, android::sp<const android::renderscriptCpp::Allocation> aout) const;
-};
diff --git a/tests/Android.mk b/tests/cppallocation/Android.mk
similarity index 68%
copy from tests/Android.mk
copy to tests/cppallocation/Android.mk
index 2263733..32e1844 100644
--- a/tests/Android.mk
+++ b/tests/cppallocation/Android.mk
@@ -2,8 +2,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	compute.cpp \
-	ScriptC_mono.cpp
+	multiply.rs \
+	compute.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libRS \
@@ -19,15 +19,11 @@
 	libbcinfo \
 	libgui
 
-LOCAL_MODULE:= rstest-compute
+LOCAL_MODULE:= rstest-cppallocation
 
 LOCAL_MODULE_TAGS := tests
 
 intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,)
-librs_generated_headers := \
-    $(intermediates)/rsgApiStructs.h \
-    $(intermediates)/rsgApiFuncDecl.h
-LOCAL_GENERATED_SOURCES := $(librs_generated_headers)
 
 LOCAL_C_INCLUDES += frameworks/rs/cpp
 LOCAL_C_INCLUDES += frameworks/rs
diff --git a/tests/cppallocation/compute.cpp b/tests/cppallocation/compute.cpp
new file mode 100644
index 0000000..8439ffb
--- /dev/null
+++ b/tests/cppallocation/compute.cpp
@@ -0,0 +1,63 @@
+
+#include "RenderScript.h"
+
+#include "ScriptC_multiply.h"
+
+using namespace android;
+using namespace RSC;
+
+int main(int argc, char** argv)
+{
+
+    uint32_t numElems = 1024;
+
+    if (argc >= 2) {
+        int tempNumElems = atoi(argv[1]);
+        if (tempNumElems < 1) {
+            printf("numElems must be greater than 0\n");
+            return 1;
+        }
+        numElems = (uint32_t) tempNumElems;
+    }
+
+    sp<RS> rs = new RS();
+
+    bool r = rs->init();
+
+    sp<const Element> e = Element::U32(rs);
+
+    Type::Builder tb(rs, e);
+    tb.setX(numElems);
+    sp<const Type> t = tb.create();
+
+    sp<Allocation> ain = Allocation::createTyped(rs, t);
+    sp<Allocation> aout = Allocation::createTyped(rs, t);
+
+    sp<ScriptC_multiply> sc = new ScriptC_multiply(rs, NULL, 0);
+
+    uint32_t* buf = new uint32_t[numElems];
+    for (uint32_t ct=0; ct < numElems; ct++) {
+        buf[ct] = (uint32_t)ct;
+    }
+
+    ain->copy1DRangeFrom(0, numElems, buf, numElems*sizeof(uint32_t));
+
+    sc->forEach_multiply(ain, aout);
+
+    aout->copy1DRangeTo(0, numElems, buf, numElems*sizeof(uint32_t));
+
+    for (uint32_t ct=0; ct < numElems; ct++) {
+        if (buf[ct] !=  ct * 2) {
+            printf("Mismatch at location %d: %u\n", ct, buf[ct]);
+            return 1;
+        }
+    }
+
+    printf("Test successful with %u elems!\n", numElems);
+
+    sc.clear();
+    t.clear();
+    e.clear();
+    ain.clear();
+    aout.clear();
+}
diff --git a/tests/cppallocation/multiply.rs b/tests/cppallocation/multiply.rs
new file mode 100644
index 0000000..d1ffefb
--- /dev/null
+++ b/tests/cppallocation/multiply.rs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(unused)
+#pragma rs_fp_relaxed
+
+uint32_t __attribute__((kernel)) multiply(uint32_t in) {
+    return in * 2;
+}
+
+
diff --git a/tests/Android.mk b/tests/cppbasic/Android.mk
similarity index 72%
rename from tests/Android.mk
rename to tests/cppbasic/Android.mk
index 2263733..5c2c53a 100644
--- a/tests/Android.mk
+++ b/tests/cppbasic/Android.mk
@@ -2,8 +2,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	compute.cpp \
-	ScriptC_mono.cpp
+	mono.rs \
+	compute.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libRS \
@@ -24,10 +24,6 @@
 LOCAL_MODULE_TAGS := tests
 
 intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,)
-librs_generated_headers := \
-    $(intermediates)/rsgApiStructs.h \
-    $(intermediates)/rsgApiFuncDecl.h
-LOCAL_GENERATED_SOURCES := $(librs_generated_headers)
 
 LOCAL_C_INCLUDES += frameworks/rs/cpp
 LOCAL_C_INCLUDES += frameworks/rs
diff --git a/tests/compute.cpp b/tests/cppbasic/compute.cpp
similarity index 74%
rename from tests/compute.cpp
rename to tests/cppbasic/compute.cpp
index 351627b..782410a 100644
--- a/tests/compute.cpp
+++ b/tests/cppbasic/compute.cpp
@@ -1,21 +1,18 @@
 
 #include "RenderScript.h"
-#include "Element.h"
-#include "Type.h"
-#include "Allocation.h"
 
 #include "ScriptC_mono.h"
 
 using namespace android;
-using namespace renderscriptCpp;
+using namespace RSC;
 
 int main(int argc, char** argv)
 {
 
-    RenderScript *rs = new RenderScript();
-    printf("New RS %p\n", rs);
+    sp<RS> rs = new RS();
+    printf("New RS %p\n", rs.get());
 
-    bool r = rs->init(16);
+    bool r = rs->init();
     printf("Init returned %i\n", r);
 
     sp<const Element> e = Element::RGBA_8888(rs);
@@ -42,20 +39,18 @@
     for (uint32_t ct=0; ct < t->getCount(); ct++) {
         buf[ct] = ct | (ct << 16);
     }
-    //ain->copy1DRangeFrom(0, 128*128, (int32_t *)buf, 128*128*4);
-    ain->copy1DRangeFromUnchecked(0, t->getCount(), buf, t->getCount()*4);
-
-
+    ain->copy1DRangeFrom(0, t->getCount(), buf, t->getCount()*4);
 
     sc->forEach_root(ain, aout);
     printf("for each done\n");
 
-
     printf("Deleting stuff\n");
     sc.clear();
     t.clear();
     a1.clear();
     e.clear();
-    delete rs;
+    ain.clear();
+    aout.clear();
+    //    delete rs;
     printf("Delete OK\n");
 }
diff --git a/tests/cppbasic/mono.rs b/tests/cppbasic/mono.rs
new file mode 100644
index 0000000..c420cac
--- /dev/null
+++ b/tests/cppbasic/mono.rs
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image)
+#pragma rs_fp_relaxed
+
+const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
+
+void root(const uchar4 *v_in, uchar4 *v_out) {
+    float4 f4 = rsUnpackColor8888(*v_in);
+
+    float3 mono = dot(f4.rgb, gMonoMult);
+    *v_out = rsPackColorTo8888(mono);
+}
+
+
diff --git a/tests/Android.mk b/tests/latency/Android.mk
similarity index 68%
copy from tests/Android.mk
copy to tests/latency/Android.mk
index 2263733..b11536d 100644
--- a/tests/Android.mk
+++ b/tests/latency/Android.mk
@@ -2,8 +2,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	compute.cpp \
-	ScriptC_mono.cpp
+	latency.rs \
+	latency.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libRS \
@@ -19,15 +19,11 @@
 	libbcinfo \
 	libgui
 
-LOCAL_MODULE:= rstest-compute
+LOCAL_MODULE:= rstest-latency
 
 LOCAL_MODULE_TAGS := tests
 
 intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,)
-librs_generated_headers := \
-    $(intermediates)/rsgApiStructs.h \
-    $(intermediates)/rsgApiFuncDecl.h
-LOCAL_GENERATED_SOURCES := $(librs_generated_headers)
 
 LOCAL_C_INCLUDES += frameworks/rs/cpp
 LOCAL_C_INCLUDES += frameworks/rs
diff --git a/tests/latency/latency.cpp b/tests/latency/latency.cpp
new file mode 100644
index 0000000..b6a6c47
--- /dev/null
+++ b/tests/latency/latency.cpp
@@ -0,0 +1,82 @@
+#include "RenderScript.h"
+#include <sys/time.h>
+
+#include "ScriptC_latency.h"
+
+using namespace android;
+using namespace RSC;
+
+int main(int argc, char** argv)
+{
+    int iters = 100;
+    int numElems = 1000;
+    bool forceCpu = false;
+
+    if (argc >= 2) {
+        iters = atoi(argv[1]);
+        if (iters <= 0) {
+            printf("iters must be positive\n");
+            return 1;
+        }
+    }
+
+    printf("iters = %d\n", iters);
+
+    if (argc >= 3) {
+        numElems = atoi(argv[2]);
+        if (numElems <= 0) {
+            printf("numElems must be positive\n");
+            return 1;
+        }
+    }
+
+    if (argc >= 4) {
+        int temp = atoi(argv[3]);
+        if (temp != 0)
+            forceCpu = true;
+    }
+
+    if (forceCpu)
+        printf("forcing CPU\n");
+
+    printf("numElems = %d\n", numElems);
+
+    sp<RS> rs = new RS();
+
+    bool r = rs->init(forceCpu); // force CPU execution
+
+    sp<const Element> e = Element::U32(rs);
+
+    Type::Builder tb(rs, e);
+    tb.setX(numElems);
+    sp<const Type> t = tb.create();
+
+    sp<Allocation> ain = Allocation::createTyped(rs, t);
+    sp<Allocation> aout = Allocation::createTyped(rs, t);
+
+    sp<ScriptC_latency> sc = new ScriptC_latency(rs, NULL, 0);
+
+    struct timeval start, stop;
+
+    gettimeofday(&start, NULL);
+
+    for (int i = 0; i < iters; i++) {
+        sc->forEach_root(ain, aout);
+    }
+
+    uint32_t temp;
+
+    rs->finish();
+
+    gettimeofday(&stop, NULL);
+
+    long long elapsed = (stop.tv_sec * 1000000) - (start.tv_sec * 1000000) + (stop.tv_usec - start.tv_usec);
+    printf("elapsed time : %lld microseconds\n", elapsed);
+    printf("time per iter: %f microseconds\n", (double)elapsed / iters);
+
+    sc.clear();
+    t.clear();
+    e.clear();
+    ain.clear();
+    aout.clear();
+}
diff --git a/tests/latency/latency.rs b/tests/latency/latency.rs
new file mode 100644
index 0000000..7ddf3fa
--- /dev/null
+++ b/tests/latency/latency.rs
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.cpptests)
+#pragma rs_fp_relaxed
+
+void root(const uchar4 *v_in, uchar4 *v_out) {
+
+}
+
+