am 42e454ed: am c67fe222: am f7af2655: Merge "Add docs to C++ API." into klp-dev

* commit '42e454ed681a19b09f0643192aa596b55e420ba4':
diff --git a/cpp/Android.mk b/cpp/Android.mk
index d266d14..b32d7f1 100644
--- a/cpp/Android.mk
+++ b/cpp/Android.mk
@@ -21,9 +21,11 @@
   RS_VERSION := "(1 + $(PLATFORM_SDK_VERSION))"
 endif
 local_cflags_for_rs_cpp += -DRS_VERSION=$(RS_VERSION)
+local_cflags_for_rs_cpp += -Wno-unused-parameter
 
 LOCAL_SRC_FILES := $(rs_cpp_SRC_FILES)
 
+LOCAL_CLANG := true
 LOCAL_CFLAGS += $(local_cflags_for_rs_cpp)
 
 LOCAL_SHARED_LIBRARIES := \
@@ -47,6 +49,7 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_CLANG := true
 LOCAL_CFLAGS += $(local_cflags_for_rs_cpp)
 
 LOCAL_SRC_FILES := $(rs_cpp_SRC_FILES)
diff --git a/cpp/BaseObj.cpp b/cpp/BaseObj.cpp
index 80d9414..2e0a637 100644
--- a/cpp/BaseObj.cpp
+++ b/cpp/BaseObj.cpp
@@ -33,7 +33,7 @@
 
 
 BaseObj::BaseObj(void *id, sp<RS> rs) {
-    mRS = rs;
+    mRS = rs.get();
     mID = id;
 }
 
@@ -44,7 +44,9 @@
 }
 
 BaseObj::~BaseObj() {
-    RS::dispatch->ObjDestroy(mRS->getContext(), mID);
+    if (mRS && mRS->getContext()) {
+        RS::dispatch->ObjDestroy(mRS->getContext(), mID);
+    }
     mRS = NULL;
     mID = NULL;
 }
diff --git a/cpp/Element.cpp b/cpp/Element.cpp
index d3fb29a..ce84699 100644
--- a/cpp/Element.cpp
+++ b/cpp/Element.cpp
@@ -358,7 +358,7 @@
 }
 
 Element::Builder::Builder(android::RSC::sp<RS> rs) {
-    mRS = rs;
+    mRS = rs.get();
     mSkipPadding = false;
 }
 
diff --git a/cpp/RenderScript.cpp b/cpp/RenderScript.cpp
index 30d530e..1da31c7 100644
--- a/cpp/RenderScript.cpp
+++ b/cpp/RenderScript.cpp
@@ -74,327 +74,327 @@
 
     RS::dispatch->AllocationGetType = (AllocationGetTypeFnPtr)dlsym(handle, "rsaAllocationGetType");
     if (RS::dispatch->AllocationGetType == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationGetType");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationGetType");
         return false;
     }
     RS::dispatch->TypeGetNativeData = (TypeGetNativeDataFnPtr)dlsym(handle, "rsaTypeGetNativeData");
     if (RS::dispatch->TypeGetNativeData == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->TypeGetNativeData");
+        ALOGV("Couldn't initialize RS::dispatch->TypeGetNativeData");
         return false;
     }
     RS::dispatch->ElementGetNativeData = (ElementGetNativeDataFnPtr)dlsym(handle, "rsaElementGetNativeData");
     if (RS::dispatch->ElementGetNativeData == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ElementGetNativeData");
+        ALOGV("Couldn't initialize RS::dispatch->ElementGetNativeData");
         return false;
     }
     RS::dispatch->ElementGetSubElements = (ElementGetSubElementsFnPtr)dlsym(handle, "rsaElementGetSubElements");
     if (RS::dispatch->ElementGetSubElements == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ElementGetSubElements");
+        ALOGV("Couldn't initialize RS::dispatch->ElementGetSubElements");
         return false;
     }
     RS::dispatch->DeviceCreate = (DeviceCreateFnPtr)dlsym(handle, "rsDeviceCreate");
     if (RS::dispatch->DeviceCreate == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->DeviceCreate");
+        ALOGV("Couldn't initialize RS::dispatch->DeviceCreate");
         return false;
     }
     RS::dispatch->DeviceDestroy = (DeviceDestroyFnPtr)dlsym(handle, "rsDeviceDestroy");
     if (RS::dispatch->DeviceDestroy == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->DeviceDestroy");
+        ALOGV("Couldn't initialize RS::dispatch->DeviceDestroy");
         return false;
     }
     RS::dispatch->DeviceSetConfig = (DeviceSetConfigFnPtr)dlsym(handle, "rsDeviceSetConfig");
     if (RS::dispatch->DeviceSetConfig == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->DeviceSetConfig");
+        ALOGV("Couldn't initialize RS::dispatch->DeviceSetConfig");
         return false;
     }
     RS::dispatch->ContextCreate = (ContextCreateFnPtr)dlsym(handle, "rsContextCreate");;
     if (RS::dispatch->ContextCreate == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ContextCreate");
+        ALOGV("Couldn't initialize RS::dispatch->ContextCreate");
         return false;
     }
     RS::dispatch->GetName = (GetNameFnPtr)dlsym(handle, "rsaGetName");;
     if (RS::dispatch->GetName == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->GetName");
+        ALOGV("Couldn't initialize RS::dispatch->GetName");
         return false;
     }
     RS::dispatch->ContextDestroy = (ContextDestroyFnPtr)dlsym(handle, "rsContextDestroy");
     if (RS::dispatch->ContextDestroy == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ContextDestroy");
+        ALOGV("Couldn't initialize RS::dispatch->ContextDestroy");
         return false;
     }
     RS::dispatch->ContextGetMessage = (ContextGetMessageFnPtr)dlsym(handle, "rsContextGetMessage");
     if (RS::dispatch->ContextGetMessage == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ContextGetMessage");
+        ALOGV("Couldn't initialize RS::dispatch->ContextGetMessage");
         return false;
     }
     RS::dispatch->ContextPeekMessage = (ContextPeekMessageFnPtr)dlsym(handle, "rsContextPeekMessage");
     if (RS::dispatch->ContextPeekMessage == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ContextPeekMessage");
+        ALOGV("Couldn't initialize RS::dispatch->ContextPeekMessage");
         return false;
     }
     RS::dispatch->ContextSendMessage = (ContextSendMessageFnPtr)dlsym(handle, "rsContextSendMessage");
     if (RS::dispatch->ContextSendMessage == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ContextSendMessage");
+        ALOGV("Couldn't initialize RS::dispatch->ContextSendMessage");
         return false;
     }
     RS::dispatch->ContextInitToClient = (ContextInitToClientFnPtr)dlsym(handle, "rsContextInitToClient");
     if (RS::dispatch->ContextInitToClient == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ContextInitToClient");
+        ALOGV("Couldn't initialize RS::dispatch->ContextInitToClient");
         return false;
     }
     RS::dispatch->ContextDeinitToClient = (ContextDeinitToClientFnPtr)dlsym(handle, "rsContextDeinitToClient");
     if (RS::dispatch->ContextDeinitToClient == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ContextDeinitToClient");
+        ALOGV("Couldn't initialize RS::dispatch->ContextDeinitToClient");
         return false;
     }
     RS::dispatch->TypeCreate = (TypeCreateFnPtr)dlsym(handle, "rsTypeCreate");
     if (RS::dispatch->TypeCreate == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->TypeCreate");
+        ALOGV("Couldn't initialize RS::dispatch->TypeCreate");
         return false;
     }
     RS::dispatch->AllocationCreateTyped = (AllocationCreateTypedFnPtr)dlsym(handle, "rsAllocationCreateTyped");
     if (RS::dispatch->AllocationCreateTyped == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationCreateTyped");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationCreateTyped");
         return false;
     }
     RS::dispatch->AllocationCreateFromBitmap = (AllocationCreateFromBitmapFnPtr)dlsym(handle, "rsAllocationCreateFromBitmap");
     if (RS::dispatch->AllocationCreateFromBitmap == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationCreateFromBitmap");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationCreateFromBitmap");
         return false;
     }
     RS::dispatch->AllocationCubeCreateFromBitmap = (AllocationCubeCreateFromBitmapFnPtr)dlsym(handle, "rsAllocationCubeCreateFromBitmap");
     if (RS::dispatch->AllocationCubeCreateFromBitmap == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationCubeCreateFromBitmap");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationCubeCreateFromBitmap");
         return false;
     }
     RS::dispatch->AllocationGetSurface = (AllocationGetSurfaceFnPtr)dlsym(handle, "rsAllocationGetSurface");
     if (RS::dispatch->AllocationGetSurface == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationGetSurface");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationGetSurface");
         return false;
     }
     RS::dispatch->AllocationSetSurface = (AllocationSetSurfaceFnPtr)dlsym(handle, "rsAllocationSetSurface");
     if (RS::dispatch->AllocationSetSurface == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationSetSurface");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationSetSurface");
         return false;
     }
     RS::dispatch->ContextFinish = (ContextFinishFnPtr)dlsym(handle, "rsContextFinish");
     if (RS::dispatch->ContextFinish == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ContextFinish");
+        ALOGV("Couldn't initialize RS::dispatch->ContextFinish");
         return false;
     }
     RS::dispatch->ContextDump = (ContextDumpFnPtr)dlsym(handle, "rsContextDump");
     if (RS::dispatch->ContextDump == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ContextDump");
+        ALOGV("Couldn't initialize RS::dispatch->ContextDump");
         return false;
     }
     RS::dispatch->ContextSetPriority = (ContextSetPriorityFnPtr)dlsym(handle, "rsContextSetPriority");
     if (RS::dispatch->ContextSetPriority == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ContextSetPriority");
+        ALOGV("Couldn't initialize RS::dispatch->ContextSetPriority");
         return false;
     }
     RS::dispatch->AssignName = (AssignNameFnPtr)dlsym(handle, "rsAssignName");
     if (RS::dispatch->AssignName == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AssignName");
+        ALOGV("Couldn't initialize RS::dispatch->AssignName");
         return false;
     }
     RS::dispatch->ObjDestroy = (ObjDestroyFnPtr)dlsym(handle, "rsObjDestroy");
     if (RS::dispatch->ObjDestroy == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ObjDestroy");
+        ALOGV("Couldn't initialize RS::dispatch->ObjDestroy");
         return false;
     }
     RS::dispatch->ElementCreate = (ElementCreateFnPtr)dlsym(handle, "rsElementCreate");
     if (RS::dispatch->ElementCreate == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ElementCreate");
+        ALOGV("Couldn't initialize RS::dispatch->ElementCreate");
         return false;
     }
     RS::dispatch->ElementCreate2 = (ElementCreate2FnPtr)dlsym(handle, "rsElementCreate2");
     if (RS::dispatch->ElementCreate2 == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ElementCreate2");
+        ALOGV("Couldn't initialize RS::dispatch->ElementCreate2");
         return false;
     }
     RS::dispatch->AllocationCopyToBitmap = (AllocationCopyToBitmapFnPtr)dlsym(handle, "rsAllocationCopyToBitmap");
     if (RS::dispatch->AllocationCopyToBitmap == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationCopyToBitmap");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationCopyToBitmap");
         return false;
     }
     RS::dispatch->Allocation1DData = (Allocation1DDataFnPtr)dlsym(handle, "rsAllocation1DData");
     if (RS::dispatch->Allocation1DData == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->Allocation1DData");
+        ALOGV("Couldn't initialize RS::dispatch->Allocation1DData");
         return false;
     }
     RS::dispatch->Allocation1DElementData = (Allocation1DElementDataFnPtr)dlsym(handle, "rsAllocation1DElementData");
     if (RS::dispatch->Allocation1DElementData == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->Allocation1DElementData");
+        ALOGV("Couldn't initialize RS::dispatch->Allocation1DElementData");
         return false;
     }
     RS::dispatch->Allocation2DData = (Allocation2DDataFnPtr)dlsym(handle, "rsAllocation2DData");
     if (RS::dispatch->Allocation2DData == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->Allocation2DData");
+        ALOGV("Couldn't initialize RS::dispatch->Allocation2DData");
         return false;
     }
     RS::dispatch->Allocation3DData = (Allocation3DDataFnPtr)dlsym(handle, "rsAllocation3DData");
     if (RS::dispatch->Allocation3DData == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->Allocation3DData");
+        ALOGV("Couldn't initialize RS::dispatch->Allocation3DData");
         return false;
     }
     RS::dispatch->AllocationGenerateMipmaps = (AllocationGenerateMipmapsFnPtr)dlsym(handle, "rsAllocationGenerateMipmaps");
     if (RS::dispatch->AllocationGenerateMipmaps == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationGenerateMipmaps");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationGenerateMipmaps");
         return false;
     }
     RS::dispatch->AllocationRead = (AllocationReadFnPtr)dlsym(handle, "rsAllocationRead");
     if (RS::dispatch->AllocationRead == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationRead");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationRead");
         return false;
     }
     RS::dispatch->Allocation1DRead = (Allocation1DReadFnPtr)dlsym(handle, "rsAllocation1DRead");
     if (RS::dispatch->Allocation1DRead == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->Allocation1DRead");
+        ALOGV("Couldn't initialize RS::dispatch->Allocation1DRead");
         return false;
     }
     RS::dispatch->Allocation2DRead = (Allocation2DReadFnPtr)dlsym(handle, "rsAllocation2DRead");
     if (RS::dispatch->Allocation2DRead == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->Allocation2DRead");
+        ALOGV("Couldn't initialize RS::dispatch->Allocation2DRead");
         return false;
     }
     RS::dispatch->AllocationSyncAll = (AllocationSyncAllFnPtr)dlsym(handle, "rsAllocationSyncAll");
     if (RS::dispatch->AllocationSyncAll == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationSyncAll");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationSyncAll");
         return false;
     }
     RS::dispatch->AllocationResize1D = (AllocationResize1DFnPtr)dlsym(handle, "rsAllocationResize1D");
     if (RS::dispatch->AllocationResize1D == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationResize1D");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationResize1D");
         return false;
     }
     RS::dispatch->AllocationCopy2DRange = (AllocationCopy2DRangeFnPtr)dlsym(handle, "rsAllocationCopy2DRange");
     if (RS::dispatch->AllocationCopy2DRange == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationCopy2DRange");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationCopy2DRange");
         return false;
     }
     RS::dispatch->AllocationCopy3DRange = (AllocationCopy3DRangeFnPtr)dlsym(handle, "rsAllocationCopy3DRange");
     if (RS::dispatch->AllocationCopy3DRange == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationCopy3DRange");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationCopy3DRange");
         return false;
     }
     RS::dispatch->SamplerCreate = (SamplerCreateFnPtr)dlsym(handle, "rsSamplerCreate");
     if (RS::dispatch->SamplerCreate == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->SamplerCreate");
+        ALOGV("Couldn't initialize RS::dispatch->SamplerCreate");
         return false;
     }
     RS::dispatch->ScriptBindAllocation = (ScriptBindAllocationFnPtr)dlsym(handle, "rsScriptBindAllocation");
     if (RS::dispatch->ScriptBindAllocation == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptBindAllocation");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptBindAllocation");
         return false;
     }
     RS::dispatch->ScriptSetTimeZone = (ScriptSetTimeZoneFnPtr)dlsym(handle, "rsScriptSetTimeZone");
     if (RS::dispatch->ScriptSetTimeZone == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptSetTimeZone");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptSetTimeZone");
         return false;
     }
     RS::dispatch->ScriptInvoke = (ScriptInvokeFnPtr)dlsym(handle, "rsScriptInvoke");
     if (RS::dispatch->ScriptInvoke == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptInvoke");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptInvoke");
         return false;
     }
     RS::dispatch->ScriptInvokeV = (ScriptInvokeVFnPtr)dlsym(handle, "rsScriptInvokeV");
     if (RS::dispatch->ScriptInvokeV == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptInvokeV");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptInvokeV");
         return false;
     }
     RS::dispatch->ScriptForEach = (ScriptForEachFnPtr)dlsym(handle, "rsScriptForEach");
     if (RS::dispatch->ScriptForEach == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptForEach");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptForEach");
         return false;
     }
     RS::dispatch->ScriptSetVarI = (ScriptSetVarIFnPtr)dlsym(handle, "rsScriptSetVarI");
     if (RS::dispatch->ScriptSetVarI == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptSetVarI");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptSetVarI");
         return false;
     }
     RS::dispatch->ScriptSetVarObj = (ScriptSetVarObjFnPtr)dlsym(handle, "rsScriptSetVarObj");
     if (RS::dispatch->ScriptSetVarObj == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptSetVarObj");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptSetVarObj");
         return false;
     }
     RS::dispatch->ScriptSetVarJ = (ScriptSetVarJFnPtr)dlsym(handle, "rsScriptSetVarJ");
     if (RS::dispatch->ScriptSetVarJ == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptSetVarJ");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptSetVarJ");
         return false;
     }
     RS::dispatch->ScriptSetVarF = (ScriptSetVarFFnPtr)dlsym(handle, "rsScriptSetVarF");
     if (RS::dispatch->ScriptSetVarF == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptSetVarF");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptSetVarF");
         return false;
     }
     RS::dispatch->ScriptSetVarD = (ScriptSetVarDFnPtr)dlsym(handle, "rsScriptSetVarD");
     if (RS::dispatch->ScriptSetVarD == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptSetVarD");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptSetVarD");
         return false;
     }
     RS::dispatch->ScriptSetVarV = (ScriptSetVarVFnPtr)dlsym(handle, "rsScriptSetVarV");
     if (RS::dispatch->ScriptSetVarV == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptSetVarV");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptSetVarV");
         return false;
     }
     RS::dispatch->ScriptGetVarV = (ScriptGetVarVFnPtr)dlsym(handle, "rsScriptGetVarV");
     if (RS::dispatch->ScriptGetVarV == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptGetVarV");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptGetVarV");
         return false;
     }
     RS::dispatch->ScriptSetVarVE = (ScriptSetVarVEFnPtr)dlsym(handle, "rsScriptSetVarVE");
     if (RS::dispatch->ScriptSetVarVE == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptSetVarVE");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptSetVarVE");
         return false;
     }
     RS::dispatch->ScriptCCreate = (ScriptCCreateFnPtr)dlsym(handle, "rsScriptCCreate");
     if (RS::dispatch->ScriptCCreate == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptCCreate");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptCCreate");
         return false;
     }
     RS::dispatch->ScriptIntrinsicCreate = (ScriptIntrinsicCreateFnPtr)dlsym(handle, "rsScriptIntrinsicCreate");
     if (RS::dispatch->ScriptIntrinsicCreate == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptIntrinsicCreate");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptIntrinsicCreate");
         return false;
     }
     RS::dispatch->ScriptKernelIDCreate = (ScriptKernelIDCreateFnPtr)dlsym(handle, "rsScriptKernelIDCreate");
     if (RS::dispatch->ScriptKernelIDCreate == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptKernelIDCreate");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptKernelIDCreate");
         return false;
     }
     RS::dispatch->ScriptFieldIDCreate = (ScriptFieldIDCreateFnPtr)dlsym(handle, "rsScriptFieldIDCreate");
     if (RS::dispatch->ScriptFieldIDCreate == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptFieldIDCreate");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptFieldIDCreate");
         return false;
     }
     RS::dispatch->ScriptGroupCreate = (ScriptGroupCreateFnPtr)dlsym(handle, "rsScriptGroupCreate");
     if (RS::dispatch->ScriptGroupCreate == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptGroupCreate");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptGroupCreate");
         return false;
     }
     RS::dispatch->ScriptGroupSetOutput = (ScriptGroupSetOutputFnPtr)dlsym(handle, "rsScriptGroupSetOutput");
     if (RS::dispatch->ScriptGroupSetOutput == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptGroupSetOutput");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptGroupSetOutput");
         return false;
     }
     RS::dispatch->ScriptGroupSetInput = (ScriptGroupSetInputFnPtr)dlsym(handle, "rsScriptGroupSetInput");
     if (RS::dispatch->ScriptGroupSetInput == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptGroupSetInput");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptGroupSetInput");
         return false;
     }
     RS::dispatch->ScriptGroupExecute = (ScriptGroupExecuteFnPtr)dlsym(handle, "rsScriptGroupExecute");
     if (RS::dispatch->ScriptGroupExecute == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->ScriptGroupExecute");
+        ALOGV("Couldn't initialize RS::dispatch->ScriptGroupExecute");
         return false;
     }
     RS::dispatch->AllocationIoSend = (AllocationIoSendFnPtr)dlsym(handle, "rsAllocationIoSend");
     if (RS::dispatch->AllocationIoSend == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationIoSend");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationIoSend");
         return false;
     }
     RS::dispatch->AllocationIoReceive = (AllocationIoReceiveFnPtr)dlsym(handle, "rsAllocationIoReceive");
     if (RS::dispatch->AllocationIoReceive == NULL) {
-        ALOGE("Couldn't initialize RS::dispatch->AllocationIoReceive");
+        ALOGV("Couldn't initialize RS::dispatch->AllocationIoReceive");
         return false;
     }
 
@@ -406,12 +406,12 @@
 static bool loadSO(const char* filename) {
     void* handle = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
     if (handle == NULL) {
-        ALOGE("couldn't dlopen %s, %s", filename, dlerror());
+        ALOGV("couldn't dlopen %s, %s", filename, dlerror());
         return false;
     }
 
     if (loadSymbols(handle) == false) {
-        ALOGE("%s init failed!", filename);
+        ALOGV("%s init failed!", filename);
         return false;
     }
     //ALOGE("Successfully loaded %s", filename);
@@ -576,7 +576,7 @@
     if (rbuf) {
         free(rbuf);
     }
-    ALOGE("RS Message thread exiting.");
+    ALOGV("RS Message thread exiting.");
     return NULL;
 }
 
diff --git a/cpp/Sampler.cpp b/cpp/Sampler.cpp
index a1f4669..767d626 100644
--- a/cpp/Sampler.cpp
+++ b/cpp/Sampler.cpp
@@ -51,7 +51,7 @@
 
 sp<Sampler> Sampler::create(sp<RS> rs, RsSamplerValue min, RsSamplerValue mag, RsSamplerValue wrapS, RsSamplerValue wrapT, float anisotropy) {
     // we aren't supporting wrapR in C++ API atm, so always pass wrap for that
-    void* id = RS::dispatch->SamplerCreate(rs.get(), min, mag, wrapS, wrapT, RS_SAMPLER_WRAP, anisotropy);
+    void* id = RS::dispatch->SamplerCreate(rs->getContext(), min, mag, wrapS, wrapT, RS_SAMPLER_WRAP, anisotropy);
     return new Sampler(rs, id);
 }
 
diff --git a/cpp/Type.cpp b/cpp/Type.cpp
index 07da0c5..d053730 100644
--- a/cpp/Type.cpp
+++ b/cpp/Type.cpp
@@ -116,7 +116,7 @@
 }
 
 Type::Builder::Builder(sp<RS> rs, sp<const Element> e) {
-    mRS = rs;
+    mRS = rs.get();
     mElement = e;
     mDimX = 0;
     mDimY = 0;
diff --git a/cpp/rsCppStructs.h b/cpp/rsCppStructs.h
index 1efd128..e45e2fb 100644
--- a/cpp/rsCppStructs.h
+++ b/cpp/rsCppStructs.h
@@ -260,7 +260,7 @@
 
 protected:
     void *mID;
-    sp<RS> mRS;
+    RS* mRS;
     std::string mName;
 
     BaseObj(void *id, sp<RS> rs);
@@ -1031,7 +1031,7 @@
      */
     class Builder {
     private:
-        sp<RS> mRS;
+        RS* mRS;
         std::vector<sp<Element> > mElements;
         std::vector<std::string> mElementNames;
         std::vector<uint32_t> mArraySizes;
@@ -1285,7 +1285,7 @@
 
     class Builder {
     protected:
-        sp<RS> mRS;
+        RS* mRS;
         uint32_t mDimX;
         uint32_t mDimY;
         uint32_t mDimZ;
@@ -1917,7 +1917,7 @@
      *
      * @return Sampler
      */
-    sp<const Sampler> CLAMP_NEAREST(sp<RS> rs);
+    static sp<const Sampler> CLAMP_NEAREST(sp<RS> rs);
     /**
      * Retrieve a sampler with min and mag set to linear and wrap modes set to
      * clamp.
@@ -1926,7 +1926,7 @@
      *
      * @return Sampler
      */
-    sp<const Sampler> CLAMP_LINEAR(sp<RS> rs);
+    static sp<const Sampler> CLAMP_LINEAR(sp<RS> rs);
     /**
      * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
      * wrap modes set to clamp.
@@ -1935,7 +1935,7 @@
      *
      * @return Sampler
      */
-    sp<const Sampler> CLAMP_LINEAR_MIP_LINEAR(sp<RS> rs);
+    static sp<const Sampler> CLAMP_LINEAR_MIP_LINEAR(sp<RS> rs);
     /**
      * Retrieve a sampler with min and mag set to nearest and wrap modes set to
      * wrap.
@@ -1944,7 +1944,7 @@
      *
      * @return Sampler
      */
-    sp<const Sampler> WRAP_NEAREST(sp<RS> rs);
+    static sp<const Sampler> WRAP_NEAREST(sp<RS> rs);
     /**
      * Retrieve a sampler with min and mag set to linear and wrap modes set to
      * wrap.
@@ -1953,7 +1953,7 @@
      *
      * @return Sampler
      */
-    sp<const Sampler> WRAP_LINEAR(sp<RS> rs);
+    static sp<const Sampler> WRAP_LINEAR(sp<RS> rs);
     /**
      * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
      * wrap modes set to wrap.
@@ -1962,7 +1962,7 @@
      *
      * @return Sampler
      */
-    sp<const Sampler> WRAP_LINEAR_MIP_LINEAR(sp<RS> rs);
+    static sp<const Sampler> WRAP_LINEAR_MIP_LINEAR(sp<RS> rs);
     /**
      * Retrieve a sampler with min and mag set to nearest and wrap modes set to
      * mirrored repeat.
@@ -1971,7 +1971,7 @@
      *
      * @return Sampler
      */
-    sp<const Sampler> MIRRORED_REPEAT_NEAREST(sp<RS> rs);
+    static sp<const Sampler> MIRRORED_REPEAT_NEAREST(sp<RS> rs);
     /**
      * Retrieve a sampler with min and mag set to linear and wrap modes set to
      * mirrored repeat.
@@ -1980,7 +1980,7 @@
      *
      * @return Sampler
      */
-    sp<const Sampler> MIRRORED_REPEAT_LINEAR(sp<RS> rs);
+    static sp<const Sampler> MIRRORED_REPEAT_LINEAR(sp<RS> rs);
     /**
      * Retrieve a sampler with min and mag set to linear and wrap modes set to
      * mirrored repeat.
@@ -1989,7 +1989,7 @@
      *
      * @return Sampler
      */
-    sp<const Sampler> MIRRORED_REPEAT_LINEAR_MIP_LINEAR(sp<RS> rs);
+    static sp<const Sampler> MIRRORED_REPEAT_LINEAR_MIP_LINEAR(sp<RS> rs);
 
 };
 
diff --git a/cpu_ref/rsCpuIntrinsicBlur.cpp b/cpu_ref/rsCpuIntrinsicBlur.cpp
index b2bd3ce..52e31f9 100644
--- a/cpu_ref/rsCpuIntrinsicBlur.cpp
+++ b/cpu_ref/rsCpuIntrinsicBlur.cpp
@@ -161,8 +161,10 @@
         t &= ~1;
         if(t) {
             rsdIntrinsicBlurVFU4_K(out, ptrIn, iStride, gPtr, ct, x1, x1 + t);
+            x1 += t;
+            ptrIn += t << 2;
+            out += t;
         }
-        x1 += t;
     }
 #endif
 
diff --git a/driver/rsdCore.cpp b/driver/rsdCore.cpp
index ed421ee..e38f92a 100644
--- a/driver/rsdCore.cpp
+++ b/driver/rsdCore.cpp
@@ -163,9 +163,9 @@
         rsdScriptGroupSetOutput,
         rsdScriptGroupExecute,
         rsdScriptGroupDestroy
-    }
+    },
 
-
+    NULL // finish
 };
 
 extern const RsdCpuReference::CpuSymbol * rsdLookupRuntimeStub(Context * pContext, char const* name);
diff --git a/driver/rsdRuntimeStubs.cpp b/driver/rsdRuntimeStubs.cpp
index ac80ba3..8431410 100644
--- a/driver/rsdRuntimeStubs.cpp
+++ b/driver/rsdRuntimeStubs.cpp
@@ -84,6 +84,10 @@
 OPAQUETYPE(rs_script_call)
 #undef OPAQUETYPE
 
+typedef enum {
+    // Empty to avoid conflicting definitions with RsAllocationCubemapFace
+} rs_allocation_cubemap_face;
+
 typedef struct {
     int tm_sec;     ///< seconds
     int tm_min;     ///< minutes
@@ -138,7 +142,6 @@
                              srcXoff, srcYoff, srcMip, srcFace);
 }
 
-#ifndef RS_COMPATIBILITY_LIB
 static void SC_AllocationIoSend(Allocation *alloc) {
     Context *rsc = RsdCpuReference::getTlsContext();
     rsrAllocationIoSend(rsc, alloc);
@@ -150,7 +153,7 @@
     rsrAllocationIoReceive(rsc, alloc);
 }
 
-
+#ifndef RS_COMPATIBILITY_LIB
 
 //////////////////////////////////////////////////////////////////////////////
 // Context
@@ -536,24 +539,24 @@
 // Message routines
 //////////////////////////////////////////////////////////////////////////////
 
-static uint32_t SC_ToClient2(int cmdID, void *data, int len) {
+static uint32_t SC_ToClient2(int cmdID, const void *data, uint32_t len) {
     Context *rsc = RsdCpuReference::getTlsContext();
     return rsrToClient(rsc, cmdID, data, len);
 }
 
 static uint32_t SC_ToClient(int cmdID) {
     Context *rsc = RsdCpuReference::getTlsContext();
-    return rsrToClient(rsc, cmdID, NULL, 0);
+    return rsrToClient(rsc, cmdID, (const void *)NULL, 0);
 }
 
-static uint32_t SC_ToClientBlocking2(int cmdID, void *data, int len) {
+static uint32_t SC_ToClientBlocking2(int cmdID, const void *data, uint32_t len) {
     Context *rsc = RsdCpuReference::getTlsContext();
     return rsrToClientBlocking(rsc, cmdID, data, len);
 }
 
 static uint32_t SC_ToClientBlocking(int cmdID) {
     Context *rsc = RsdCpuReference::getTlsContext();
-    return rsrToClientBlocking(rsc, cmdID, NULL, 0);
+    return rsrToClientBlocking(rsc, cmdID, (const void *)NULL, 0);
 }
 
 
@@ -1222,29 +1225,60 @@
 // Compatibility Library entry points
 //////////////////////////////////////////////////////////////////////////////
 
-bool rsIsObject(rs_element src) {
-    return SC_IsObject((ObjectBase*)src.p);
-}
-
-#define CLEAR_SET_OBJ(t) \
+#define IS_CLEAR_SET_OBJ(t) \
+    bool rsIsObject(t src) { \
+        return SC_IsObject((ObjectBase*)src.p); \
+    } \
     void __attribute__((overloadable)) rsClearObject(t *dst) { \
-    return SC_ClearObject((ObjectBase**) dst); \
+        return SC_ClearObject((ObjectBase**) dst); \
     } \
     void __attribute__((overloadable)) rsSetObject(t *dst, t src) { \
-    return SC_SetObject((ObjectBase**) dst, (ObjectBase*) src.p); \
+        return SC_SetObject((ObjectBase**) dst, (ObjectBase*) src.p); \
     }
 
-CLEAR_SET_OBJ(rs_element)
-CLEAR_SET_OBJ(rs_type)
-CLEAR_SET_OBJ(rs_allocation)
-CLEAR_SET_OBJ(rs_sampler)
-CLEAR_SET_OBJ(rs_script)
-#undef CLEAR_SET_OBJ
+IS_CLEAR_SET_OBJ(rs_element)
+IS_CLEAR_SET_OBJ(rs_type)
+IS_CLEAR_SET_OBJ(rs_allocation)
+IS_CLEAR_SET_OBJ(rs_sampler)
+IS_CLEAR_SET_OBJ(rs_script)
+#undef IS_CLEAR_SET_OBJ
 
 const Allocation * rsGetAllocation(const void *ptr) {
     return SC_GetAllocation(ptr);
 }
 
+void __attribute__((overloadable)) rsAllocationIoSend(rs_allocation a) {
+    SC_AllocationIoSend((Allocation *)a.p);
+}
+
+void __attribute__((overloadable)) rsAllocationIoReceive(rs_allocation a) {
+    SC_AllocationIoReceive((Allocation *)a.p);
+}
+
+
+void __attribute__((overloadable)) rsAllocationCopy1DRange(
+        rs_allocation dstAlloc,
+        uint32_t dstOff, uint32_t dstMip, uint32_t count,
+        rs_allocation srcAlloc,
+        uint32_t srcOff, uint32_t srcMip) {
+    SC_AllocationCopy1DRange((Allocation *)dstAlloc.p, dstOff, dstMip, count,
+                             (Allocation *)srcAlloc.p, srcOff, srcMip);
+}
+
+void __attribute__((overloadable)) rsAllocationCopy2DRange(
+        rs_allocation dstAlloc,
+        uint32_t dstXoff, uint32_t dstYoff,
+        uint32_t dstMip, rs_allocation_cubemap_face dstFace,
+        uint32_t width, uint32_t height,
+        rs_allocation srcAlloc,
+        uint32_t srcXoff, uint32_t srcYoff,
+        uint32_t srcMip, rs_allocation_cubemap_face srcFace) {
+    SC_AllocationCopy2DRange((Allocation *)dstAlloc.p, dstXoff, dstYoff,
+                             dstMip, dstFace, width, height,
+                             (Allocation *)srcAlloc.p, srcXoff, srcYoff,
+                             srcMip, srcFace);
+}
+
 void __attribute__((overloadable)) rsForEach(rs_script script,
                                              rs_allocation in,
                                              rs_allocation out,
@@ -1255,6 +1289,20 @@
 
 void __attribute__((overloadable)) rsForEach(rs_script script,
                                              rs_allocation in,
+                                             rs_allocation out) {
+    return SC_ForEach_SAA((Script *)script.p, (Allocation*)in.p, (Allocation*)out.p);
+}
+
+void __attribute__((overloadable)) rsForEach(rs_script script,
+                                             rs_allocation in,
+                                             rs_allocation out,
+                                             const void *usr,
+                                             uint32_t usrLen) {
+    return SC_ForEach_SAAUL((Script *)script.p, (Allocation*)in.p, (Allocation*)out.p, usr, usrLen);
+}
+
+void __attribute__((overloadable)) rsForEach(rs_script script,
+                                             rs_allocation in,
                                              rs_allocation out,
                                              const void *usr,
                                              uint32_t usrLen,
@@ -1275,14 +1323,20 @@
     return rsrUptimeMillis(rsc);
 }
 
-uint32_t rsSendToClientBlocking2(int cmdID, void *data, int len) {
-    Context *rsc = RsdCpuReference::getTlsContext();
-    return rsrToClientBlocking(rsc, cmdID, data, len);
+uint32_t rsSendToClient(int cmdID) {
+    return SC_ToClient(cmdID);
+}
+
+uint32_t rsSendToClient(int cmdID, const void *data, uint32_t len) {
+    return SC_ToClient2(cmdID, data, len);
 }
 
 uint32_t rsSendToClientBlocking(int cmdID) {
-    Context *rsc = RsdCpuReference::getTlsContext();
-    return rsrToClientBlocking(rsc, cmdID, NULL, 0);
+    return SC_ToClientBlocking(cmdID);
+}
+
+uint32_t rsSendToClientBlocking(int cmdID, const void *data, uint32_t len) {
+    return SC_ToClientBlocking2(cmdID, data, len);
 }
 
 static void SC_debugF(const char *s, float f) {
diff --git a/java/tests/Balls/src/com/example/android/rs/balls/ball_physics.rs b/java/tests/Balls/src/com/example/android/rs/balls/ball_physics.rs
index 5b5d2e0..a8c781d 100644
--- a/java/tests/Balls/src/com/example/android/rs/balls/ball_physics.rs
+++ b/java/tests/Balls/src/com/example/android/rs/balls/ball_physics.rs
@@ -60,11 +60,11 @@
             float2 vec2 = vec * vec;
             float len2 = vec2.x + vec2.y;
 
-            if ((len2 < 10000.f) && (len2 > 0.f)) {
-                float t = native_powr(len2, 1.5f) + 16.0f;
-                float2 pfv = (vec / t) * 16000.f;
-                pressure += length(pfv);
-                fv -= pfv;
+            if ((len2 < 10000.f) && (len2 > 0.001f)) {
+                float len = rsqrt(len2 + 4.f);
+                float f = (len * len * len) * 20000.f;
+                fv -= vec * f;
+                pressure += f;
             }
         }
     }
@@ -137,7 +137,7 @@
     }
 
     // low pressure ~500, high ~2500
-    pressure = max(pressure - 400.f, 0.f);
+    pressure *= 12.f;
     ball->pressure = pressure;
 
     //rsDebug("p ", pressure);
diff --git a/java/tests/Balls/src/com/example/android/rs/balls/balls.rs b/java/tests/Balls/src/com/example/android/rs/balls/balls.rs
index 9be9f38..077916d 100644
--- a/java/tests/Balls/src/com/example/android/rs/balls/balls.rs
+++ b/java/tests/Balls/src/com/example/android/rs/balls/balls.rs
@@ -46,8 +46,9 @@
     int2 gridDims = (int2){ rsAllocationGetDimX(gGrid),
                             rsAllocationGetDimY(gGrid) };
 
-    rs_allocation ain = rsGetAllocation(balls);
-    int32_t dimX = rsAllocationGetDimX(ain);
+    rs_allocation aNull;  // Empty rs_allocation, since we don't have an input.
+    rs_allocation aout = rsGetAllocation(balls);
+    int32_t dimX = rsAllocationGetDimX(aout);
 
     // Binning
     // Clear the particle list
@@ -92,7 +93,7 @@
     }
 
 
-    rsForEach(physics_script, ain, ain);
+    rsForEach(physics_script, aNull, aout);
 
     for (uint32_t ct=0; ct < dimX; ct++) {
         point[ct].position = balls[ct].position;
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 2dc7f07..77f554a 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -112,7 +112,6 @@
      * Define enum type for test names
      */
     public enum TestName {
-        // totally there are 38 test cases
         LEVELS_VEC3_RELAXED ("Levels Vec3 Relaxed"),
         LEVELS_VEC4_RELAXED ("Levels Vec4 Relaxed"),
         LEVELS_VEC3_FULL ("Levels Vec3 Full"),
@@ -140,7 +139,7 @@
         CROSS_PROCESS_USING_LUT ("CrossProcess (using LUT)"),
         CONVOLVE_5X5 ("Convolve 5x5"),
         INTRINSICS_CONVOLVE_5X5 ("Intrinsics Convolve 5x5"),
-        MANDELBROT ("Mandelbrot"),
+        MANDELBROT_FLOAT ("Mandelbrot fp32"),
         INTRINSICS_BLEND ("Intrinsics Blend"),
         INTRINSICS_BLUR_25G ("Intrinsics Blur 25 uchar"),
         VIBRANCE ("Vibrance"),
@@ -153,7 +152,8 @@
         COLOR_CUBE_3D_INTRINSIC ("Color Cube (3D LUT intrinsic)"),
         USAGE_IO ("Usage io"),
         ARTISTIC_1("Artistic 1"),
-        HISTOGRAM ("Histogram");
+        HISTOGRAM ("Histogram"),
+        MANDELBROT_DOUBLE ("Mandelbrot fp64");
 
 
         private final String name;
@@ -168,8 +168,6 @@
         }
     }
 
-    Bitmap mBitmapIn;
-    Bitmap mBitmapIn2;
     Bitmap mBitmapOut;
 
     private Spinner mSpinner;
@@ -184,12 +182,9 @@
     private TextView mText4;
     private TextView mText5;
 
-    private float mSaturation = 1.0f;
-
     private TextView mBenchmarkResult;
     private Spinner mTestSpinner;
 
-    private SurfaceView mSurfaceView;
     private ImageView mDisplayView;
 
     private boolean mDoingBenchmark;
@@ -378,8 +373,8 @@
         case INTRINSICS_CONVOLVE_5X5:
             mTest = new Convolve5x5(true);
             break;
-        case MANDELBROT:
-            mTest = new Mandelbrot();
+        case MANDELBROT_FLOAT:
+            mTest = new Mandelbrot(false);
             break;
         case INTRINSICS_BLEND:
             mTest = new Blend();
@@ -420,9 +415,12 @@
         case HISTOGRAM:
             mTest = new Histogram();
             break;
+        case MANDELBROT_DOUBLE:
+            mTest = new Mandelbrot(true);
+            break;
         }
 
-        mTest.createBaseTest(this, mBitmapIn, mBitmapIn2, mBitmapOut);
+        mTest.createBaseTest(this);
         setupBars();
 
         mTest.runTest();
@@ -447,12 +445,15 @@
             };
 
     void init() {
-        mBitmapIn = loadBitmap(R.drawable.img1600x1067);
-        mBitmapIn2 = loadBitmap(R.drawable.img1600x1067b);
-        mBitmapOut = Bitmap.createBitmap(mBitmapIn.getWidth(), mBitmapIn.getHeight(),
-                                         mBitmapIn.getConfig());
-
-        mSurfaceView = (SurfaceView) findViewById(R.id.surface);
+        mRS = RenderScript.create(this);
+        mInPixelsAllocation = Allocation.createFromBitmapResource(
+                mRS, getResources(), R.drawable.img1600x1067);
+        mInPixelsAllocation2 = Allocation.createFromBitmapResource(
+                mRS, getResources(), R.drawable.img1600x1067b);
+        mBitmapOut = Bitmap.createBitmap(mInPixelsAllocation.getType().getX(),
+                                         mInPixelsAllocation.getType().getY(),
+                                         Bitmap.Config.ARGB_8888);
+        mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut);
 
         mDisplayView = (ImageView) findViewById(R.id.display);
         mDisplayView.setImageBitmap(mBitmapOut);
@@ -483,21 +484,6 @@
         mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
         mBenchmarkResult.setText("Result: not run");
 
-
-        mRS = RenderScript.create(this);
-        mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
-                                                          Allocation.MipmapControl.MIPMAP_NONE,
-                                                          Allocation.USAGE_SHARED |
-                                                          Allocation.USAGE_GRAPHICS_TEXTURE |
-                                                          Allocation.USAGE_SCRIPT);
-        mInPixelsAllocation2 = Allocation.createFromBitmap(mRS, mBitmapIn2,
-                                                           Allocation.MipmapControl.MIPMAP_NONE,
-                                                           Allocation.USAGE_SHARED |
-                                                           Allocation.USAGE_GRAPHICS_TEXTURE |
-                                                           Allocation.USAGE_SCRIPT);
-        mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut);
-
-
         setupTests();
         changeTest(TestName.LEVELS_VEC3_RELAXED);
     }
@@ -519,8 +505,6 @@
         mInPixelsAllocation = null;
         mInPixelsAllocation2 = null;
         mOutPixelsAllocation = null;
-        mBitmapIn = null;
-        mBitmapIn2 = null;
         mBitmapOut = null;
     }
 
@@ -547,12 +531,6 @@
         init();
     }
 
-    private Bitmap loadBitmap(int resource) {
-        final BitmapFactory.Options options = new BitmapFactory.Options();
-        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
-        return BitmapFactory.decodeResource(getResources(), resource, options);
-    }
-
     // button hook
     public void benchmark(View v) {
         float t = getBenchmark();
@@ -622,6 +600,7 @@
 
         mTest.exitBenchmark();
         mDoingBenchmark = false;
+
         return ft;
     }
 }
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java b/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
index 5263c61..8b3984a 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
@@ -303,8 +303,8 @@
     // Test case 27: Mandelbrot
     @LargeTest
     public void testMandelbrot() {
-        TestAction ta = new TestAction(TestName.MANDELBROT);
-        runTest(ta, TestName.MANDELBROT.name());
+        TestAction ta = new TestAction(TestName.MANDELBROT_FLOAT);
+        runTest(ta, TestName.MANDELBROT_FLOAT.name());
     }
 
     // Test case 28: Intrinsics Blend
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/Mandelbrot.java b/java/tests/ImageProcessing/src/com/android/rs/image/Mandelbrot.java
index 20036e6..f84dcb9 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/Mandelbrot.java
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/Mandelbrot.java
@@ -30,6 +30,11 @@
 
 public class Mandelbrot extends TestBase {
     private ScriptC_mandelbrot mScript;
+    private boolean mUseDouble = false;
+
+    public Mandelbrot(boolean useDouble) {
+        mUseDouble = useDouble;
+    }
 
     public boolean onBar1Setup(SeekBar b, TextView t) {
         t.setText("Iterations");
@@ -90,7 +95,11 @@
     }
 
     public void runTest() {
-        mScript.forEach_root(mOutPixelsAllocation);
+        if (mUseDouble) {
+            mScript.forEach_rootD(mOutPixelsAllocation);
+        } else {
+            mScript.forEach_root(mOutPixelsAllocation);
+        }
         mRS.finish();
     }
 
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/TestBase.java b/java/tests/ImageProcessing/src/com/android/rs/image/TestBase.java
index a353d9c..cfa9897 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/TestBase.java
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/TestBase.java
@@ -19,9 +19,7 @@
 import android.app.Activity;
 import android.content.Context;
 import android.os.Bundle;
-import android.graphics.BitmapFactory;
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.renderscript.ScriptC;
 import android.renderscript.RenderScript;
 import android.renderscript.Type;
@@ -104,7 +102,7 @@
         return false;
     }
 
-    public final void createBaseTest(ImageProcessingActivity ipact, Bitmap b, Bitmap b2, Bitmap outb) {
+    public final void createBaseTest(ImageProcessingActivity ipact) {
         act = ipact;
         mRS = ipact.mRS;
         mRS.setMessageHandler(new MessageProcessor(act));
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/colorcube.rs b/java/tests/ImageProcessing/src/com/android/rs/image/colorcube.rs
index c0d6ace..a501ee6 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/colorcube.rs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/colorcube.rs
@@ -32,15 +32,10 @@
 
     float4 m = (float4)(1.f / 255.f) * convert_float4(gDims - 1);
     gCoordMul = convert_int4(m * (float4)0x10000);
-
-    rsDebug("dims", gDims);
-    rsDebug("gCoordMul", gCoordMul);
 }
 
-void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
-    //rsDebug("root", in);
-
-    int4 baseCoord = convert_int4(*in) * gCoordMul;
+uchar4 __attribute__((kernel)) root(uchar4 in) {
+    int4 baseCoord = convert_int4(in) * gCoordMul;
     int4 coord1 = baseCoord >> (int4)16;
     int4 coord2 = min(coord1 + 1, gDims - 1);
 
@@ -67,23 +62,8 @@
     uint4 v = ((z0 * weight1.z) + (z1 * weight2.z)) >> (uint4)16;
     uint4 v2 = (v + 0x7f) >> (uint4)8;
 
-    *out = convert_uchar4(v2);
-    out->a = 0xff;
-
-    #if 0
-    if (in->r != out->r) {
-        rsDebug("dr", in->r - out->r);
-        //rsDebug("in", convert_int4(*in));
-        //rsDebug("coord1", coord1);
-        //rsDebug("coord2", coord2);
-        //rsDebug("weight1", weight1);
-        //rsDebug("weight2", weight2);
-        //rsDebug("yz00", yz00);
-        //rsDebug("z0", z0);
-        //rsDebug("v", v);
-        //rsDebug("v2", v2);
-        //rsDebug("out", convert_int4(*out));
-    }
-    #endif
+    uchar4 o = convert_uchar4(v2);
+    o.a = 0xff;
+    return o;
 }
 
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/colormatrix.fs b/java/tests/ImageProcessing/src/com/android/rs/image/colormatrix.rs
similarity index 97%
rename from java/tests/ImageProcessing/src/com/android/rs/image/colormatrix.fs
rename to java/tests/ImageProcessing/src/com/android/rs/image/colormatrix.rs
index 86fb248..fa083ea 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/colormatrix.fs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/colormatrix.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 static rs_matrix4x4 Mat;
 
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/contrast.rs b/java/tests/ImageProcessing/src/com/android/rs/image/contrast.rs
index ef6fd63..06c1802 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/contrast.rs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/contrast.rs
@@ -25,8 +25,10 @@
     brightC = 127.f - brightM * 127.f;
 }
 
-void contrast(const uchar4 *in, uchar4 *out)
-{
-    float3 v = convert_float3(in->rgb) * brightM + brightC;
-    out->rgb = convert_uchar3(clamp(v, 0.f, 255.f));
+uchar4 __attribute__((kernel)) contrast(uchar4 in) {
+    float3 v = convert_float3(in.rgb) * brightM + brightC;
+    uchar4 o;
+    o.rgb = convert_uchar3(clamp(v, 0.f, 255.f));
+    o.a = 0xff;
+    return o;
 }
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/convolve3x3.fs b/java/tests/ImageProcessing/src/com/android/rs/image/convolve3x3.fs
deleted file mode 100644
index 4f8b4d8..0000000
--- a/java/tests/ImageProcessing/src/com/android/rs/image/convolve3x3.fs
+++ /dev/null
@@ -1,57 +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.
- */
-
-#include "ip.rsh"
-
-int32_t gWidth;
-int32_t gHeight;
-rs_allocation gIn;
-
-float gCoeffs[9];
-
-uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
-    uint32_t x1 = min((int32_t)x+1, gWidth-1);
-    uint32_t x2 = max((int32_t)x-1, 0);
-    uint32_t y1 = min((int32_t)y+1, gHeight-1);
-    uint32_t y2 = max((int32_t)y-1, 0);
-
-    float4 result;
-
-    float4 p00 = convert_float4(rsGetElementAt_uchar4(gIn, x1, y1));
-    float4 p01 = convert_float4(rsGetElementAt_uchar4(gIn, x, y1));
-    float4 p02 = convert_float4(rsGetElementAt_uchar4(gIn, x2, y1));
-    float4 p10 = convert_float4(rsGetElementAt_uchar4(gIn, x1, y));
-    float4 p11 = convert_float4(rsGetElementAt_uchar4(gIn, x, y));
-    float4 p12 = convert_float4(rsGetElementAt_uchar4(gIn, x2, y));
-    float4 p20 = convert_float4(rsGetElementAt_uchar4(gIn, x1, y2));
-    float4 p21 = convert_float4(rsGetElementAt_uchar4(gIn, x, y2));
-    float4 p22 = convert_float4(rsGetElementAt_uchar4(gIn, x2, y2));
-
-    result = p00 * gCoeffs[0];
-    result += p01 * gCoeffs[1];
-    result += p02 * gCoeffs[2];
-    result += p10 * gCoeffs[3];
-    result += p11 * gCoeffs[4];
-    result += p12 * gCoeffs[5];
-    result += p20 * gCoeffs[6];
-    result += p21 * gCoeffs[7];
-    result += p22 * gCoeffs[8];
-
-    result = clamp(result, 0.f, 255.f);
-    return convert_uchar4(result);
-}
-
-
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/convolve3x3.rs b/java/tests/ImageProcessing/src/com/android/rs/image/convolve3x3.rs
new file mode 100644
index 0000000..1b1cf3f
--- /dev/null
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/convolve3x3.rs
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+int32_t gWidth;
+int32_t gHeight;
+rs_allocation gIn;
+
+float gCoeffs[9];
+
+uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
+    uint32_t x1 = min((int32_t)x+1, gWidth-1);
+    uint32_t x2 = max((int32_t)x-1, 0);
+    uint32_t y1 = min((int32_t)y+1, gHeight-1);
+    uint32_t y2 = max((int32_t)y-1, 0);
+
+    float4 sum = convert_float4(rsGetElementAt_uchar4(gIn, x1, y1)) * gCoeffs[0];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x, y1)) * gCoeffs[1];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x2, y1)) * gCoeffs[2];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x1, y)) * gCoeffs[3];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x, y)) * gCoeffs[4];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x2, y)) * gCoeffs[5];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x1, y2)) * gCoeffs[6];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x, y2)) * gCoeffs[7];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x2, y2)) * gCoeffs[8];
+
+    sum = clamp(sum, 0.f, 255.f);
+    return convert_uchar4(sum);
+}
+
+
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/convolve5x5.fs b/java/tests/ImageProcessing/src/com/android/rs/image/convolve5x5.fs
deleted file mode 100644
index 922a593..0000000
--- a/java/tests/ImageProcessing/src/com/android/rs/image/convolve5x5.fs
+++ /dev/null
@@ -1,72 +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.
- */
-
-#include "ip.rsh"
-
-int32_t gWidth;
-int32_t gHeight;
-rs_allocation gIn;
-
-float gCoeffs[25];
-
-uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
-    uint32_t x0 = max((int32_t)x-2, 0);
-    uint32_t x1 = max((int32_t)x-1, 0);
-    uint32_t x2 = x;
-    uint32_t x3 = min((int32_t)x+1, gWidth-1);
-    uint32_t x4 = min((int32_t)x+2, gWidth-1);
-
-    uint32_t y0 = max((int32_t)y-2, 0);
-    uint32_t y1 = max((int32_t)y-1, 0);
-    uint32_t y2 = y;
-    uint32_t y3 = min((int32_t)y+1, gHeight-1);
-    uint32_t y4 = min((int32_t)y+2, gHeight-1);
-
-    float4 p0 = convert_float4(rsGetElementAt_uchar4(gIn, x0, y0)) * gCoeffs[0]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x1, y0)) * gCoeffs[1]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x2, y0)) * gCoeffs[2]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x3, y0)) * gCoeffs[3]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x4, y0)) * gCoeffs[4];
-
-    float4 p1 = convert_float4(rsGetElementAt_uchar4(gIn, x0, y1)) * gCoeffs[5]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x1, y1)) * gCoeffs[6]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x2, y1)) * gCoeffs[7]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x3, y1)) * gCoeffs[8]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x4, y1)) * gCoeffs[9];
-
-    float4 p2 = convert_float4(rsGetElementAt_uchar4(gIn, x0, y2)) * gCoeffs[10]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x1, y2)) * gCoeffs[11]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x2, y2)) * gCoeffs[12]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x3, y2)) * gCoeffs[13]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x4, y2)) * gCoeffs[14];
-
-    float4 p3 = convert_float4(rsGetElementAt_uchar4(gIn, x0, y3)) * gCoeffs[15]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x1, y3)) * gCoeffs[16]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x2, y3)) * gCoeffs[17]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x3, y3)) * gCoeffs[18]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x4, y3)) * gCoeffs[19];
-
-    float4 p4 = convert_float4(rsGetElementAt_uchar4(gIn, x0, y4)) * gCoeffs[20]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x1, y4)) * gCoeffs[21]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x2, y4)) * gCoeffs[22]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x3, y4)) * gCoeffs[23]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x4, y4)) * gCoeffs[24];
-
-    p0 = clamp(p0 + p1 + p2 + p3 + p4, 0.f, 255.f);
-    return convert_uchar4(p0);
-}
-
-
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/convolve5x5.rs b/java/tests/ImageProcessing/src/com/android/rs/image/convolve5x5.rs
new file mode 100644
index 0000000..ed8461b
--- /dev/null
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/convolve5x5.rs
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+int32_t gWidth;
+int32_t gHeight;
+rs_allocation gIn;
+
+float gCoeffs[25];
+
+uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
+    uint32_t x0 = max((int32_t)x-2, 0);
+    uint32_t x1 = max((int32_t)x-1, 0);
+    uint32_t x2 = x;
+    uint32_t x3 = min((int32_t)x+1, gWidth-1);
+    uint32_t x4 = min((int32_t)x+2, gWidth-1);
+
+    uint32_t y0 = max((int32_t)y-2, 0);
+    uint32_t y1 = max((int32_t)y-1, 0);
+    uint32_t y2 = y;
+    uint32_t y3 = min((int32_t)y+1, gHeight-1);
+    uint32_t y4 = min((int32_t)y+2, gHeight-1);
+
+    float4 sum = convert_float4(rsGetElementAt_uchar4(gIn, x0, y0)) * gCoeffs[0]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x1, y0)) * gCoeffs[1]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x2, y0)) * gCoeffs[2]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x3, y0)) * gCoeffs[3]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y0)) * gCoeffs[4]
+
+               + convert_float4(rsGetElementAt_uchar4(gIn, x0, y1)) * gCoeffs[5]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x1, y1)) * gCoeffs[6]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x2, y1)) * gCoeffs[7]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x3, y1)) * gCoeffs[8]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y1)) * gCoeffs[9]
+
+               + convert_float4(rsGetElementAt_uchar4(gIn, x0, y2)) * gCoeffs[10]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x1, y2)) * gCoeffs[11]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x2, y2)) * gCoeffs[12]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x3, y2)) * gCoeffs[13]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y2)) * gCoeffs[14]
+
+               + convert_float4(rsGetElementAt_uchar4(gIn, x0, y3)) * gCoeffs[15]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x1, y3)) * gCoeffs[16]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x2, y3)) * gCoeffs[17]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x3, y3)) * gCoeffs[18]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y3)) * gCoeffs[19]
+
+               + convert_float4(rsGetElementAt_uchar4(gIn, x0, y4)) * gCoeffs[20]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x1, y4)) * gCoeffs[21]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x2, y4)) * gCoeffs[22]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x3, y4)) * gCoeffs[23]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y4)) * gCoeffs[24];
+
+    return convert_uchar4(clamp(sum, 0.f, 255.f));
+}
+
+
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/copy.fs b/java/tests/ImageProcessing/src/com/android/rs/image/copy.rs
similarity index 96%
rename from java/tests/ImageProcessing/src/com/android/rs/image/copy.fs
rename to java/tests/ImageProcessing/src/com/android/rs/image/copy.rs
index 6595874..b69f2df 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/copy.fs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/copy.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 uchar4 __attribute__((kernel)) root(uchar4 v_in) {
     return v_in;
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/fisheye.rsh b/java/tests/ImageProcessing/src/com/android/rs/image/fisheye.rsh
index 2eacb7d..fb95005 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/fisheye.rsh
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/fisheye.rsh
@@ -33,7 +33,7 @@
         axis_scale.y = (float)dim_y / (float)dim_x;
     else
         axis_scale.x = (float)dim_x / (float)dim_y;
-    
+
     const float bound2 = 0.25f * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
     const float bound = sqrt(bound2);
     const float radius = 1.15f * bound;
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.fs b/java/tests/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.rs
similarity index 100%
rename from java/tests/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.fs
rename to java/tests/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.rs
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.fs b/java/tests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.rs
similarity index 96%
rename from java/tests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.fs
rename to java/tests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.rs
index f986b5d..31646c4 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.fs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 #include "fisheye.rsh"
 
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/grain.fs b/java/tests/ImageProcessing/src/com/android/rs/image/grain.rs
similarity index 100%
rename from java/tests/ImageProcessing/src/com/android/rs/image/grain.fs
rename to java/tests/ImageProcessing/src/com/android/rs/image/grain.rs
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/greyscale.fs b/java/tests/ImageProcessing/src/com/android/rs/image/greyscale.rs
similarity index 100%
rename from java/tests/ImageProcessing/src/com/android/rs/image/greyscale.fs
rename to java/tests/ImageProcessing/src/com/android/rs/image/greyscale.rs
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/levels.rsh b/java/tests/ImageProcessing/src/com/android/rs/image/levels.rsh
index e289906..b864493 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/levels.rsh
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/levels.rsh
@@ -21,7 +21,7 @@
 float overInWMinInB;
 rs_matrix3x3 colorMat;
 
-uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) root(uchar4 in) {
     uchar4 out;
     float3 pixel = convert_float4(in).rgb;
     pixel = rsMatrixMultiply(&colorMat, pixel);
@@ -34,7 +34,7 @@
     return out;
 }
 
-uchar4 __attribute__((kernel)) root4(uchar4 in, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) root4(uchar4 in) {
     float4 pixel = convert_float4(in);
     pixel.rgb = rsMatrixMultiply(&colorMat, pixel.rgb);
     pixel = clamp(pixel, 0.f, 255.f);
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/levels_relaxed.fs b/java/tests/ImageProcessing/src/com/android/rs/image/levels_relaxed.rs
similarity index 96%
rename from java/tests/ImageProcessing/src/com/android/rs/image/levels_relaxed.fs
rename to java/tests/ImageProcessing/src/com/android/rs/image/levels_relaxed.rs
index 28596ba..c0bc4b7 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/levels_relaxed.fs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/levels_relaxed.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 #include "levels.rsh"
 
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/mandelbrot.rs b/java/tests/ImageProcessing/src/com/android/rs/image/mandelbrot.rs
index de0bd00..5429acd 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/mandelbrot.rs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/mandelbrot.rs
@@ -53,3 +53,36 @@
                       (0xff * ((iter - (mi3 * 2)) / mi3)), 0xff};
   }
 }
+
+uchar4 __attribute__((kernel)) rootD(uint32_t x, uint32_t y) {
+  double2 p;
+  p.x = lowerBoundX + ((float)x / gDimX) * scaleFactor;
+  p.y = lowerBoundY + ((float)y / gDimY) * scaleFactor;
+
+  double2 t = 0;
+  double2 t2 = t * t;
+  int iter = 0;
+  while((t2.x + t2.y < 4.f) && (iter < gMaxIteration)) {
+    double xtemp = t2.x - t2.y + p.x;
+    t.y = 2 * t.x * t.y + p.y;
+    t.x = xtemp;
+    iter++;
+    t2 = t * t;
+  }
+
+  if(iter >= gMaxIteration) {
+    // write a non-transparent black pixel
+    return (uchar4){0, 0, 0, 0xff};
+  } else {
+    double mi3 = gMaxIteration / 3.f;
+    if (iter <= (gMaxIteration / 3))
+      return (uchar4){0xff * (iter / mi3), 0, 0, 0xff};
+    else if (iter <= (((gMaxIteration / 3) * 2)))
+      return (uchar4){0xff - (0xff * ((iter - mi3) / mi3)),
+                      (0xff * ((iter - mi3) / mi3)), 0, 0xff};
+    else
+      return (uchar4){0, 0xff - (0xff * ((iter - (mi3 * 2)) / mi3)),
+                      (0xff * ((iter - (mi3 * 2)) / mi3)), 0xff};
+  }
+}
+
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/shadows.rs b/java/tests/ImageProcessing/src/com/android/rs/image/shadows.rs
index 90757a3..2f06104 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/shadows.rs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/shadows.rs
@@ -17,18 +17,18 @@
 #include "ip.rsh"
 #pragma rs_fp_relaxed
 
-static double shadowFilterMap[] = {
-    -0.00591,  0.0001,
-     1.16488,  0.01668,
-    -0.18027, -0.06791,
-    -0.12625,  0.09001,
-     0.15065, -0.03897
+static float shadowFilterMap[] = {
+    -0.00591f,  0.0001f,
+     1.16488f,  0.01668f,
+    -0.18027f, -0.06791f,
+    -0.12625f,  0.09001f,
+     0.15065f, -0.03897f
 };
 
-static double poly[] = {
-    0., 0.,
-    0., 0.,
-    0.
+static float poly[] = {
+    0.f, 0.f,
+    0.f, 0.f,
+    0.f
 };
 
 static const int ABITS = 4;
@@ -36,10 +36,10 @@
 static const int k1=255 << ABITS;
 static const int k2=HSCALE << ABITS;
 
-static double fastevalPoly(double *poly,int n, double x){
+static float fastevalPoly(float *poly,int n, float x){
 
-    double f =x;
-    double sum = poly[0]+poly[1]*f;
+    float f =x;
+    float sum = poly[0]+poly[1]*f;
     int i;
     for (i = 2; i < n; i++) {
         f*=x;
@@ -177,16 +177,15 @@
 }
 
 void prepareShadows(float scale) {
-    double s = (scale>=0)?scale:scale/5;
+    float s = (scale>=0) ? scale : scale / 5.f;
     for (int i = 0; i < 5; i++) {
         poly[i] = fastevalPoly(shadowFilterMap+i*2,2 , s);
     }
 }
 
-void shadowsKernel(const uchar4 *in, uchar4 *out) {
-    ushort3 hsv = rgb2hsv(*in);
-    double v = (fastevalPoly(poly,5,hsv.x/4080.)*4080);
-    if (v>4080) v = 4080;
-    hsv.x = (unsigned short) ((v>0)?v:0);
-    *out = hsv2rgb(hsv);
+uchar4 __attribute__((kernel)) shadowsKernel(uchar4 in) {
+    ushort3 hsv = rgb2hsv(in);
+    float v = (fastevalPoly(poly, 5, hsv.x * (1.f / 4080.f)) * 4080.f);
+    hsv.x = (unsigned short) clamp(v, 0.f, 4080.f);
+    return hsv2rgb(hsv);
 }
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/threshold.fs b/java/tests/ImageProcessing/src/com/android/rs/image/threshold.rs
similarity index 98%
rename from java/tests/ImageProcessing/src/com/android/rs/image/threshold.fs
rename to java/tests/ImageProcessing/src/com/android/rs/image/threshold.rs
index 0b2c2e8..d30a87b 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/threshold.fs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/threshold.rs
@@ -15,7 +15,7 @@
  */
 
 #include "ip.rsh"
-
+#pragma rs_fp_relaxed
 
 int height;
 int width;
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/vibrance.rs b/java/tests/ImageProcessing/src/com/android/rs/image/vibrance.rs
index b82e1d3..7fa295e 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/vibrance.rs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/vibrance.rs
@@ -25,13 +25,10 @@
 
 static float Vib = 0.f;
 
-void vibranceKernel(const uchar4 *in, uchar4 *out) {
-
-    float R, G, B;
-
-    int r = in->r;
-    int g = in->g;
-    int b = in->b;
+uchar4 __attribute__((kernel)) vibranceKernel(uchar4 in) {
+    int r = in.r;
+    int g = in.g;
+    int b = in.b;
     float red = (r-max(g, b)) * (1.f / 256.f);
     float S = (float)(Vib/(1+native_exp(-red*3)))+1;
     float MS = 1.0f - S;
@@ -39,18 +36,21 @@
     float Gt = Gf * MS;
     float Bt = Bf * MS;
     int t = (r + g) >> 1;
-    R = r;
-    G = g;
-    B = b;
+
+    float R = r;
+    float G = g;
+    float B = b;
 
     float Rc = R * (Rt + S) + G * Gt + B * Bt;
     float Gc = R * Rt + G * (Gt + S) + B * Bt;
     float Bc = R * Rt + G * Gt + B * (Bt + S);
 
-    out->r = rsClamp(Rc, 0, 255);
-    out->g = rsClamp(Gc, 0, 255);
-    out->b = rsClamp(Bc, 0, 255);
-
+    uchar4 o;
+    o.r = rsClamp(Rc, 0, 255);
+    o.g = rsClamp(Gc, 0, 255);
+    o.b = rsClamp(Bc, 0, 255);
+    o.a = 0xff;
+    return o;
 }
 
 void prepareVibrance() {
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.fs b/java/tests/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.rs
similarity index 100%
rename from java/tests/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.fs
rename to java/tests/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.rs
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.fs b/java/tests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.rs
similarity index 96%
rename from java/tests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.fs
rename to java/tests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.rs
index 8202c5c..262d516 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.fs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 #include "vignette.rsh"
 
diff --git a/java/tests/ImageProcessing2/src/com/android/rs/image/fisheye.rsh b/java/tests/ImageProcessing2/src/com/android/rs/image/fisheye.rsh
index 2eacb7d..fb95005 100644
--- a/java/tests/ImageProcessing2/src/com/android/rs/image/fisheye.rsh
+++ b/java/tests/ImageProcessing2/src/com/android/rs/image/fisheye.rsh
@@ -33,7 +33,7 @@
         axis_scale.y = (float)dim_y / (float)dim_x;
     else
         axis_scale.x = (float)dim_x / (float)dim_y;
-    
+
     const float bound2 = 0.25f * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
     const float bound = sqrt(bound2);
     const float radius = 1.15f * bound;
diff --git a/java/tests/ImageProcessing_jb/Android.mk b/java/tests/ImageProcessing_jb/Android.mk
index 20d6be7..680c1de 100644
--- a/java/tests/ImageProcessing_jb/Android.mk
+++ b/java/tests/ImageProcessing_jb/Android.mk
@@ -24,6 +24,6 @@
 #LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
 
 LOCAL_PACKAGE_NAME := ImageProcessingJB
-LOCAL_SDK_VERSION := 17
+LOCAL_SDK_VERSION := 18
 
 include $(BUILD_PACKAGE)
diff --git a/java/tests/ImageProcessing_jb/AndroidManifest.xml b/java/tests/ImageProcessing_jb/AndroidManifest.xml
index b3fcfc4..7d42883 100644
--- a/java/tests/ImageProcessing_jb/AndroidManifest.xml
+++ b/java/tests/ImageProcessing_jb/AndroidManifest.xml
@@ -4,11 +4,17 @@
     package="com.android.rs.imagejb">
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-sdk android:minSdkVersion="11" />
-    <application android:label="Image Processing JB"
+    <application android:label="IP-18"
                  android:hardwareAccelerated="true">
         <activity android:name="ImageProcessingActivityJB">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+
+        <activity class=".IPControlsJB" android:name="IPControlsJB">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
diff --git a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1280x720a.jpg b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1280x720a.jpg
new file mode 100644
index 0000000..ff09574
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1280x720a.jpg
Binary files differ
diff --git a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1280x720b.jpg b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1280x720b.jpg
new file mode 100644
index 0000000..e9f6aa4
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1280x720b.jpg
Binary files differ
diff --git a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1600x1067.jpg b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1600x1067.jpg
deleted file mode 100644
index 05d3ee2..0000000
--- a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1600x1067.jpg
+++ /dev/null
Binary files differ
diff --git a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1600x1067b.jpg b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1600x1067b.jpg
deleted file mode 100644
index aed0781..0000000
--- a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1600x1067b.jpg
+++ /dev/null
Binary files differ
diff --git a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1920x1080a.jpg b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1920x1080a.jpg
new file mode 100644
index 0000000..80b16ab
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1920x1080a.jpg
Binary files differ
diff --git a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1920x1080b.jpg b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1920x1080b.jpg
new file mode 100644
index 0000000..b4883d6
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img1920x1080b.jpg
Binary files differ
diff --git a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img3840x2160a.jpg b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img3840x2160a.jpg
new file mode 100644
index 0000000..871b22c
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img3840x2160a.jpg
Binary files differ
diff --git a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img3840x2160b.jpg b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img3840x2160b.jpg
new file mode 100644
index 0000000..281bed0
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img3840x2160b.jpg
Binary files differ
diff --git a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img800x450a.jpg b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img800x450a.jpg
new file mode 100644
index 0000000..6d5b623
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img800x450a.jpg
Binary files differ
diff --git a/java/tests/ImageProcessing_jb/res/drawable-nodpi/img800x450b.jpg b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img800x450b.jpg
new file mode 100644
index 0000000..2013e07
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/res/drawable-nodpi/img800x450b.jpg
Binary files differ
diff --git a/java/tests/ImageProcessing_jb/res/layout/controls.xml b/java/tests/ImageProcessing_jb/res/layout/controls.xml
new file mode 100644
index 0000000..0e89dd9
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/res/layout/controls.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+            android:orientation="vertical"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:id="@+id/toplevel">
+
+    <Spinner
+        android:id="@+id/image_size"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"/>
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent" android:layout_height="wrap_content">
+        <ToggleButton android:id="@+id/io_control"
+             android:layout_width="wrap_content"
+             android:layout_height="wrap_content"
+             android:textColorLink="@android:color/holo_blue_light"
+             android:textOff="@string/io_control_on"
+             android:textOn="@string/io_control_off"
+             android:textSize="12dp"/>
+        <ToggleButton
+             android:id="@+id/length_control"
+             android:layout_width="wrap_content"
+             android:layout_height="wrap_content"
+             android:textColorLink="@android:color/holo_blue_light"
+             android:textOff="@string/length_long"
+             android:textOn="@string/length_short"
+             android:textSize="12dp"/>
+        <ToggleButton
+             android:id="@+id/background_work"
+             android:layout_width="wrap_content"
+             android:layout_height="wrap_content"
+             android:textColorLink="@android:color/holo_blue_light"
+             android:textOff="@string/dvfs_on"
+             android:textOn="@string/dvfs_off"
+             android:textSize="12dp"/>
+        <ToggleButton
+             android:id="@+id/pause"
+             android:layout_width="wrap_content"
+             android:layout_height="wrap_content"
+             android:textColorLink="@android:color/holo_blue_light"
+             android:textOff="@string/pause_on"
+             android:textOn="@string/pause_off"
+             android:textSize="12dp"/>
+    </LinearLayout>
+
+    <ListView
+        android:id="@+id/test_list"
+        android:layout_weight="0.2"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"/>
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="fill_parent" android:layout_height="wrap_content">
+        <Button
+         android:id="@+id/select_all"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content"
+         android:text="@string/select_all"
+         android:textSize="12dp"
+         android:onClick="btnSelAll"/>
+        <Button
+         android:id="@+id/select_none"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content"
+         android:text="@string/select_none"
+         android:textSize="12dp"
+         android:onClick="btnSelNone"/>
+        <Button
+         android:id="@+id/select_hp"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content"
+         android:text="@string/select_hp"
+         android:textSize="12dp"
+         android:onClick="btnSelHp"/>
+        <Button
+         android:id="@+id/select_lp"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content"
+         android:text="@string/select_lp"
+         android:textSize="12dp"
+         android:onClick="btnSelLp"/>
+        <Button
+         android:id="@+id/select_intrinsics"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content"
+         android:text="@string/select_intrinsics"
+         android:textSize="12dp"
+         android:onClick="btnSelIntrinsic"/>
+    </LinearLayout>
+
+    <Button
+         android:id="@+id/run"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content"
+         android:text="@string/benchmark"
+         android:onClick="btnRun"/>
+
+    <TextView
+        android:id="@+id/results"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textSize="8pt"
+        android:layout_marginLeft="10sp"
+        android:layout_marginTop="15sp"
+        android:text="@string/results"/>
+
+</LinearLayout>
+
diff --git a/java/tests/ImageProcessing_jb/res/layout/main.xml b/java/tests/ImageProcessing_jb/res/layout/main.xml
index f0a2b92..f98d05d 100644
--- a/java/tests/ImageProcessing_jb/res/layout/main.xml
+++ b/java/tests/ImageProcessing_jb/res/layout/main.xml
@@ -30,33 +30,24 @@
                 android:orientation="vertical"
                 android:layout_width="fill_parent"
                 android:layout_height="fill_parent">
-            <ImageView
-                android:id="@+id/display"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content" />
+
             <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:orientation="horizontal"
-                android:layout_width="fill_parent"
+                android:layout_width="wrap_content"
                 android:layout_height="wrap_content">
-                    <Button
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:text="@string/benchmark"
-                        android:onClick="benchmark"/>
-                    <TextView
-                        android:id="@+id/benchmarkText"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:textSize="8pt"
-                        android:text="@string/saturation"/>
+		    <view class="com.android.rs.imagejb.ImageProcessingActivityJB$SizedTV"
+		        android:id="@+id/display"
+		        android:layout_width="wrap_content"
+		        android:layout_height="wrap_content" />
+		    <ImageView
+		        android:id="@+id/display2"
+		        android:layout_width="wrap_content"
+		        android:layout_height="wrap_content" />
             </LinearLayout>
-            <Spinner
-                android:id="@+id/filterselection"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"/>
+
             <Spinner
                 android:id="@+id/spinner1"
-                android:layout_width="fill_parent"
+                android:layout_width="wrap_content"
                 android:layout_height="wrap_content"/>
             <TextView
                 android:id="@+id/slider1Text"
@@ -128,11 +119,6 @@
                 android:layout_marginRight="10sp"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"/>
-            <Button
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/benchmark_all"
-                    android:onClick="benchmark_all"/>
             </LinearLayout>
     </ScrollView>
 </LinearLayout>
diff --git a/java/tests/ImageProcessing_jb/res/values/strings.xml b/java/tests/ImageProcessing_jb/res/values/strings.xml
index a7dd165..fdaefcd 100644
--- a/java/tests/ImageProcessing_jb/res/values/strings.xml
+++ b/java/tests/ImageProcessing_jb/res/values/strings.xml
@@ -29,6 +29,23 @@
     <string name="gamma">Gamma</string>
     <string name="saturation">Saturation</string>
     <string name="benchmark">Benchmark</string>
-    <string name="benchmark_all">Benchmark All</string>
+
+    <string name="results">Results: not run</string>
+
+    <string name="io_control_on">USAGE_IO</string>
+    <string name="io_control_off">USAGE_IO</string>
+    <string name="length_long">Long run</string>
+    <string name="length_short">Long run</string>
+    <string name="dvfs_on">Background work</string>
+    <string name="dvfs_off">Background work</string>
+    <string name="run_all">Benchmark All</string>
+    <string name="run_one">Benchmark One</string>
+    <string name="select_all">All</string>
+    <string name="select_none">None</string>
+    <string name="select_hp">Full FP</string>
+    <string name="select_lp">Relaxed FP</string>
+    <string name="pause_on">Pause</string>
+    <string name="pause_off">Pause</string>
+    <string name="select_intrinsics">Intrinsics</string>
 
 </resources>
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Artistic1.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Artistic1.java
new file mode 100644
index 0000000..181493d
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Artistic1.java
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+package com.android.rs.imagejb;
+
+import java.lang.Math;
+
+import android.renderscript.*;
+import android.util.Log;
+
+public class Artistic1 extends TestBase {
+    private ScriptC_artistic1 mScript;
+    private Allocation mBlured;
+
+    public void createTest(android.content.res.Resources res) {
+        mScript = new ScriptC_artistic1(mRS);
+        mBlured = Allocation.createTyped(mRS, mInPixelsAllocation.getType());
+        mScript.set_gBlur(mBlured);
+
+        ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(mRS, Element.U8_4(mRS));
+        blur.setRadius(20);
+        blur.setInput(mInPixelsAllocation);
+        blur.forEach(mBlured);
+    }
+
+    public void runTest() {
+        mScript.invoke_setup();
+        mScript.forEach_process(mInPixelsAllocation, mOutPixelsAllocation);
+    }
+
+}
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blend.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blend.java
index 302dc31..63c0c9c 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blend.java
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blend.java
@@ -25,7 +25,6 @@
 import android.renderscript.RenderScript;
 import android.renderscript.Script;
 import android.renderscript.ScriptC;
-import android.renderscript.ScriptGroup;
 import android.renderscript.ScriptIntrinsicBlend;
 import android.renderscript.Type;
 import android.util.Log;
@@ -122,10 +121,10 @@
         image2.copy2DRangeFrom(0, 0, mInPixelsAllocation2.getType().getX(), mInPixelsAllocation2.getType().getY(), mInPixelsAllocation2, 0, 0);
 
         mBlendHelper.set_alpha(image1Alpha);
-        mBlendHelper.forEach_setImageAlpha(image1);
+        mBlendHelper.forEach_setImageAlpha(image1, image1);
 
         mBlendHelper.set_alpha(image2Alpha);
-        mBlendHelper.forEach_setImageAlpha(image2);
+        mBlendHelper.forEach_setImageAlpha(image2, image2);
 
         switch (currentIntrinsic) {
         case 0:
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blur25G.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blur25G.java
new file mode 100644
index 0000000..6e0cf59
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Blur25G.java
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+package com.android.rs.imagejb;
+
+import java.lang.Math;
+
+import android.graphics.Bitmap;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.ScriptIntrinsicBlur;
+import android.renderscript.ScriptIntrinsicColorMatrix;
+import android.renderscript.Type;
+import android.renderscript.Matrix4f;
+import android.util.Log;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+public class Blur25G extends TestBase {
+    private final int MAX_RADIUS = 25;
+    private float mRadius = MAX_RADIUS;
+
+    private ScriptIntrinsicBlur mIntrinsic;
+
+    private ScriptC_greyscale mScript;
+    private Allocation mScratchPixelsAllocation1;
+    private Allocation mScratchPixelsAllocation2;
+
+
+    public Blur25G() {
+    }
+
+    public boolean onBar1Setup(SeekBar b, TextView t) {
+        t.setText("Radius");
+        b.setProgress(100);
+        return true;
+    }
+
+
+    public void onBar1Changed(int progress) {
+        mRadius = ((float)progress) / 100.0f * MAX_RADIUS;
+        if (mRadius <= 0.10f) {
+            mRadius = 0.10f;
+        }
+        mIntrinsic.setRadius(mRadius);
+    }
+
+
+    public void createTest(android.content.res.Resources res) {
+        int width = mInPixelsAllocation.getType().getX();
+        int height = mInPixelsAllocation.getType().getY();
+
+        Type.Builder tb = new Type.Builder(mRS, Element.U8(mRS));
+        tb.setX(width);
+        tb.setY(height);
+        mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create());
+        mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create());
+
+        mScript = new ScriptC_greyscale(mRS);
+        mScript.forEach_toU8(mInPixelsAllocation, mScratchPixelsAllocation1);
+
+        mIntrinsic = ScriptIntrinsicBlur.create(mRS, Element.U8(mRS));
+        mIntrinsic.setRadius(MAX_RADIUS);
+        mIntrinsic.setInput(mScratchPixelsAllocation1);
+    }
+
+    public void runTest() {
+        mIntrinsic.forEach(mScratchPixelsAllocation2);
+    }
+
+    public void setupBenchmark() {
+        mIntrinsic.setRadius(MAX_RADIUS);
+    }
+
+    public void exitBenchmark() {
+        mIntrinsic.setRadius(mRadius);
+    }
+
+    public void updateBitmap(Bitmap b) {
+        mScript.forEach_toU8_4(mScratchPixelsAllocation2, mOutPixelsAllocation);
+        mOutPixelsAllocation.copyTo(b);
+    }
+
+}
+
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/ColorCube.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ColorCube.java
new file mode 100644
index 0000000..0153f40
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ColorCube.java
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+package com.android.rs.imagejb;
+
+import java.lang.Math;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Matrix4f;
+import android.renderscript.RenderScript;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
+import android.renderscript.ScriptIntrinsic3DLUT;
+import android.renderscript.ScriptIntrinsicColorMatrix;
+import android.renderscript.Type;
+import android.util.Log;
+
+public class ColorCube extends TestBase {
+    private Allocation mCube;
+    private ScriptC_colorcube mScript;
+    private ScriptIntrinsic3DLUT mIntrinsic;
+    private boolean mUseIntrinsic;
+
+    public ColorCube(boolean useIntrinsic) {
+        mUseIntrinsic = useIntrinsic;
+    }
+
+    private void initCube() {
+        final int sx = 32;
+        final int sy = 32;
+        final int sz = 16;
+
+        Type.Builder tb = new Type.Builder(mRS, Element.U8_4(mRS));
+        tb.setX(sx);
+        tb.setY(sy);
+        tb.setZ(sz);
+        Type t = tb.create();
+        mCube = Allocation.createTyped(mRS, t);
+
+        int dat[] = new int[sx * sy * sz];
+        for (int z = 0; z < sz; z++) {
+            for (int y = 0; y < sy; y++) {
+                for (int x = 0; x < sx; x++ ) {
+                    int v = 0xff000000;
+                    v |= (0xff * x / (sx - 1));
+                    v |= (0xff * y / (sy - 1)) << 8;
+                    v |= (0xff * z / (sz - 1)) << 16;
+                    dat[z*sy*sx + y*sx + x] = v;
+                }
+            }
+        }
+
+        mCube.copyFromUnchecked(dat);
+    }
+
+    public void createTest(android.content.res.Resources res) {
+        mScript = new ScriptC_colorcube(mRS, res, R.raw.colorcube);
+        mIntrinsic = ScriptIntrinsic3DLUT.create(mRS, Element.U8_4(mRS));
+
+        initCube();
+        mScript.invoke_setCube(mCube);
+        mIntrinsic.setLUT(mCube);
+    }
+
+    public void runTest() {
+        if (mUseIntrinsic) {
+            mIntrinsic.forEach(mInPixelsAllocation, mOutPixelsAllocation);
+        } else {
+            mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
+        }
+    }
+
+}
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/ColorMatrix.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ColorMatrix.java
index 5053d4d..a3823b6 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/ColorMatrix.java
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ColorMatrix.java
@@ -24,7 +24,6 @@
 import android.renderscript.RenderScript;
 import android.renderscript.Script;
 import android.renderscript.ScriptC;
-import android.renderscript.ScriptGroup;
 import android.renderscript.ScriptIntrinsicColorMatrix;
 import android.renderscript.Type;
 import android.util.Log;
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve3x3.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve3x3.java
index d7acf4a..f70f7b4 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve3x3.java
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve3x3.java
@@ -24,7 +24,6 @@
 import android.renderscript.RenderScript;
 import android.renderscript.Script;
 import android.renderscript.ScriptC;
-import android.renderscript.ScriptGroup;
 import android.renderscript.ScriptIntrinsicConvolve3x3;
 import android.renderscript.Type;
 import android.util.Log;
@@ -64,7 +63,11 @@
     }
 
     public void runTest() {
-        mScript.forEach_root(mOutPixelsAllocation);
+        if (mUseIntrinsic) {
+            mIntrinsic.forEach(mOutPixelsAllocation);
+        } else {
+            mScript.forEach_root(mOutPixelsAllocation);
+        }
     }
 
 }
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve5x5.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve5x5.java
index d1dbb1f..c332074 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve5x5.java
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Convolve5x5.java
@@ -24,7 +24,6 @@
 import android.renderscript.RenderScript;
 import android.renderscript.Script;
 import android.renderscript.ScriptC;
-import android.renderscript.ScriptGroup;
 import android.renderscript.ScriptIntrinsicConvolve5x5;
 import android.renderscript.Type;
 import android.util.Log;
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPControlsJB.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPControlsJB.java
new file mode 100644
index 0000000..597e645
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPControlsJB.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+package com.android.rs.imagejb;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.graphics.Canvas;
+import android.graphics.Point;
+import android.view.SurfaceView;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.Spinner;
+import android.widget.ToggleButton;
+import android.widget.TextView;
+import android.widget.CompoundButton;
+import android.widget.ListView;
+import android.view.View;
+import java.util.ArrayList;
+import java.util.ListIterator;
+import android.util.Log;
+import android.content.Intent;
+
+import android.os.Environment;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+public class IPControlsJB extends Activity {
+    private final String TAG = "Img";
+    public final String RESULT_FILE = "image_processing_result.csv";
+
+    private ToggleButton mIOButton;
+    private Spinner mResSpinner;
+    private ListView mTestListView;
+    private TextView mResultView;
+
+    private ArrayAdapter<String> mTestListAdapter;
+    private ArrayList<String> mTestList = new ArrayList<String>();
+
+    private boolean mToggleIO = false;
+    private boolean mToggleDVFS = true;
+    private boolean mToggleLong = false;
+    private boolean mTogglePause = false;
+
+    private float mResults[];
+
+    public enum Resolutions {
+        RES_4K(3840, 2160, "4k (3840x2160)"),
+        RES_1080P(1920, 1080, "1080p (1920x1080)"),
+        RES_720P(1280, 720, "720p (1280x720)"),
+        RES_WVGA(800, 480, "WVGA (800x480)");
+
+        private final String name;
+        public final int width;
+        public final int height;
+
+        private Resolutions(int w, int h, String s) {
+            width = w;
+            height = h;
+            name = s;
+        }
+
+        // return quoted string as displayed test name
+        public String toString() {
+            return name;
+        }
+    }
+    private Resolutions mRes;
+
+
+    private AdapterView.OnItemSelectedListener mResSpinnerListener =
+            new AdapterView.OnItemSelectedListener() {
+                public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+                    mRes = Resolutions.values()[pos];
+                }
+
+                public void onNothingSelected(AdapterView parent) {
+                }
+            };
+
+    void init() {
+        mIOButton = (ToggleButton) findViewById(R.id.io_control);
+
+        mResSpinner = (Spinner) findViewById(R.id.image_size);
+        mResSpinner.setOnItemSelectedListener(mResSpinnerListener);
+        mResSpinner.setAdapter(new ArrayAdapter<Resolutions>(
+            this, R.layout.spinner_layout, Resolutions.values()));
+
+        for (int i=0; i < IPTestListJB.TestName.values().length; i++) {
+            mTestList.add(IPTestListJB.TestName.values()[i].toString());
+        }
+
+        mTestListView = (ListView) findViewById(R.id.test_list);
+        mTestListAdapter = new ArrayAdapter(this,
+                android.R.layout.simple_list_item_activated_1,
+                mTestList);
+
+        mTestListView.setAdapter(mTestListAdapter);
+        mTestListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+        mTestListAdapter.notifyDataSetChanged();
+
+        ToggleButton toggle;
+        toggle = (ToggleButton) findViewById(R.id.io_control);
+        toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                mToggleIO = isChecked;
+            }
+        });
+        toggle.setChecked(mToggleIO);
+
+        toggle = (ToggleButton) findViewById(R.id.length_control);
+        toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                mToggleLong = isChecked;
+            }
+        });
+        toggle.setChecked(mToggleLong);
+
+        toggle = (ToggleButton) findViewById(R.id.background_work);
+        toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                mToggleDVFS = isChecked;
+            }
+        });
+        toggle.setChecked(mToggleDVFS);
+
+        toggle = (ToggleButton) findViewById(R.id.pause);
+        toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                mTogglePause = isChecked;
+            }
+        });
+        toggle.setChecked(mTogglePause);
+
+        mResultView = (TextView) findViewById(R.id.results);
+
+
+        Point size = new Point();
+        getWindowManager().getDefaultDisplay().getSize(size);
+        int md = (size.x > size.y) ? size.x : size.y;
+        for (int ct=0; ct < Resolutions.values().length; ct++) {
+            if (Resolutions.values()[ct].width <= (int)(md * 1.2)) {
+                mResSpinner.setSelection(ct);
+                break;
+            }
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.controls);
+        init();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        //cleanup();
+    }
+
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+       // init();
+    }
+
+    private void checkGroup(int group) {
+        IPTestListJB.TestName t[] = IPTestListJB.TestName.values();
+        for (int i=0; i < t.length; i++) {
+            mTestListView.setItemChecked(i, group == t[i].group);
+        }
+    }
+
+    public void btnRun(View v) {
+        IPTestListJB.TestName t[] = IPTestListJB.TestName.values();
+
+        int count = 0;
+        for (int i = 0; i < t.length; i++) {
+            if (mTestListView.isItemChecked(i)) {
+                count++;
+            }
+        }
+        if (count == 0) {
+            return;
+        }
+
+        int testList[] = new int[count];
+        count = 0;
+        for (int i = 0; i < t.length; i++) {
+            if (mTestListView.isItemChecked(i)) {
+                testList[count++] = i;
+            }
+        }
+
+        Intent intent = new Intent(this, ImageProcessingActivityJB.class);
+        intent.putExtra("tests", testList);
+        intent.putExtra("enable io", mToggleIO);
+        intent.putExtra("enable dvfs", mToggleDVFS);
+        intent.putExtra("enable long", mToggleLong);
+        intent.putExtra("enable pause", mTogglePause);
+        intent.putExtra("resolution X", mRes.width);
+        intent.putExtra("resolution Y", mRes.height);
+        startActivityForResult(intent, 0);
+    }
+
+    float rebase(float v, IPTestListJB.TestName t) {
+        if (v > 0.001) {
+            v = t.baseline / v;
+        }
+        float pr = (1920.f / mRes.width) * (1080.f / mRes.height);
+        return v / pr;
+    }
+
+    private void writeResults() {
+        // write result into a file
+        File externalStorage = Environment.getExternalStorageDirectory();
+        if (!externalStorage.canWrite()) {
+            Log.v(TAG, "sdcard is not writable");
+            return;
+        }
+        File resultFile = new File(externalStorage, RESULT_FILE);
+        resultFile.setWritable(true, false);
+        try {
+            BufferedWriter rsWriter = new BufferedWriter(new FileWriter(resultFile));
+            Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath());
+            java.text.DecimalFormat df = new java.text.DecimalFormat("######.##");
+
+            for (int ct=0; ct < IPTestListJB.TestName.values().length; ct++) {
+                IPTestListJB.TestName t = IPTestListJB.TestName.values()[ct];
+                final float r = mResults[ct];
+                float r2 = rebase(r, t);
+                String s = new String("" + t.toString() + ", " + df.format(r) + ", " + df.format(r2));
+                rsWriter.write(s + "\n");
+            }
+            rsWriter.close();
+        } catch (IOException e) {
+            Log.v(TAG, "Unable to write result file " + e.getMessage());
+        }
+    }
+
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == 0) {
+            if (resultCode == RESULT_OK) {
+                java.text.DecimalFormat df = new java.text.DecimalFormat("######.#");
+                mResults = new float[IPTestListJB.TestName.values().length];
+
+                float r[] = data.getFloatArrayExtra("results");
+                int id[] = data.getIntArrayExtra("tests");
+
+                for (int ct=0; ct < id.length; ct++) {
+                    IPTestListJB.TestName t = IPTestListJB.TestName.values()[id[ct]];
+
+                    String s = t.toString() + "   " + df.format(rebase(r[ct], t)) +
+                            "X,   " + df.format(r[ct]) + "ms";
+                    mTestList.set(id[ct], s);
+                    mTestListAdapter.notifyDataSetChanged();
+                    mResults[id[ct]] = r[ct];
+                }
+
+                double gm[] = {1.0, 1.0, 1.0};
+                double count[] = {0, 0, 0};
+                for (int ct=0; ct < IPTestListJB.TestName.values().length; ct++) {
+                    IPTestListJB.TestName t = IPTestListJB.TestName.values()[ct];
+                    gm[t.group] *= rebase(mResults[ct], t);
+                    count[t.group] += 1.0;
+                }
+                gm[0] = java.lang.Math.pow(gm[0], 1.0 / count[0]);
+                gm[1] = java.lang.Math.pow(gm[1], 1.0 / count[1]);
+                gm[2] = java.lang.Math.pow(gm[2], 1.0 / count[2]);
+
+                String s = "Results:  fp full=" + df.format(gm[0]) +
+                        ",  fp relaxed=" +df.format(gm[1]) +
+                        ",  intrinsics=" + df.format(gm[2]);
+                mResultView.setText(s);
+                writeResults();
+            }
+        }
+    }
+
+    public void btnSelAll(View v) {
+        IPTestListJB.TestName t[] = IPTestListJB.TestName.values();
+        for (int i=0; i < t.length; i++) {
+            mTestListView.setItemChecked(i, true);
+        }
+    }
+
+    public void btnSelNone(View v) {
+        checkGroup(-1);
+    }
+
+    public void btnSelHp(View v) {
+        checkGroup(0);
+    }
+
+    public void btnSelLp(View v) {
+        checkGroup(1);
+    }
+
+    public void btnSelIntrinsic(View v) {
+        checkGroup(2);
+    }
+
+
+
+}
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPTestListJB.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPTestListJB.java
new file mode 100644
index 0000000..4bf99e3
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/IPTestListJB.java
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ */
+
+package com.android.rs.imagejb;
+
+import android.app.Activity;
+import android.view.View;
+import android.util.Log;
+
+public class IPTestListJB {
+    private final String TAG = "Img";
+    public final String RESULT_FILE = "image_processing_result.csv";
+
+    public static final int FULL_FP = 0;
+    public static final int RELAXED_FP = 1;
+    public static final int INTRINSIC = 2;
+
+    /**
+     * Define enum type for test names
+     */
+    public enum TestName {
+        LEVELS_VEC3_RELAXED ("Levels Vec3 Relaxed", RELAXED_FP, 55.6f),
+        LEVELS_VEC4_RELAXED ("Levels Vec4 Relaxed", RELAXED_FP, 39.1f),
+        LEVELS_VEC3_FULL ("Levels Vec3 Full", FULL_FP, 57.4f),
+        LEVELS_VEC4_FULL ("Levels Vec4 Full", FULL_FP, 68.1f),
+        BLUR_RADIUS_25 ("Blur radius 25", RELAXED_FP, 1045.f),
+        INTRINSIC_BLUR_RADIUS_25 ("Intrinsic Blur radius 25", INTRINSIC, 643.f),
+        GREYSCALE ("Greyscale", RELAXED_FP, 38.3f),
+        GRAIN ("Grain", RELAXED_FP, 57.8f),
+        FISHEYE_FULL ("Fisheye Full", FULL_FP, 211.2f),
+        FISHEYE_RELAXED ("Fisheye Relaxed", RELAXED_FP, 198.1f),
+        FISHEYE_APPROXIMATE_FULL ("Fisheye Approximate Full", FULL_FP, 211.0f),
+        FISHEYE_APPROXIMATE_RELAXED ("Fisheye Approximate Relaxed", RELAXED_FP, 190.1f),
+        VIGNETTE_FULL ("Vignette Full", FULL_FP, 98.6f),
+        VIGNETTE_RELAXED ("Vignette Relaxed", RELAXED_FP, 110.7f),
+        VIGNETTE_APPROXIMATE_FULL ("Vignette Approximate Full", FULL_FP, 80.6f),
+        VIGNETTE_APPROXIMATE_RELAXED ("Vignette Approximate Relaxed", RELAXED_FP, 87.9f),
+        GROUP_TEST_EMULATED ("Group Test (emulated)", INTRINSIC, 37.81f),
+        GROUP_TEST_NATIVE ("Group Test (native)", INTRINSIC, 37.8f),
+        CONVOLVE_3X3 ("Convolve 3x3", RELAXED_FP, 62.1f),
+        INTRINSICS_CONVOLVE_3X3 ("Intrinsics Convolve 3x3", INTRINSIC, 24.5f),
+        COLOR_MATRIX ("ColorMatrix", RELAXED_FP, 25.5f),
+        INTRINSICS_COLOR_MATRIX ("Intrinsics ColorMatrix", INTRINSIC, 13.3f),
+        INTRINSICS_COLOR_MATRIX_GREY ("Intrinsics ColorMatrix Grey", INTRINSIC, 13.4f),
+        COPY ("Copy", RELAXED_FP, 25.6f),
+        CROSS_PROCESS_USING_LUT ("CrossProcess (using LUT)", INTRINSIC, 18.6f),
+        CONVOLVE_5X5 ("Convolve 5x5", RELAXED_FP, 215.8f),
+        INTRINSICS_CONVOLVE_5X5 ("Intrinsics Convolve 5x5", INTRINSIC, 29.8f),
+        MANDELBROT_FLOAT ("Mandelbrot (fp32)", FULL_FP, 108.1f),
+        MANDELBROT_DOUBLE ("Mandelbrot (fp64)", FULL_FP, 108.1f),
+        INTRINSICS_BLEND ("Intrinsics Blend", INTRINSIC, 94.2f),
+        INTRINSICS_BLUR_25G ("Intrinsics Blur 25 uchar", INTRINSIC, 173.3f),
+        VIBRANCE ("Vibrance", RELAXED_FP, 88.3f),
+        BW_FILTER ("BW Filter", RELAXED_FP, 69.7f),
+        SHADOWS ("Shadows", RELAXED_FP, 155.3f),
+        CONTRAST ("Contrast", RELAXED_FP, 27.0f),
+        EXPOSURE ("Exposure", RELAXED_FP, 64.7f),
+        WHITE_BALANCE ("White Balance", RELAXED_FP, 160.1f),
+        COLOR_CUBE ("Color Cube", RELAXED_FP, 85.3f),
+        COLOR_CUBE_3D_INTRINSIC ("Color Cube (3D LUT intrinsic)", INTRINSIC, 49.5f),
+        ARTISTIC1 ("Artistic 1", RELAXED_FP, 120.f);
+
+
+        private final String name;
+        public final int group;
+        public final float baseline;
+
+        private TestName(String s, int g, float base) {
+            name = s;
+            group = g;
+            baseline = base;
+        }
+        private TestName(String s, int g) {
+            name = s;
+            group = g;
+            baseline = 1.f;
+        }
+
+        // return quoted string as displayed test name
+        public String toString() {
+            return name;
+        }
+    }
+
+    static TestBase newTest(TestName testName) {
+        switch(testName) {
+        case LEVELS_VEC3_RELAXED:
+            return new LevelsV4(false, false);
+        case LEVELS_VEC4_RELAXED:
+            return new LevelsV4(false, true);
+        case LEVELS_VEC3_FULL:
+            return new LevelsV4(true, false);
+        case LEVELS_VEC4_FULL:
+            return new LevelsV4(true, true);
+        case BLUR_RADIUS_25:
+            return new Blur25(false);
+        case INTRINSIC_BLUR_RADIUS_25:
+            return new Blur25(true);
+        case GREYSCALE:
+            return new Greyscale();
+        case GRAIN:
+            return new Grain();
+        case FISHEYE_FULL:
+            return new Fisheye(false, false);
+        case FISHEYE_RELAXED:
+            return new Fisheye(false, true);
+        case FISHEYE_APPROXIMATE_FULL:
+            return new Fisheye(true, false);
+        case FISHEYE_APPROXIMATE_RELAXED:
+            return new Fisheye(true, true);
+        case VIGNETTE_FULL:
+            return new Vignette(false, false);
+        case VIGNETTE_RELAXED:
+            return new Vignette(false, true);
+        case VIGNETTE_APPROXIMATE_FULL:
+            return new Vignette(true, false);
+        case VIGNETTE_APPROXIMATE_RELAXED:
+            return new Vignette(true, true);
+        case GROUP_TEST_EMULATED:
+            return new GroupTest(false);
+        case GROUP_TEST_NATIVE:
+            return new GroupTest(true);
+        case CONVOLVE_3X3:
+            return new Convolve3x3(false);
+        case INTRINSICS_CONVOLVE_3X3:
+            return new Convolve3x3(true);
+        case COLOR_MATRIX:
+            return new ColorMatrix(false, false);
+        case INTRINSICS_COLOR_MATRIX:
+            return new ColorMatrix(true, false);
+        case INTRINSICS_COLOR_MATRIX_GREY:
+            return new ColorMatrix(true, true);
+        case COPY:
+            return new Copy();
+        case CROSS_PROCESS_USING_LUT:
+            return new CrossProcess();
+        case CONVOLVE_5X5:
+            return new Convolve5x5(false);
+        case INTRINSICS_CONVOLVE_5X5:
+            return new Convolve5x5(true);
+        case MANDELBROT_FLOAT:
+            return new Mandelbrot(false);
+        case MANDELBROT_DOUBLE:
+            return new Mandelbrot(true);
+        case INTRINSICS_BLEND:
+            return new Blend();
+        case INTRINSICS_BLUR_25G:
+            return new Blur25G();
+        case VIBRANCE:
+            return new Vibrance();
+        case BW_FILTER:
+            return new BWFilter();
+        case SHADOWS:
+            return new Shadows();
+        case CONTRAST:
+            return new Contrast();
+        case EXPOSURE:
+            return new Exposure();
+        case WHITE_BALANCE:
+            return new WhiteBalance();
+        case COLOR_CUBE:
+            return new ColorCube(false);
+        case COLOR_CUBE_3D_INTRINSIC:
+            return new ColorCube(true);
+        case ARTISTIC1:
+            return new Artistic1();
+        }
+        return null;
+    }
+}
+
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingActivityJB.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingActivityJB.java
index 93937ef..d9b35bc 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingActivityJB.java
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/ImageProcessingActivityJB.java
@@ -17,20 +17,21 @@
 package com.android.rs.imagejb;
 
 import android.app.Activity;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
-import android.graphics.BitmapFactory;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.view.SurfaceView;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
-import android.widget.ImageView;
 import android.widget.SeekBar;
 import android.widget.Spinner;
 import android.widget.TextView;
 import android.view.View;
+import android.view.TextureView;
+import android.view.Surface;
+import android.graphics.SurfaceTexture;
+import android.graphics.Point;
+
 import android.util.Log;
 import android.renderscript.ScriptC;
 import android.renderscript.RenderScript;
@@ -39,79 +40,11 @@
 import android.renderscript.Element;
 import android.renderscript.Script;
 
-import android.os.Environment;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
 
 public class ImageProcessingActivityJB extends Activity
-                                       implements SeekBar.OnSeekBarChangeListener {
+                                       implements SeekBar.OnSeekBarChangeListener,
+                                                  TextureView.SurfaceTextureListener {
     private final String TAG = "Img";
-    public final String RESULT_FILE = "image_processing_result.csv";
-
-    RenderScript mRS;
-    Allocation mInPixelsAllocation;
-    Allocation mInPixelsAllocation2;
-    Allocation mOutPixelsAllocation;
-
-    /**
-     * Define enum type for test names
-     */
-    public enum TestName {
-        // totally there are 38 test cases
-        LEVELS_VEC3_RELAXED ("Levels Vec3 Relaxed"),
-        LEVELS_VEC4_RELAXED ("Levels Vec4 Relaxed"),
-        LEVELS_VEC3_FULL ("Levels Vec3 Full"),
-        LEVELS_VEC4_FULL ("Levels Vec4 Full"),
-        BLUR_RADIUS_25 ("Blur radius 25"),
-        INTRINSIC_BLUE_RADIUS_25 ("Intrinsic Blur radius 25"),
-        GREYSCALE ("Greyscale"),
-        GRAIN ("Grain"),
-        FISHEYE_FULL ("Fisheye Full"),
-        FISHEYE_RELAXED ("Fisheye Relaxed"),
-        FISHEYE_APPROXIMATE_FULL ("Fisheye Approximate Full"),
-        FISHEYE_APPROXIMATE_RELAXED ("Fisheye Approximate Relaxed"),
-        VIGNETTE_FULL ("Vignette Full"),
-        VIGNETTE_RELAXED ("Vignette Relaxed"),
-        VIGNETTE_APPROXIMATE_FULL ("Vignette Approximate Full"),
-        VIGNETTE_APPROXIMATE_RELAXED ("Vignette Approximate Relaxed"),
-        GROUP_TEST_EMULATED ("Group Test (emulated)"),
-        GROUP_TEST_NATIVE ("Group Test (native)"),
-        CONVOLVE_3X3 ("Convolve 3x3"),
-        INTRINSICS_CONVOLVE_3X3 ("Intrinsics Convolve 3x3"),
-        COLOR_MATRIX ("ColorMatrix"),
-        INTRINSICS_COLOR_MATRIX ("Intrinsics ColorMatrix"),
-        INTRINSICS_COLOR_MATRIX_GREY ("Intrinsics ColorMatrix Grey"),
-        COPY ("Copy"),
-        CROSS_PROCESS_USING_LUT ("CrossProcess (using LUT)"),
-        CONVOLVE_5X5 ("Convolve 5x5"),
-        INTRINSICS_CONVOLVE_5X5 ("Intrinsics Convolve 5x5"),
-        MANDELBROT ("Mandelbrot"),
-        INTRINSICS_BLEND ("Intrinsics Blend"),
-        VIBRANCE ("Vibrance"),
-        BW_FILTER ("BW Filter"),
-        SHADOWS ("Shadows"),
-        CONTRAST ("Contrast"),
-        EXPOSURE ("Exposure"),
-        WHITE_BALANCE ("White Balance");
-
-
-        private final String name;
-
-        private TestName(String s) {
-            name = s;
-        }
-
-        // return quoted string as displayed test name
-        public String toString() {
-            return name;
-        }
-    }
-
-    Bitmap mBitmapIn;
-    Bitmap mBitmapIn2;
-    Bitmap mBitmapOut;
 
     private Spinner mSpinner;
     private SeekBar mBar1;
@@ -124,77 +57,366 @@
     private TextView mText3;
     private TextView mText4;
     private TextView mText5;
+    private SizedTV mDisplayView;
 
-    private float mSaturation = 1.0f;
+    private int mTestList[];
+    private float mTestResults[];
 
-    private TextView mBenchmarkResult;
-    private Spinner mTestSpinner;
+    private boolean mToggleIO;
+    private boolean mToggleDVFS;
+    private boolean mToggleLong;
+    private boolean mTogglePause;
+    private int mBitmapWidth;
+    private int mBitmapHeight;
 
-    private SurfaceView mSurfaceView;
-    private ImageView mDisplayView;
+    static public class SizedTV extends TextureView {
+        int mWidth;
+        int mHeight;
 
-    private boolean mDoingBenchmark;
+        public SizedTV(android.content.Context c) {
+            super(c);
+            mWidth = 800;
+            mHeight = 450;
+        }
 
-    private TestBase mTest;
-    private int mRunCount;
+        public SizedTV(android.content.Context c, android.util.AttributeSet attrs) {
+            super(c, attrs);
+            mWidth = 800;
+            mHeight = 450;
+        }
 
-    public void updateDisplay() {
-        mHandler.sendMessage(Message.obtain());
+        public SizedTV(android.content.Context c, android.util.AttributeSet attrs, int f) {
+            super(c, attrs, f);
+            mWidth = 800;
+            mHeight = 450;
+        }
+
+        protected void onMeasure(int w, int h) {
+            setMeasuredDimension(mWidth, mHeight);
+        }
     }
 
-    private Handler mHandler = new Handler() {
-        // Allow the filter to complete without blocking the UI
-        // thread.  When the message arrives that the op is complete
-        // we will either mark completion or start a new filter if
-        // more work is ready.  Either way, display the result.
-        @Override
-        public void handleMessage(Message msg) {
-            mTest.updateBitmap(mBitmapOut);
-            mDisplayView.invalidate();
+    /////////////////////////////////////////////////////////////////////////
 
-            boolean doTest = false;
-            synchronized(this) {
-                if (mRunCount > 0) {
-                    mRunCount--;
-                    if (mRunCount > 0) {
-                        doTest = true;
+    class Processor extends Thread {
+        RenderScript mRS;
+        Allocation mInPixelsAllocation;
+        Allocation mInPixelsAllocation2;
+        Allocation mOutDisplayAllocation;
+        Allocation mOutPixelsAllocation;
+
+        private Surface mOutSurface;
+        private float mLastResult;
+        private boolean mRun = true;
+        private int mOp = 0;
+        private boolean mDoingBenchmark;
+        private TestBase mTest;
+        private TextureView mDisplayView;
+
+        private boolean mBenchmarkMode;
+
+        Processor(RenderScript rs, TextureView v, boolean benchmarkMode) {
+            mRS = rs;
+            mDisplayView = v;
+
+            switch(mBitmapWidth) {
+            case 3840:
+                mInPixelsAllocation = Allocation.createFromBitmapResource(
+                        mRS, getResources(), R.drawable.img3840x2160a);
+                mInPixelsAllocation2 = Allocation.createFromBitmapResource(
+                        mRS, getResources(), R.drawable.img3840x2160b);
+                break;
+            case 1920:
+                mInPixelsAllocation = Allocation.createFromBitmapResource(
+                        mRS, getResources(), R.drawable.img1920x1080a);
+                mInPixelsAllocation2 = Allocation.createFromBitmapResource(
+                        mRS, getResources(), R.drawable.img1920x1080b);
+                break;
+            case 1280:
+                mInPixelsAllocation = Allocation.createFromBitmapResource(
+                        mRS, getResources(), R.drawable.img1280x720a);
+                mInPixelsAllocation2 = Allocation.createFromBitmapResource(
+                        mRS, getResources(), R.drawable.img1280x720b);
+                break;
+            case 800:
+                mInPixelsAllocation = Allocation.createFromBitmapResource(
+                        mRS, getResources(), R.drawable.img800x450a);
+                mInPixelsAllocation2 = Allocation.createFromBitmapResource(
+                        mRS, getResources(), R.drawable.img800x450b);
+                break;
+            }
+
+            mOutDisplayAllocation = Allocation.createTyped(mRS, mInPixelsAllocation.getType(),
+                                                               Allocation.MipmapControl.MIPMAP_NONE,
+                                                               Allocation.USAGE_SCRIPT |
+                                                               Allocation.USAGE_IO_OUTPUT);
+            mOutPixelsAllocation = mOutDisplayAllocation;
+
+            if (!mToggleIO) {
+                // Not using USAGE_IO for the script so create a non-io kernel to copy from
+                mOutPixelsAllocation = Allocation.createTyped(mRS, mInPixelsAllocation.getType(),
+                                                              Allocation.MipmapControl.MIPMAP_NONE,
+                                                              Allocation.USAGE_SCRIPT);
+            }
+
+            mBenchmarkMode = benchmarkMode;
+            start();
+        }
+
+        private float getBenchmark() {
+            mDoingBenchmark = true;
+
+            mTest.setupBenchmark();
+            long result = 0;
+            long runtime = 1000;
+            if (mToggleLong) {
+                runtime = 10000;
+            }
+
+            if (mToggleDVFS) {
+                mDvfsWar.go();
+            }
+
+            //Log.v("rs", "Warming");
+            long t = java.lang.System.currentTimeMillis() + 250;
+            do {
+                mTest.runTest();
+                mTest.finish();
+            } while (t > java.lang.System.currentTimeMillis());
+            //mHandler.sendMessage(Message.obtain());
+
+            //Log.v("rs", "Benchmarking");
+            int ct = 0;
+            t = java.lang.System.currentTimeMillis();
+            do {
+                mTest.runTest();
+                mTest.finish();
+                ct++;
+            } while ((t + runtime) > java.lang.System.currentTimeMillis());
+            t = java.lang.System.currentTimeMillis() - t;
+            float ft = (float)t;
+            ft /= ct;
+
+            mTest.exitBenchmark();
+            mDoingBenchmark = false;
+
+            android.util.Log.v("rs", "bench " + ft);
+            return ft;
+        }
+
+        private Handler mHandler = new Handler() {
+            // Allow the filter to complete without blocking the UI
+            // thread.  When the message arrives that the op is complete
+            // we will either mark completion or start a new filter if
+            // more work is ready.  Either way, display the result.
+            @Override
+            public void handleMessage(Message msg) {
+                synchronized(this) {
+                    if (mRS == null || mOutPixelsAllocation == null) {
+                        return;
                     }
+                    if (mOutDisplayAllocation != mOutPixelsAllocation) {
+                        mOutDisplayAllocation.copyFrom(mOutPixelsAllocation);
+                    }
+                    mOutDisplayAllocation.ioSend();
+                    mDisplayView.invalidate();
+                    //mTest.runTestSendMessage();
                 }
             }
-            if (doTest) {
-                mTest.runTestSendMessage();
+        };
+
+        public void run() {
+            Surface lastSurface = null;
+            while (mRun) {
+                synchronized(this) {
+                    try {
+                        this.wait();
+                    } catch(InterruptedException e) {
+                    }
+                    if (!mRun) return;
+
+                    if ((mOutSurface == null) || (mOutPixelsAllocation == null)) {
+                        continue;
+                    }
+
+                    if (lastSurface != mOutSurface) {
+                        mOutDisplayAllocation.setSurface(mOutSurface);
+                        lastSurface = mOutSurface;
+                    }
+                }
+
+                if (mBenchmarkMode) {
+                    for (int ct=0; (ct < mTestList.length) && mRun; ct++) {
+                        mRS.finish();
+
+                        try {
+                            sleep(250);
+                        } catch(InterruptedException e) {
+                        }
+
+                        if (mTest != null) {
+                            mTest.destroy();
+                        }
+
+                        mTest = changeTest(mTestList[ct]);
+                        if (mTogglePause) {
+                            for (int i=0; (i < 100) && mRun; i++) {
+                                try {
+                                    sleep(100);
+                                } catch(InterruptedException e) {
+                                }
+                            }
+                        }
+
+                        mTestResults[ct] = getBenchmark();
+                        mHandler.sendMessage(Message.obtain());
+                    }
+                    onBenchmarkFinish(mRun);
+                }
+            }
+
+        }
+
+        public void update() {
+            synchronized(this) {
+                if (mOp == 0) {
+                    mOp = 2;
+                }
+                notifyAll();
             }
         }
 
+        public void setSurface(Surface s) {
+            synchronized(this) {
+                mOutSurface = s;
+                notifyAll();
+            }
+            //update();
+        }
+
+        public void exit() {
+            mRun = false;
+
+            synchronized(this) {
+                notifyAll();
+            }
+
+            try {
+                this.join();
+            } catch(InterruptedException e) {
+            }
+
+            mInPixelsAllocation.destroy();
+            mInPixelsAllocation2.destroy();
+            if (mOutPixelsAllocation != mOutDisplayAllocation) {
+                mOutPixelsAllocation.destroy();
+            }
+            mOutDisplayAllocation.destroy();
+            mRS.destroy();
+
+            mInPixelsAllocation = null;
+            mInPixelsAllocation2 = null;
+            mOutPixelsAllocation = null;
+            mOutDisplayAllocation = null;
+            mRS = null;
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////////
+
+    static class DVFSWorkaround {
+        static class spinner extends Thread {
+            boolean mRun = true;
+            long mNextSleep;
+
+            spinner() {
+                setPriority(MIN_PRIORITY);
+                start();
+            }
+
+            public void run() {
+                while (mRun) {
+                    Thread.yield();
+                    synchronized(this) {
+                        long t = java.lang.System.currentTimeMillis();
+                        if (t > mNextSleep) {
+                            try {
+                                this.wait();
+                            } catch(InterruptedException e) {
+                            }
+                        }
+                    }
+                }
+            }
+
+            public void go(long t) {
+                synchronized(this) {
+                    mNextSleep = t;
+                    notifyAll();
+                }
+            }
+        }
+
+        spinner s1;
+        DVFSWorkaround() {
+            s1 = new spinner();
+        }
+
+        void go() {
+            long t = java.lang.System.currentTimeMillis() + 2000;
+            s1.go(t);
+        }
+
+        void destroy() {
+            synchronized(this) {
+                s1.mRun = false;
+                notifyAll();
+            }
+        }
+    }
+    DVFSWorkaround mDvfsWar = new DVFSWorkaround();
+
+    ///////////////////////////////////////////////////////////
+
+
+    private boolean mDoingBenchmark;
+    public Processor mProcessor;
+
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            mDisplayView.invalidate();
+        }
     };
 
+    public void updateDisplay() {
+        mHandler.sendMessage(Message.obtain());
+        //mProcessor.update();
+    }
+
+    TestBase changeTest(int id) {
+        IPTestListJB.TestName t = IPTestListJB.TestName.values()[id];
+        TestBase tb = IPTestListJB.newTest(t);
+        tb.createBaseTest(this);
+        //setupBars(tb);
+        return tb;
+    }
+
     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
         if (fromUser) {
-
             if (seekBar == mBar1) {
-                mTest.onBar1Changed(progress);
+                mProcessor.mTest.onBar1Changed(progress);
             } else if (seekBar == mBar2) {
-                mTest.onBar2Changed(progress);
+                mProcessor.mTest.onBar2Changed(progress);
             } else if (seekBar == mBar3) {
-                mTest.onBar3Changed(progress);
+                mProcessor.mTest.onBar3Changed(progress);
             } else if (seekBar == mBar4) {
-                mTest.onBar4Changed(progress);
+                mProcessor.mTest.onBar4Changed(progress);
             } else if (seekBar == mBar5) {
-                mTest.onBar5Changed(progress);
+                mProcessor.mTest.onBar5Changed(progress);
             }
-
-            boolean doTest = false;
-            synchronized(this) {
-                if (mRunCount == 0) {
-                    doTest = true;
-                    mRunCount = 1;
-                } else {
-                    mRunCount = 2;
-                }
-            }
-            if (doTest) {
-                mTest.runTestSendMessage();
-            }
+            mProcessor.update();
         }
     }
 
@@ -204,182 +426,56 @@
     public void onStopTrackingTouch(SeekBar seekBar) {
     }
 
-    void setupBars() {
+    void setupBars(TestBase t) {
         mSpinner.setVisibility(View.VISIBLE);
-        mTest.onSpinner1Setup(mSpinner);
+        t.onSpinner1Setup(mSpinner);
 
         mBar1.setVisibility(View.VISIBLE);
         mText1.setVisibility(View.VISIBLE);
-        mTest.onBar1Setup(mBar1, mText1);
+        t.onBar1Setup(mBar1, mText1);
 
         mBar2.setVisibility(View.VISIBLE);
         mText2.setVisibility(View.VISIBLE);
-        mTest.onBar2Setup(mBar2, mText2);
+        t.onBar2Setup(mBar2, mText2);
 
         mBar3.setVisibility(View.VISIBLE);
         mText3.setVisibility(View.VISIBLE);
-        mTest.onBar3Setup(mBar3, mText3);
+        t.onBar3Setup(mBar3, mText3);
 
         mBar4.setVisibility(View.VISIBLE);
         mText4.setVisibility(View.VISIBLE);
-        mTest.onBar4Setup(mBar4, mText4);
+        t.onBar4Setup(mBar4, mText4);
 
         mBar5.setVisibility(View.VISIBLE);
         mText5.setVisibility(View.VISIBLE);
-        mTest.onBar5Setup(mBar5, mText5);
+        t.onBar5Setup(mBar5, mText5);
     }
 
+    void hideBars() {
+        mSpinner.setVisibility(View.INVISIBLE);
 
-    void changeTest(TestName testName) {
-        if (mTest != null) {
-            mTest.destroy();
-        }
-        switch(testName) {
-        case LEVELS_VEC3_RELAXED:
-            mTest = new LevelsV4(false, false);
-            break;
-        case LEVELS_VEC4_RELAXED:
-            mTest = new LevelsV4(false, true);
-            break;
-        case LEVELS_VEC3_FULL:
-            mTest = new LevelsV4(true, false);
-            break;
-        case LEVELS_VEC4_FULL:
-            mTest = new LevelsV4(true, true);
-            break;
-        case BLUR_RADIUS_25:
-            mTest = new Blur25(false);
-            break;
-        case INTRINSIC_BLUE_RADIUS_25:
-            mTest = new Blur25(true);
-            break;
-        case GREYSCALE:
-            mTest = new Greyscale();
-            break;
-        case GRAIN:
-            mTest = new Grain();
-            break;
-        case FISHEYE_FULL:
-            mTest = new Fisheye(false, false);
-            break;
-        case FISHEYE_RELAXED:
-            mTest = new Fisheye(false, true);
-            break;
-        case FISHEYE_APPROXIMATE_FULL:
-            mTest = new Fisheye(true, false);
-            break;
-        case FISHEYE_APPROXIMATE_RELAXED:
-            mTest = new Fisheye(true, true);
-            break;
-        case VIGNETTE_FULL:
-            mTest = new Vignette(false, false);
-            break;
-        case VIGNETTE_RELAXED:
-            mTest = new Vignette(false, true);
-            break;
-        case VIGNETTE_APPROXIMATE_FULL:
-            mTest = new Vignette(true, false);
-            break;
-        case VIGNETTE_APPROXIMATE_RELAXED:
-            mTest = new Vignette(true, true);
-            break;
-        case GROUP_TEST_EMULATED:
-            mTest = new GroupTest(false);
-            break;
-        case GROUP_TEST_NATIVE:
-            mTest = new GroupTest(true);
-            break;
-        case CONVOLVE_3X3:
-            mTest = new Convolve3x3(false);
-            break;
-        case INTRINSICS_CONVOLVE_3X3:
-            mTest = new Convolve3x3(true);
-            break;
-        case COLOR_MATRIX:
-            mTest = new ColorMatrix(false, false);
-            break;
-        case INTRINSICS_COLOR_MATRIX:
-            mTest = new ColorMatrix(true, false);
-            break;
-        case INTRINSICS_COLOR_MATRIX_GREY:
-            mTest = new ColorMatrix(true, true);
-            break;
-        case COPY:
-            mTest = new Copy();
-            break;
-        case CROSS_PROCESS_USING_LUT:
-            mTest = new CrossProcess();
-            break;
-        case CONVOLVE_5X5:
-            mTest = new Convolve5x5(false);
-            break;
-        case INTRINSICS_CONVOLVE_5X5:
-            mTest = new Convolve5x5(true);
-            break;
-        case MANDELBROT:
-            mTest = new Mandelbrot();
-            break;
-        case INTRINSICS_BLEND:
-            mTest = new Blend();
-            break;
-        case VIBRANCE:
-            mTest = new Vibrance();
-            break;
-        case BW_FILTER:
-            mTest = new BWFilter();
-            break;
-        case SHADOWS:
-            mTest = new Shadows();
-            break;
-        case CONTRAST:
-            mTest = new Contrast();
-            break;
-        case EXPOSURE:
-            mTest = new Exposure();
-            break;
-        case WHITE_BALANCE:
-            mTest = new WhiteBalance();
-            break;
-        }
+        mBar1.setVisibility(View.INVISIBLE);
+        mText1.setVisibility(View.INVISIBLE);
 
-        mTest.createBaseTest(this, mBitmapIn, mBitmapIn2, mBitmapOut);
-        setupBars();
+        mBar2.setVisibility(View.INVISIBLE);
+        mText2.setVisibility(View.INVISIBLE);
 
-        mTest.runTest();
-        updateDisplay();
-        mBenchmarkResult.setText("Result: not run");
+        mBar3.setVisibility(View.INVISIBLE);
+        mText3.setVisibility(View.INVISIBLE);
+
+        mBar4.setVisibility(View.INVISIBLE);
+        mText4.setVisibility(View.INVISIBLE);
+
+        mBar5.setVisibility(View.INVISIBLE);
+        mText5.setVisibility(View.INVISIBLE);
     }
 
-    void setupTests() {
-        mTestSpinner.setAdapter(new ArrayAdapter<TestName>(
-            this, R.layout.spinner_layout, TestName.values()));
-    }
-
-    private AdapterView.OnItemSelectedListener mTestSpinnerListener =
-            new AdapterView.OnItemSelectedListener() {
-                public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
-                    changeTest(TestName.values()[pos]);
-                }
-
-                public void onNothingSelected(AdapterView parent) {
-
-                }
-            };
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
 
-        mBitmapIn = loadBitmap(R.drawable.img1600x1067);
-        mBitmapIn2 = loadBitmap(R.drawable.img1600x1067b);
-        mBitmapOut = Bitmap.createBitmap(mBitmapIn.getWidth(), mBitmapIn.getHeight(),
-                                         mBitmapIn.getConfig());
-
-        mSurfaceView = (SurfaceView) findViewById(R.id.surface);
-
-        mDisplayView = (ImageView) findViewById(R.id.display);
-        mDisplayView.setImageBitmap(mBitmapOut);
+        mDisplayView = (SizedTV) findViewById(R.id.display);
 
         mSpinner = (Spinner) findViewById(R.id.spinner1);
 
@@ -400,95 +496,97 @@
         mText3 = (TextView) findViewById(R.id.slider3Text);
         mText4 = (TextView) findViewById(R.id.slider4Text);
         mText5 = (TextView) findViewById(R.id.slider5Text);
-
-        mTestSpinner = (Spinner) findViewById(R.id.filterselection);
-        mTestSpinner.setOnItemSelectedListener(mTestSpinnerListener);
-
-        mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
-        mBenchmarkResult.setText("Result: not run");
-
-
-        mRS = RenderScript.create(this);
-        mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn);
-        mInPixelsAllocation2 = Allocation.createFromBitmap(mRS, mBitmapIn2);
-        mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut);
-
-
-        setupTests();
-        changeTest(TestName.LEVELS_VEC3_RELAXED);
     }
 
-
-    private Bitmap loadBitmap(int resource) {
-        final BitmapFactory.Options options = new BitmapFactory.Options();
-        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
-        return BitmapFactory.decodeResource(getResources(), resource, options);
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mProcessor.exit();
     }
 
-    // button hook
-    public void benchmark(View v) {
-        float t = getBenchmark();
-        //long javaTime = javaFilter();
-        //mBenchmarkResult.setText("RS: " + t + " ms  Java: " + javaTime + " ms");
-        mBenchmarkResult.setText("Result: " + t + " ms");
-        Log.v(TAG, "getBenchmark: Renderscript frame time core ms " + t);
-    }
-
-    public void benchmark_all(View v) {
-        // write result into a file
-        File externalStorage = Environment.getExternalStorageDirectory();
-        if (!externalStorage.canWrite()) {
-            Log.v(TAG, "sdcard is not writable");
-            return;
+    public void onBenchmarkFinish(boolean ok) {
+        if (ok) {
+            Intent intent = new Intent();
+            intent.putExtra("tests", mTestList);
+            intent.putExtra("results", mTestResults);
+            setResult(RESULT_OK, intent);
+        } else {
+            setResult(RESULT_CANCELED);
         }
-        File resultFile = new File(externalStorage, RESULT_FILE);
-        resultFile.setWritable(true, false);
-        try {
-            BufferedWriter rsWriter = new BufferedWriter(new FileWriter(resultFile));
-            Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath());
-            for (TestName tn: TestName.values()) {
-                changeTest(tn);
-                float t = getBenchmark();
-                String s = new String("" + tn.toString() + ", " + t);
-                rsWriter.write(s + "\n");
-                Log.v(TAG, "Test " + s + "ms\n");
+        finish();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Intent i = getIntent();
+        mTestList = i.getIntArrayExtra("tests");
+
+        mToggleIO = i.getBooleanExtra("enable io", false);
+        mToggleDVFS = i.getBooleanExtra("enable dvfs", true);
+        mToggleLong = i.getBooleanExtra("enable long", false);
+        mTogglePause = i.getBooleanExtra("enable pause", false);
+        mBitmapWidth = i.getIntExtra("resolution X", 0);
+        mBitmapHeight = i.getIntExtra("resolution Y", 0);
+
+        mTestResults = new float[mTestList.length];
+
+        hideBars();
+
+        Point size = new Point();
+        getWindowManager().getDefaultDisplay().getSize(size);
+
+        int mScreenWidth = size.x;
+        int mScreenHeight = size.y;
+
+        int tw = mBitmapWidth;
+        int th = mBitmapHeight;
+
+        if (tw > mScreenWidth || th > mScreenHeight) {
+            float s1 = (float)tw / (float)mScreenWidth;
+            float s2 = (float)th / (float)mScreenHeight;
+
+            if (s1 > s2) {
+                tw /= s1;
+                th /= s1;
+            } else {
+                tw /= s2;
+                th /= s2;
             }
-            rsWriter.close();
-        } catch (IOException e) {
-            Log.v(TAG, "Unable to write result file " + e.getMessage());
         }
-        changeTest(TestName.LEVELS_VEC3_RELAXED);
+
+        android.util.Log.v("rs", "TV sizes " + tw + ", " + th);
+
+        mDisplayView.mWidth = tw;
+        mDisplayView.mHeight = th;
+        //mDisplayView.setTransform(new android.graphics.Matrix());
+
+        mProcessor = new Processor(RenderScript.create(this), mDisplayView, true);
+        mDisplayView.setSurfaceTextureListener(this);
     }
 
-    // For benchmark test
-    public float getBenchmark() {
-        mDoingBenchmark = true;
+    protected void onDestroy() {
+        super.onDestroy();
+    }
 
-        mTest.setupBenchmark();
-        long result = 0;
 
-        //Log.v(TAG, "Warming");
-        long t = java.lang.System.currentTimeMillis() + 250;
-        do {
-            mTest.runTest();
-            mTest.finish();
-        } while (t > java.lang.System.currentTimeMillis());
+    @Override
+    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
+        mProcessor.setSurface(new Surface(surface));
+    }
 
-        //Log.v(TAG, "Benchmarking");
-        int ct = 0;
-        t = java.lang.System.currentTimeMillis();
-        do {
-            mTest.runTest();
-            mTest.finish();
-            ct++;
-        } while ((t+1000) > java.lang.System.currentTimeMillis());
-        t = java.lang.System.currentTimeMillis() - t;
-        float ft = (float)t;
-        ft /= ct;
+    @Override
+    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
+        mProcessor.setSurface(new Surface(surface));
+    }
 
-        mTest.exitBenchmark();
-        mDoingBenchmark = false;
+    @Override
+    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+        mProcessor.setSurface(null);
+        return true;
+    }
 
-        return ft;
+    @Override
+    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
     }
 }
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/LevelsV4.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/LevelsV4.java
index 741e480..ba08b54 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/LevelsV4.java
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/LevelsV4.java
@@ -109,7 +109,7 @@
     public boolean onBar4Setup(SeekBar b, TextView t) {
         b.setMax(128);
         b.setProgress(128);
-        t.setText("Out White");
+        t.setText("In White");
         return true;
     }
     public boolean onBar5Setup(SeekBar b, TextView t) {
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Mandelbrot.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Mandelbrot.java
index ca34848..26134b1 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/Mandelbrot.java
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/Mandelbrot.java
@@ -30,6 +30,11 @@
 
 public class Mandelbrot extends TestBase {
     private ScriptC_mandelbrot mScript;
+    private boolean mUseDouble = false;
+
+    public Mandelbrot(boolean useDouble) {
+        mUseDouble = useDouble;
+    }
 
     public boolean onBar1Setup(SeekBar b, TextView t) {
         t.setText("Iterations");
@@ -90,7 +95,11 @@
     }
 
     public void runTest() {
-        mScript.forEach_root(mOutPixelsAllocation);
+        if (mUseDouble) {
+            mScript.forEach_rootD(mOutPixelsAllocation);
+        } else {
+            mScript.forEach_root(mOutPixelsAllocation);
+        }
         mRS.finish();
     }
 
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/TestBase.java b/java/tests/ImageProcessing_jb/src/com/android/rs/image/TestBase.java
index 9ae366a..3de9809 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/TestBase.java
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/TestBase.java
@@ -45,8 +45,6 @@
     protected Allocation mInPixelsAllocation;
     protected Allocation mInPixelsAllocation2;
     protected Allocation mOutPixelsAllocation;
-    protected ScriptC_msg mMessageScript;
-
     protected ImageProcessingActivityJB act;
 
     private class MessageProcessor extends RenderScript.RSMessageHandler {
@@ -106,14 +104,14 @@
         return false;
     }
 
-    public final void createBaseTest(ImageProcessingActivityJB ipact, Bitmap b, Bitmap b2, Bitmap outb) {
+    public final void createBaseTest(ImageProcessingActivityJB ipact) {
         act = ipact;
-        mRS = ipact.mRS;
+        mRS = ipact.mProcessor.mRS;
         mRS.setMessageHandler(new MessageProcessor(act));
 
-        mInPixelsAllocation = ipact.mInPixelsAllocation;
-        mInPixelsAllocation2 = ipact.mInPixelsAllocation2;
-        mOutPixelsAllocation = ipact.mOutPixelsAllocation;
+        mInPixelsAllocation = ipact.mProcessor.mInPixelsAllocation;
+        mInPixelsAllocation2 = ipact.mProcessor.mInPixelsAllocation2;
+        mOutPixelsAllocation = ipact.mProcessor.mOutPixelsAllocation;
 
         createTest(act.getResources());
     }
@@ -128,7 +126,7 @@
 
     final public void runTestSendMessage() {
         runTest();
-        mMessageScript.invoke_sendMsg();
+        mRS.sendMessage(0, null);
     }
 
     public void finish() {
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/artistic1.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/artistic1.rs
new file mode 100644
index 0000000..8051f29
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/artistic1.rs
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+rs_allocation gBlur;
+
+static float gOverWm1;
+static float gOverHm1;
+static uchar gLutR[256];
+static uchar gLutG[256];
+static uchar gLutB[256];
+
+void setup() {
+    int w = rsAllocationGetDimX(gBlur);
+    int h = rsAllocationGetDimY(gBlur);
+    gOverWm1 = 1.f / w;
+    gOverHm1 = 1.f / h;
+
+    for (int x=0; x < 256; x++) {
+        gLutR[x] = x;//255-x;
+        gLutG[x] = x;//255-x;
+        gLutB[x] = x;//255-x;
+    }
+}
+
+uchar4 __attribute__((kernel)) process(uchar4 in, uint32_t x, uint32_t y) {
+    float2 xyDist;
+    xyDist.x = (x * gOverWm1 - 0.5f);
+    xyDist.y = (y * gOverHm1 - 0.5f);
+
+    // color
+    float4 v1 = rsUnpackColor8888(in);
+    float4 v2 = rsUnpackColor8888(rsGetElementAt_uchar4(gBlur, x, y));
+
+    float dist = dot(xyDist, xyDist) * 1.4f;
+    float pdist = native_powr(dist, 2.7f * 0.5f);
+    //float pdist = powr(dist, 2.7f * 0.5f);
+
+    pdist = clamp(pdist, 0.f, 1.f);
+    v1 = mix(v1, v2, dist * 2.f);
+    v1 *= 1.f - pdist;
+
+    // apply curve
+    uchar4 out = rsPackColorTo8888(v1);
+
+    out.r = gLutR[out.r];
+    out.g = gLutG[out.g];
+    out.b = gLutB[out.b];
+    return out;
+}
+
+
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/blend.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/blend.rs
index 9ec1246..3f2fdc5 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/blend.rs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/blend.rs
@@ -13,11 +13,14 @@
 // limitations under the License.
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 uchar alpha = 0x0;
 
-void setImageAlpha(uchar4 *v_out, uint32_t x, uint32_t y) {
-  v_out->rgba = convert_uchar4((convert_uint4(v_out->rgba) * alpha) >> (uint4)8);
-  v_out->a = alpha;
+uchar4 __attribute__((kernel)) setImageAlpha(uchar4 in, uint32_t x, uint32_t y) {
+    uchar4 out;
+    out.rgba = convert_uchar4((convert_uint4(in.rgba) * alpha) >> (uint4)8);
+    out.a = alpha;
+    return out;
 }
 
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/bwfilter.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/bwfilter.rs
index e706d44..e211620 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/bwfilter.rs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/bwfilter.rs
@@ -15,7 +15,7 @@
  */
 
 #include "ip.rsh"
-//#pragma rs_fp_relaxed
+#pragma rs_fp_relaxed
 
 static float sr = 0.f;
 static float sg = 0.f;
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/colorcube.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/colorcube.rs
new file mode 100644
index 0000000..a501ee6
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/colorcube.rs
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+
+static rs_allocation gCube;
+static int4 gDims;
+static int4 gCoordMul;
+
+
+void setCube(rs_allocation c) {
+    gCube = c;
+    gDims.x = rsAllocationGetDimX(gCube);
+    gDims.y = rsAllocationGetDimY(gCube);
+    gDims.z = rsAllocationGetDimZ(gCube);
+    gDims.w = 0;
+
+    float4 m = (float4)(1.f / 255.f) * convert_float4(gDims - 1);
+    gCoordMul = convert_int4(m * (float4)0x10000);
+}
+
+uchar4 __attribute__((kernel)) root(uchar4 in) {
+    int4 baseCoord = convert_int4(in) * gCoordMul;
+    int4 coord1 = baseCoord >> (int4)16;
+    int4 coord2 = min(coord1 + 1, gDims - 1);
+
+    int4 weight2 = baseCoord & 0xffff;
+    int4 weight1 = (int4)0x10000 - weight2;
+
+    uint4 v000 = convert_uint4(rsGetElementAt_uchar4(gCube, coord1.x, coord1.y, coord1.z));
+    uint4 v100 = convert_uint4(rsGetElementAt_uchar4(gCube, coord2.x, coord1.y, coord1.z));
+    uint4 v010 = convert_uint4(rsGetElementAt_uchar4(gCube, coord1.x, coord2.y, coord1.z));
+    uint4 v110 = convert_uint4(rsGetElementAt_uchar4(gCube, coord2.x, coord2.y, coord1.z));
+    uint4 v001 = convert_uint4(rsGetElementAt_uchar4(gCube, coord1.x, coord1.y, coord2.z));
+    uint4 v101 = convert_uint4(rsGetElementAt_uchar4(gCube, coord2.x, coord1.y, coord2.z));
+    uint4 v011 = convert_uint4(rsGetElementAt_uchar4(gCube, coord1.x, coord2.y, coord2.z));
+    uint4 v111 = convert_uint4(rsGetElementAt_uchar4(gCube, coord2.x, coord2.y, coord2.z));
+
+    uint4 yz00 = ((v000 * weight1.x) + (v100 * weight2.x)) >> (uint4)8;
+    uint4 yz10 = ((v010 * weight1.x) + (v110 * weight2.x)) >> (uint4)8;
+    uint4 yz01 = ((v001 * weight1.x) + (v101 * weight2.x)) >> (uint4)8;
+    uint4 yz11 = ((v011 * weight1.x) + (v111 * weight2.x)) >> (uint4)8;
+
+    uint4 z0 = ((yz00 * weight1.y) + (yz10 * weight2.y)) >> (uint4)16;
+    uint4 z1 = ((yz01 * weight1.y) + (yz11 * weight2.y)) >> (uint4)16;
+
+    uint4 v = ((z0 * weight1.z) + (z1 * weight2.z)) >> (uint4)16;
+    uint4 v2 = (v + 0x7f) >> (uint4)8;
+
+    uchar4 o = convert_uchar4(v2);
+    o.a = 0xff;
+    return o;
+}
+
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/colormatrix.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/colormatrix.fs
deleted file mode 100644
index 86fb248..0000000
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/colormatrix.fs
+++ /dev/null
@@ -1,35 +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.
- */
-
-#include "ip.rsh"
-
-static rs_matrix4x4 Mat;
-
-void init() {
-    rsMatrixLoadIdentity(&Mat);
-}
-
-void setMatrix(rs_matrix4x4 m) {
-    Mat = m;
-}
-
-uchar4 __attribute__((kernel)) root(uchar4 in) {
-    float4 f = convert_float4(in);
-    f = rsMatrixMultiply(&Mat, f);
-    f = clamp(f, 0.f, 255.f);
-    return convert_uchar4(f);
-}
-
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/colormatrix.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/colormatrix.rs
similarity index 97%
copy from java/tests/ImageProcessing/src/com/android/rs/image/colormatrix.fs
copy to java/tests/ImageProcessing_jb/src/com/android/rs/image/colormatrix.rs
index 86fb248..fa083ea 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/colormatrix.fs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/colormatrix.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 static rs_matrix4x4 Mat;
 
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/contrast.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/contrast.rs
index d3743d3..06c1802 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/contrast.rs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/contrast.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 static float brightM = 0.f;
 static float brightC = 0.f;
@@ -24,14 +25,10 @@
     brightC = 127.f - brightM * 127.f;
 }
 
-void contrast(const uchar4 *in, uchar4 *out)
-{
-#if 0
-    out->r = rsClamp((int)(brightM * in->r + brightC), 0, 255);
-    out->g = rsClamp((int)(brightM * in->g + brightC), 0, 255);
-    out->b = rsClamp((int)(brightM * in->b + brightC), 0, 255);
-#else
-    float3 v = convert_float3(in->rgb) * brightM + brightC;
-    out->rgb = convert_uchar3(clamp(v, 0.f, 255.f));
-#endif
+uchar4 __attribute__((kernel)) contrast(uchar4 in) {
+    float3 v = convert_float3(in.rgb) * brightM + brightC;
+    uchar4 o;
+    o.rgb = convert_uchar3(clamp(v, 0.f, 255.f));
+    o.a = 0xff;
+    return o;
 }
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve3x3.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve3x3.fs
deleted file mode 100644
index 177e86e..0000000
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve3x3.fs
+++ /dev/null
@@ -1,65 +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.
- */
-
-#include "ip.rsh"
-
-int32_t gWidth;
-int32_t gHeight;
-rs_allocation gIn;
-
-float gCoeffs[9];
-
-uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
-    uint32_t x1 = min((int32_t)x+1, gWidth-1);
-    uint32_t x2 = max((int32_t)x-1, 0);
-    uint32_t y1 = min((int32_t)y+1, gHeight-1);
-    uint32_t y2 = max((int32_t)y-1, 0);
-
-    float4 p00 = convert_float4(rsGetElementAt_uchar4(gIn, x1, y1));
-    float4 p01 = convert_float4(rsGetElementAt_uchar4(gIn, x, y1));
-    float4 p02 = convert_float4(rsGetElementAt_uchar4(gIn, x2, y1));
-    float4 p10 = convert_float4(rsGetElementAt_uchar4(gIn, x1, y));
-    float4 p11 = convert_float4(rsGetElementAt_uchar4(gIn, x, y));
-    float4 p12 = convert_float4(rsGetElementAt_uchar4(gIn, x2, y));
-    float4 p20 = convert_float4(rsGetElementAt_uchar4(gIn, x1, y2));
-    float4 p21 = convert_float4(rsGetElementAt_uchar4(gIn, x, y2));
-    float4 p22 = convert_float4(rsGetElementAt_uchar4(gIn, x2, y2));
-    p00 *= gCoeffs[0];
-    p01 *= gCoeffs[1];
-    p02 *= gCoeffs[2];
-    p10 *= gCoeffs[3];
-    p11 *= gCoeffs[4];
-    p12 *= gCoeffs[5];
-    p20 *= gCoeffs[6];
-    p21 *= gCoeffs[7];
-    p22 *= gCoeffs[8];
-
-    p00 += p01;
-    p02 += p10;
-    p11 += p12;
-    p20 += p21;
-
-    p22 += p00;
-    p02 += p11;
-
-    p20 += p22;
-    p20 += p02;
-
-    p20 = clamp(p20, 0.f, 255.f);
-    return convert_uchar4(p20);
-}
-
-
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve3x3.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve3x3.rs
new file mode 100644
index 0000000..1b1cf3f
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve3x3.rs
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+int32_t gWidth;
+int32_t gHeight;
+rs_allocation gIn;
+
+float gCoeffs[9];
+
+uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
+    uint32_t x1 = min((int32_t)x+1, gWidth-1);
+    uint32_t x2 = max((int32_t)x-1, 0);
+    uint32_t y1 = min((int32_t)y+1, gHeight-1);
+    uint32_t y2 = max((int32_t)y-1, 0);
+
+    float4 sum = convert_float4(rsGetElementAt_uchar4(gIn, x1, y1)) * gCoeffs[0];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x, y1)) * gCoeffs[1];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x2, y1)) * gCoeffs[2];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x1, y)) * gCoeffs[3];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x, y)) * gCoeffs[4];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x2, y)) * gCoeffs[5];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x1, y2)) * gCoeffs[6];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x, y2)) * gCoeffs[7];
+    sum += convert_float4(rsGetElementAt_uchar4(gIn, x2, y2)) * gCoeffs[8];
+
+    sum = clamp(sum, 0.f, 255.f);
+    return convert_uchar4(sum);
+}
+
+
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve5x5.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve5x5.fs
deleted file mode 100644
index 922a593..0000000
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve5x5.fs
+++ /dev/null
@@ -1,72 +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.
- */
-
-#include "ip.rsh"
-
-int32_t gWidth;
-int32_t gHeight;
-rs_allocation gIn;
-
-float gCoeffs[25];
-
-uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
-    uint32_t x0 = max((int32_t)x-2, 0);
-    uint32_t x1 = max((int32_t)x-1, 0);
-    uint32_t x2 = x;
-    uint32_t x3 = min((int32_t)x+1, gWidth-1);
-    uint32_t x4 = min((int32_t)x+2, gWidth-1);
-
-    uint32_t y0 = max((int32_t)y-2, 0);
-    uint32_t y1 = max((int32_t)y-1, 0);
-    uint32_t y2 = y;
-    uint32_t y3 = min((int32_t)y+1, gHeight-1);
-    uint32_t y4 = min((int32_t)y+2, gHeight-1);
-
-    float4 p0 = convert_float4(rsGetElementAt_uchar4(gIn, x0, y0)) * gCoeffs[0]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x1, y0)) * gCoeffs[1]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x2, y0)) * gCoeffs[2]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x3, y0)) * gCoeffs[3]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x4, y0)) * gCoeffs[4];
-
-    float4 p1 = convert_float4(rsGetElementAt_uchar4(gIn, x0, y1)) * gCoeffs[5]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x1, y1)) * gCoeffs[6]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x2, y1)) * gCoeffs[7]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x3, y1)) * gCoeffs[8]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x4, y1)) * gCoeffs[9];
-
-    float4 p2 = convert_float4(rsGetElementAt_uchar4(gIn, x0, y2)) * gCoeffs[10]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x1, y2)) * gCoeffs[11]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x2, y2)) * gCoeffs[12]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x3, y2)) * gCoeffs[13]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x4, y2)) * gCoeffs[14];
-
-    float4 p3 = convert_float4(rsGetElementAt_uchar4(gIn, x0, y3)) * gCoeffs[15]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x1, y3)) * gCoeffs[16]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x2, y3)) * gCoeffs[17]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x3, y3)) * gCoeffs[18]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x4, y3)) * gCoeffs[19];
-
-    float4 p4 = convert_float4(rsGetElementAt_uchar4(gIn, x0, y4)) * gCoeffs[20]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x1, y4)) * gCoeffs[21]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x2, y4)) * gCoeffs[22]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x3, y4)) * gCoeffs[23]
-              + convert_float4(rsGetElementAt_uchar4(gIn, x4, y4)) * gCoeffs[24];
-
-    p0 = clamp(p0 + p1 + p2 + p3 + p4, 0.f, 255.f);
-    return convert_uchar4(p0);
-}
-
-
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve5x5.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve5x5.rs
new file mode 100644
index 0000000..ed8461b
--- /dev/null
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/convolve5x5.rs
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+int32_t gWidth;
+int32_t gHeight;
+rs_allocation gIn;
+
+float gCoeffs[25];
+
+uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
+    uint32_t x0 = max((int32_t)x-2, 0);
+    uint32_t x1 = max((int32_t)x-1, 0);
+    uint32_t x2 = x;
+    uint32_t x3 = min((int32_t)x+1, gWidth-1);
+    uint32_t x4 = min((int32_t)x+2, gWidth-1);
+
+    uint32_t y0 = max((int32_t)y-2, 0);
+    uint32_t y1 = max((int32_t)y-1, 0);
+    uint32_t y2 = y;
+    uint32_t y3 = min((int32_t)y+1, gHeight-1);
+    uint32_t y4 = min((int32_t)y+2, gHeight-1);
+
+    float4 sum = convert_float4(rsGetElementAt_uchar4(gIn, x0, y0)) * gCoeffs[0]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x1, y0)) * gCoeffs[1]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x2, y0)) * gCoeffs[2]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x3, y0)) * gCoeffs[3]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y0)) * gCoeffs[4]
+
+               + convert_float4(rsGetElementAt_uchar4(gIn, x0, y1)) * gCoeffs[5]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x1, y1)) * gCoeffs[6]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x2, y1)) * gCoeffs[7]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x3, y1)) * gCoeffs[8]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y1)) * gCoeffs[9]
+
+               + convert_float4(rsGetElementAt_uchar4(gIn, x0, y2)) * gCoeffs[10]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x1, y2)) * gCoeffs[11]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x2, y2)) * gCoeffs[12]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x3, y2)) * gCoeffs[13]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y2)) * gCoeffs[14]
+
+               + convert_float4(rsGetElementAt_uchar4(gIn, x0, y3)) * gCoeffs[15]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x1, y3)) * gCoeffs[16]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x2, y3)) * gCoeffs[17]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x3, y3)) * gCoeffs[18]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y3)) * gCoeffs[19]
+
+               + convert_float4(rsGetElementAt_uchar4(gIn, x0, y4)) * gCoeffs[20]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x1, y4)) * gCoeffs[21]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x2, y4)) * gCoeffs[22]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x3, y4)) * gCoeffs[23]
+               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y4)) * gCoeffs[24];
+
+    return convert_uchar4(clamp(sum, 0.f, 255.f));
+}
+
+
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/copy.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/copy.fs
deleted file mode 100644
index 6595874..0000000
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/copy.fs
+++ /dev/null
@@ -1,23 +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.
- */
-
-#include "ip.rsh"
-
-uchar4 __attribute__((kernel)) root(uchar4 v_in) {
-    return v_in;
-}
-
-
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/copy.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/copy.rs
similarity index 96%
copy from java/tests/ImageProcessing/src/com/android/rs/image/copy.fs
copy to java/tests/ImageProcessing_jb/src/com/android/rs/image/copy.rs
index 6595874..b69f2df 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/copy.fs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/copy.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 uchar4 __attribute__((kernel)) root(uchar4 v_in) {
     return v_in;
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/exposure.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/exposure.rs
index 0f05cb9..b937f70 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/exposure.rs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/exposure.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 static float bright = 0.f;
 
@@ -22,10 +23,12 @@
     bright = 255.f / (255.f - v);
 }
 
-void exposure(const uchar4 *in, uchar4 *out)
+uchar4 __attribute__((kernel)) exposure(uchar4 in)
 {
-    out->r = rsClamp((int)(bright * in->r), 0, 255);
-    out->g = rsClamp((int)(bright * in->g), 0, 255);
-    out->b = rsClamp((int)(bright * in->b), 0, 255);
+    uchar4 out = 0;
+    out.r = rsClamp((int)(bright * in.r), 0, 255);
+    out.g = rsClamp((int)(bright * in.g), 0, 255);
+    out.b = rsClamp((int)(bright * in.b), 0, 255);
+    return out;
 }
 
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye.rsh b/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye.rsh
index 2eacb7d..fb95005 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye.rsh
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye.rsh
@@ -33,7 +33,7 @@
         axis_scale.y = (float)dim_y / (float)dim_x;
     else
         axis_scale.x = (float)dim_x / (float)dim_y;
-    
+
     const float bound2 = 0.25f * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
     const float bound = sqrt(bound2);
     const float radius = 1.15f * bound;
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_relaxed.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_relaxed.rs
similarity index 96%
rename from java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_relaxed.fs
rename to java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_relaxed.rs
index ed69ff4..d83a218 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_relaxed.fs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_approx_relaxed.rs
@@ -16,5 +16,6 @@
 
 #include "ip.rsh"
 
+#pragma rs_fp_relaxed
 #include "fisheye_approx.rsh"
 
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_relaxed.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_relaxed.fs
deleted file mode 100644
index f986b5d..0000000
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_relaxed.fs
+++ /dev/null
@@ -1,20 +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.
- */
-
-#include "ip.rsh"
-
-#include "fisheye.rsh"
-
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_relaxed.rs
similarity index 96%
copy from java/tests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.fs
copy to java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_relaxed.rs
index f986b5d..31646c4 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.fs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/fisheye_relaxed.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 #include "fisheye.rsh"
 
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/grain.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/grain.rs
similarity index 100%
rename from java/tests/ImageProcessing_jb/src/com/android/rs/image/grain.fs
rename to java/tests/ImageProcessing_jb/src/com/android/rs/image/grain.rs
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/greyscale.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/greyscale.rs
similarity index 100%
rename from java/tests/ImageProcessing_jb/src/com/android/rs/image/greyscale.fs
rename to java/tests/ImageProcessing_jb/src/com/android/rs/image/greyscale.rs
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/levels.rsh b/java/tests/ImageProcessing_jb/src/com/android/rs/image/levels.rsh
index e289906..b864493 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/levels.rsh
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/levels.rsh
@@ -21,7 +21,7 @@
 float overInWMinInB;
 rs_matrix3x3 colorMat;
 
-uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) root(uchar4 in) {
     uchar4 out;
     float3 pixel = convert_float4(in).rgb;
     pixel = rsMatrixMultiply(&colorMat, pixel);
@@ -34,7 +34,7 @@
     return out;
 }
 
-uchar4 __attribute__((kernel)) root4(uchar4 in, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) root4(uchar4 in) {
     float4 pixel = convert_float4(in);
     pixel.rgb = rsMatrixMultiply(&colorMat, pixel.rgb);
     pixel = clamp(pixel, 0.f, 255.f);
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/levels_relaxed.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/levels_relaxed.fs
deleted file mode 100644
index 28596ba..0000000
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/levels_relaxed.fs
+++ /dev/null
@@ -1,20 +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.
- */
-
-#include "ip.rsh"
-
-#include "levels.rsh"
-
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/levels_relaxed.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/levels_relaxed.rs
similarity index 96%
copy from java/tests/ImageProcessing/src/com/android/rs/image/levels_relaxed.fs
copy to java/tests/ImageProcessing_jb/src/com/android/rs/image/levels_relaxed.rs
index 28596ba..c0bc4b7 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/levels_relaxed.fs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/levels_relaxed.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 #include "levels.rsh"
 
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/mandelbrot.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/mandelbrot.rs
index de0bd00..5429acd 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/mandelbrot.rs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/mandelbrot.rs
@@ -53,3 +53,36 @@
                       (0xff * ((iter - (mi3 * 2)) / mi3)), 0xff};
   }
 }
+
+uchar4 __attribute__((kernel)) rootD(uint32_t x, uint32_t y) {
+  double2 p;
+  p.x = lowerBoundX + ((float)x / gDimX) * scaleFactor;
+  p.y = lowerBoundY + ((float)y / gDimY) * scaleFactor;
+
+  double2 t = 0;
+  double2 t2 = t * t;
+  int iter = 0;
+  while((t2.x + t2.y < 4.f) && (iter < gMaxIteration)) {
+    double xtemp = t2.x - t2.y + p.x;
+    t.y = 2 * t.x * t.y + p.y;
+    t.x = xtemp;
+    iter++;
+    t2 = t * t;
+  }
+
+  if(iter >= gMaxIteration) {
+    // write a non-transparent black pixel
+    return (uchar4){0, 0, 0, 0xff};
+  } else {
+    double mi3 = gMaxIteration / 3.f;
+    if (iter <= (gMaxIteration / 3))
+      return (uchar4){0xff * (iter / mi3), 0, 0, 0xff};
+    else if (iter <= (((gMaxIteration / 3) * 2)))
+      return (uchar4){0xff - (0xff * ((iter - mi3) / mi3)),
+                      (0xff * ((iter - mi3) / mi3)), 0, 0xff};
+    else
+      return (uchar4){0, 0xff - (0xff * ((iter - (mi3 * 2)) / mi3)),
+                      (0xff * ((iter - (mi3 * 2)) / mi3)), 0xff};
+  }
+}
+
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/msg.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/msg.rs
deleted file mode 100644
index 645eb98..0000000
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/msg.rs
+++ /dev/null
@@ -1,23 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(com.android.rs.imagejb)
-
-void sendMsg() {
-    rsSendToClientBlocking(0);
-}
-
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/shadows.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/shadows.rs
index f6c149d..2f06104 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/shadows.rs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/shadows.rs
@@ -15,20 +15,20 @@
  */
 
 #include "ip.rsh"
-//#pragma rs_fp_relaxed
+#pragma rs_fp_relaxed
 
-static double shadowFilterMap[] = {
-    -0.00591,  0.0001,
-     1.16488,  0.01668,
-    -0.18027, -0.06791,
-    -0.12625,  0.09001,
-     0.15065, -0.03897
+static float shadowFilterMap[] = {
+    -0.00591f,  0.0001f,
+     1.16488f,  0.01668f,
+    -0.18027f, -0.06791f,
+    -0.12625f,  0.09001f,
+     0.15065f, -0.03897f
 };
 
-static double poly[] = {
-    0., 0.,
-    0., 0.,
-    0.
+static float poly[] = {
+    0.f, 0.f,
+    0.f, 0.f,
+    0.f
 };
 
 static const int ABITS = 4;
@@ -36,10 +36,10 @@
 static const int k1=255 << ABITS;
 static const int k2=HSCALE << ABITS;
 
-static double fastevalPoly(double *poly,int n, double x){
+static float fastevalPoly(float *poly,int n, float x){
 
-    double f =x;
-    double sum = poly[0]+poly[1]*f;
+    float f =x;
+    float sum = poly[0]+poly[1]*f;
     int i;
     for (i = 2; i < n; i++) {
         f*=x;
@@ -177,16 +177,15 @@
 }
 
 void prepareShadows(float scale) {
-    double s = (scale>=0)?scale:scale/5;
+    float s = (scale>=0) ? scale : scale / 5.f;
     for (int i = 0; i < 5; i++) {
         poly[i] = fastevalPoly(shadowFilterMap+i*2,2 , s);
     }
 }
 
-void shadowsKernel(const uchar4 *in, uchar4 *out) {
-    ushort3 hsv = rgb2hsv(*in);
-    double v = (fastevalPoly(poly,5,hsv.x/4080.)*4080);
-    if (v>4080) v = 4080;
-    hsv.x = (unsigned short) ((v>0)?v:0);
-    *out = hsv2rgb(hsv);
+uchar4 __attribute__((kernel)) shadowsKernel(uchar4 in) {
+    ushort3 hsv = rgb2hsv(in);
+    float v = (fastevalPoly(poly, 5, hsv.x * (1.f / 4080.f)) * 4080.f);
+    hsv.x = (unsigned short) clamp(v, 0.f, 4080.f);
+    return hsv2rgb(hsv);
 }
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/threshold.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/threshold.fs
deleted file mode 100644
index 0b2c2e8..0000000
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/threshold.fs
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2013 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 "ip.rsh"
-
-
-int height;
-int width;
-static int radius;
-
-rs_allocation InPixel;
-rs_allocation ScratchPixel1;
-rs_allocation ScratchPixel2;
-
-const int MAX_RADIUS = 25;
-
-// Store our coefficients here
-static float gaussian[MAX_RADIUS * 2 + 1];
-
-void setRadius(int rad) {
-    radius = rad;
-    // Compute gaussian weights for the blur
-    // e is the euler's number
-    float e = 2.718281828459045f;
-    float pi = 3.1415926535897932f;
-    // g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 )
-    // x is of the form [-radius .. 0 .. radius]
-    // and sigma varies with radius.
-    // Based on some experimental radius values and sigma's
-    // we approximately fit sigma = f(radius) as
-    // sigma = radius * 0.4  + 0.6
-    // The larger the radius gets, the more our gaussian blur
-    // will resemble a box blur since with large sigma
-    // the gaussian curve begins to lose its shape
-    float sigma = 0.4f * (float)radius + 0.6f;
-
-    // Now compute the coefficints
-    // We will store some redundant values to save some math during
-    // the blur calculations
-    // precompute some values
-    float coeff1 = 1.0f / (sqrt( 2.0f * pi ) * sigma);
-    float coeff2 = - 1.0f / (2.0f * sigma * sigma);
-
-    float normalizeFactor = 0.0f;
-    float floatR = 0.0f;
-    for (int r = -radius; r <= radius; r ++) {
-        floatR = (float)r;
-        gaussian[r + radius] = coeff1 * pow(e, floatR * floatR * coeff2);
-        normalizeFactor += gaussian[r + radius];
-    }
-
-    //Now we need to normalize the weights because all our coefficients need to add up to one
-    normalizeFactor = 1.0f / normalizeFactor;
-    for (int r = -radius; r <= radius; r ++) {
-        floatR = (float)r;
-        gaussian[r + radius] *= normalizeFactor;
-    }
-}
-
-float4 __attribute__((kernel)) copyIn(uchar4 in) {
-    return convert_float4(in);
-}
-
-uchar4 __attribute__((kernel)) vert(uint32_t x, uint32_t y) {
-    float3 blurredPixel = 0;
-    int gi = 0;
-    uchar4 out;
-    if ((y > radius) && (y < (height - radius))) {
-        for (int r = -radius; r <= radius; r ++) {
-            float4 i = rsGetElementAt_float4(ScratchPixel2, x, y + r);
-            blurredPixel += i.xyz * gaussian[gi++];
-        }
-    } else {
-        for (int r = -radius; r <= radius; r ++) {
-            int validH = rsClamp((int)y + r, (int)0, (int)(height - 1));
-            float4 i = rsGetElementAt_float4(ScratchPixel2, x, validH);
-            blurredPixel += i.xyz * gaussian[gi++];
-        }
-    }
-
-    out.xyz = convert_uchar3(clamp(blurredPixel, 0.f, 255.f));
-    out.w = 0xff;
-    return out;
-}
-
-float4 __attribute__((kernel)) horz(uint32_t x, uint32_t y) {
-    float4 blurredPixel = 0;
-    int gi = 0;
-    if ((x > radius) && (x < (width - radius))) {
-        for (int r = -radius; r <= radius; r ++) {
-            float4 i = rsGetElementAt_float4(ScratchPixel1, x + r, y);
-            blurredPixel += i * gaussian[gi++];
-        }
-    } else {
-        for (int r = -radius; r <= radius; r ++) {
-            // Stepping left and right away from the pixel
-            int validX = rsClamp((int)x + r, (int)0, (int)(width - 1));
-            float4 i = rsGetElementAt_float4(ScratchPixel1, validX, y);
-            blurredPixel += i * gaussian[gi++];
-        }
-    }
-
-    return blurredPixel;
-}
-
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/threshold.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/threshold.rs
similarity index 98%
copy from java/tests/ImageProcessing/src/com/android/rs/image/threshold.fs
copy to java/tests/ImageProcessing_jb/src/com/android/rs/image/threshold.rs
index 0b2c2e8..d30a87b 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/threshold.fs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/threshold.rs
@@ -15,7 +15,7 @@
  */
 
 #include "ip.rsh"
-
+#pragma rs_fp_relaxed
 
 int height;
 int width;
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/vibrance.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/vibrance.rs
index 8db113c..7fa295e 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/vibrance.rs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/vibrance.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 float vibrance = 0.f;
 
@@ -22,49 +23,36 @@
 static const float Gf = 0.587f;
 static const float Bf = 0.114f;
 
-static float S  = 0.f;
-static float MS = 0.f;
-static float Rt = 0.f;
-static float Gt = 0.f;
-static float Bt = 0.f;
 static float Vib = 0.f;
 
-void vibranceKernel(const uchar4 *in, uchar4 *out) {
+uchar4 __attribute__((kernel)) vibranceKernel(uchar4 in) {
+    int r = in.r;
+    int g = in.g;
+    int b = in.b;
+    float red = (r-max(g, b)) * (1.f / 256.f);
+    float S = (float)(Vib/(1+native_exp(-red*3)))+1;
+    float MS = 1.0f - S;
+    float Rt = Rf * MS;
+    float Gt = Gf * MS;
+    float Bt = Bf * MS;
+    int t = (r + g) >> 1;
 
-    float R, G, B;
-
-    int r = in->r;
-    int g = in->g;
-    int b = in->b;
-    float red = (r-max(g, b))/256.f;
-    float sx = (float)(Vib/(1+exp(-red*3)));
-    S = sx+1;
-    MS = 1.0f - S;
-    Rt = Rf * MS;
-    Gt = Gf * MS;
-    Bt = Bf * MS;
-    int t = (r + g) / 2;
-    R = r;
-    G = g;
-    B = b;
+    float R = r;
+    float G = g;
+    float B = b;
 
     float Rc = R * (Rt + S) + G * Gt + B * Bt;
     float Gc = R * Rt + G * (Gt + S) + B * Bt;
     float Bc = R * Rt + G * Gt + B * (Bt + S);
 
-    out->r = rsClamp(Rc, 0, 255);
-    out->g = rsClamp(Gc, 0, 255);
-    out->b = rsClamp(Bc, 0, 255);
-
+    uchar4 o;
+    o.r = rsClamp(Rc, 0, 255);
+    o.g = rsClamp(Gc, 0, 255);
+    o.b = rsClamp(Bc, 0, 255);
+    o.a = 0xff;
+    return o;
 }
 
 void prepareVibrance() {
-
     Vib = vibrance/100.f;
-    S  = Vib + 1;
-    MS = 1.0f - S;
-    Rt = Rf * MS;
-    Gt = Gf * MS;
-    Bt = Bf * MS;
-
 }
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_approx.rsh b/java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_approx.rsh
index 0eacdc8..5668621 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_approx.rsh
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_approx.rsh
@@ -50,7 +50,7 @@
     const float2 inCoord = {(float)x, (float)y};
     const float2 coord = mad(inCoord, inv_dimensions, neg_center);
     const float sloped_dist_ratio = fast_length(axis_scale * coord)  * sloped_inv_max_dist;
-    const float lumen = opp_shade + shade * half_recip(1.f + sloped_neg_range * exp(sloped_dist_ratio));
+    const float lumen = opp_shade + shade * half_recip(1.f + sloped_neg_range * native_exp(sloped_dist_ratio));
     float4 fout;
     fout.rgb = fin.rgb * lumen;
     fout.w = fin.w;
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_relaxed.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_relaxed.rs
similarity index 100%
rename from java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_relaxed.fs
rename to java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_approx_relaxed.rs
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_relaxed.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_relaxed.fs
deleted file mode 100644
index 8202c5c..0000000
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_relaxed.fs
+++ /dev/null
@@ -1,20 +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.
- */
-
-#include "ip.rsh"
-
-#include "vignette.rsh"
-
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.fs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_relaxed.rs
similarity index 96%
copy from java/tests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.fs
copy to java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_relaxed.rs
index 8202c5c..262d516 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.fs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/vignette_relaxed.rs
@@ -15,6 +15,7 @@
  */
 
 #include "ip.rsh"
+#pragma rs_fp_relaxed
 
 #include "vignette.rsh"
 
diff --git a/java/tests/ImageProcessing_jb/src/com/android/rs/image/wbalance.rs b/java/tests/ImageProcessing_jb/src/com/android/rs/image/wbalance.rs
index 6650671..c803640 100644
--- a/java/tests/ImageProcessing_jb/src/com/android/rs/image/wbalance.rs
+++ b/java/tests/ImageProcessing_jb/src/com/android/rs/image/wbalance.rs
@@ -15,7 +15,7 @@
  */
 
 #include "ip.rsh"
-//#pragma rs_fp_relaxed
+#pragma rs_fp_relaxed
 
 static int histR[256] = {0}, histG[256] = {0}, histB[256] = {0};
 
@@ -23,9 +23,7 @@
 uint32_t histogramHeight;
 uint32_t histogramWidth;
 
-static float scaleR;
-static float scaleG;
-static float scaleB;
+static float3 scale;
 
 static uchar4 estimateWhite() {
 
@@ -115,28 +113,19 @@
     int maximum = max(estimation.r, max(estimation.g, estimation.b));
     float avg = (minimum + maximum) / 2.f;
 
-    scaleR =  avg/estimation.r;
-    scaleG =  avg/estimation.g;
-    scaleB =  avg/estimation.b;
-
+    scale.r =  avg/estimation.r;
+    scale.g =  avg/estimation.g;
+    scale.b =  avg/estimation.b;
 }
 
-static unsigned char contrastClamp(int c)
-{
-    int N = 255;
-    c &= ~(c >> 31);
-    c -= N;
-    c &= (c >> 31);
-    c += N;
-    return  (unsigned char) c;
+uchar4 __attribute__((kernel)) whiteBalanceKernel(uchar4 in) {
+    float3 t = convert_float3(in.rgb);
+    t *= scale;
+    t = min(t, 255.f);
+
+    uchar4 out;
+    out.rgb = convert_uchar3(t);
+    out.a = 255;
+    return out;
 }
 
-void whiteBalanceKernel(const uchar4 *in, uchar4 *out) {
-    float Rc =  in->r*scaleR;
-    float Gc =  in->g*scaleG;
-    float Bc =  in->b*scaleB;
-
-    out->r = contrastClamp(Rc);
-    out->g = contrastClamp(Gc);
-    out->b = contrastClamp(Bc);
-}
diff --git a/java/tests/LivePreview/src/com/android/rs/livepreview/RsYuv.java b/java/tests/LivePreview/src/com/android/rs/livepreview/RsYuv.java
index 12d3185..15cd72a 100644
--- a/java/tests/LivePreview/src/com/android/rs/livepreview/RsYuv.java
+++ b/java/tests/LivePreview/src/com/android/rs/livepreview/RsYuv.java
@@ -27,6 +27,7 @@
 import android.renderscript.RenderScript;
 import android.util.Log;
 import android.view.TextureView;
+import android.view.Surface;
 import android.view.View;
 
 import android.content.res.Resources;
@@ -44,7 +45,7 @@
     private ScriptC_yuv mScript;
     private ScriptIntrinsicYuvToRGB mYuv;
     private boolean mHaveSurface;
-    private SurfaceTexture mSurface;
+    private Surface mSurface;
     private ScriptGroup mGroup;
 
     RsYuv(RenderScript rs) {
@@ -55,7 +56,7 @@
 
     void setupSurface() {
         if (mAllocationOut != null) {
-            mAllocationOut.setSurfaceTexture(mSurface);
+            mAllocationOut.setSurface(mSurface);
         }
         if (mSurface != null) {
             mHaveSurface = true;
@@ -116,7 +117,7 @@
 
             //mYuv.forEach(mAllocationOut);
             //mScript.forEach_root(mAllocationOut, mAllocationOut);
-            mAllocationOut.ioSendOutput();
+            mAllocationOut.ioSend();
         }
     }
 
@@ -125,21 +126,21 @@
     @Override
     public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
         android.util.Log.v("cpa", "onSurfaceTextureAvailable " + surface);
-        mSurface = surface;
+        mSurface = new Surface(surface);
         setupSurface();
     }
 
     @Override
     public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
         android.util.Log.v("cpa", "onSurfaceTextureSizeChanged " + surface);
-        mSurface = surface;
+        mSurface = new Surface(surface);
         setupSurface();
     }
 
     @Override
     public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
         android.util.Log.v("cpa", "onSurfaceTextureDestroyed " + surface);
-        mSurface = surface;
+        mSurface = null;
         setupSurface();
         return true;
     }
diff --git a/java/tests/RSTest_CompatLib/src/com/android/rs/test/RSTestCore.java b/java/tests/RSTest_CompatLib/src/com/android/rs/test/RSTestCore.java
index 2ee2a33..462e4f4 100644
--- a/java/tests/RSTest_CompatLib/src/com/android/rs/test/RSTestCore.java
+++ b/java/tests/RSTest_CompatLib/src/com/android/rs/test/RSTestCore.java
@@ -57,6 +57,7 @@
 
         unitTests = new ArrayList<UnitTest>();
 
+        unitTests.add(new UT_apitest(this, mRes, mCtx));
         unitTests.add(new UT_primitives(this, mRes, mCtx));
         unitTests.add(new UT_instance(this, mRes, mCtx));
         unitTests.add(new UT_constant(this, mRes, mCtx));
diff --git a/java/tests/RSTest_CompatLib/src/com/android/rs/test/UT_apitest.java b/java/tests/RSTest_CompatLib/src/com/android/rs/test/UT_apitest.java
new file mode 100644
index 0000000..1b2cd05
--- /dev/null
+++ b/java/tests/RSTest_CompatLib/src/com/android/rs/test/UT_apitest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+package com.android.rs.test_compat;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_apitest extends UnitTest {
+    private Resources mRes;
+
+    protected UT_apitest(RSTestCore rstc, Resources res, Context ctx) {
+        super(rstc, "API Test", ctx);
+        mRes = res;
+    }
+
+    public void run() {
+        RenderScript pRS = RenderScript.create(mCtx);
+        ScriptC_apitest s = new ScriptC_apitest(pRS);
+        pRS.setMessageHandler(mRsMessage);
+        Element elem = Element.I8(pRS);
+        Type.Builder typeBuilder = new Type.Builder(pRS, elem);
+
+        int x = 5;
+        int y = 7;
+        int z = 0;  // Don't actually setZ()
+        s.set_x(x);
+        s.set_y(y);
+        s.set_z(z);
+        typeBuilder.setX(x).setY(y);
+        Type type = typeBuilder.create();
+        Allocation alloc = Allocation.createTyped(pRS, type);
+        Allocation allocDst = Allocation.createTyped(pRS, type);
+        Sampler sampler = Sampler.CLAMP_NEAREST(pRS);
+        s.set_elemNonNull(elem);
+        s.set_typeNonNull(type);
+        s.set_allocNonNull(alloc);
+        s.set_allocDst(allocDst);
+        s.set_samplerNonNull(sampler);
+        s.set_scriptNonNull(s);
+        s.bind_allocPtr(alloc);
+
+        s.invoke_api_test();
+        pRS.finish();
+        waitForMessage();
+        pRS.destroy();
+    }
+}
diff --git a/java/tests/RSTest_CompatLib/src/com/android/rs/test/apitest.rs b/java/tests/RSTest_CompatLib/src/com/android/rs/test/apitest.rs
new file mode 100644
index 0000000..0068283
--- /dev/null
+++ b/java/tests/RSTest_CompatLib/src/com/android/rs/test/apitest.rs
@@ -0,0 +1,1203 @@
+#include "shared.rsh"
+
+uint32_t x;
+uint32_t y;
+uint32_t z;
+
+rs_element elemNull;
+rs_element elemNonNull;
+rs_type typeNull;
+rs_type typeNonNull;
+rs_allocation allocNull;
+rs_allocation allocNonNull;
+rs_sampler samplerNull;
+rs_sampler samplerNonNull;
+rs_script scriptNull;
+rs_script scriptNonNull;
+
+char *allocPtr;
+rs_allocation allocDst;
+
+volatile bool b;
+volatile char c;
+volatile char2 c2;
+volatile char3 c3;
+volatile char4 c4;
+volatile uchar uc;
+volatile uchar2 uc2;
+volatile uchar3 uc3;
+volatile uchar4 uc4;
+volatile short s;
+volatile short2 s2;
+volatile short3 s3;
+volatile short4 s4;
+volatile ushort us;
+volatile ushort2 us2;
+volatile ushort3 us3;
+volatile ushort4 us4;
+volatile int i;
+volatile int2 i2;
+volatile int3 i3;
+volatile int4 i4;
+volatile uint ui;
+volatile uint2 ui2;
+volatile uint3 ui3;
+volatile uint4 ui4;
+volatile long l;
+volatile long2 l2;
+volatile long3 l3;
+volatile long4 l4;
+volatile ulong ul;
+volatile ulong2 ul2;
+volatile ulong3 ul3;
+volatile ulong4 ul4;
+volatile float f;
+volatile float2 f2;
+volatile float3 f3;
+volatile float4 f4;
+volatile double d;
+volatile double2 d2;
+volatile double3 d3;
+volatile double4 d4;
+
+rs_allocation aChar;
+rs_allocation aChar2;
+rs_allocation aChar3;
+rs_allocation aChar4;
+rs_allocation aUChar;
+rs_allocation aUChar2;
+rs_allocation aUChar3;
+rs_allocation aUChar4;
+rs_allocation aShort;
+rs_allocation aShort2;
+rs_allocation aShort3;
+rs_allocation aShort4;
+rs_allocation aUShort;
+rs_allocation aUShort2;
+rs_allocation aUShort3;
+rs_allocation aUShort4;
+rs_allocation aInt;
+rs_allocation aInt2;
+rs_allocation aInt3;
+rs_allocation aInt4;
+rs_allocation aUInt;
+rs_allocation aUInt2;
+rs_allocation aUInt3;
+rs_allocation aUInt4;
+rs_allocation aLong;
+rs_allocation aLong2;
+rs_allocation aLong3;
+rs_allocation aLong4;
+rs_allocation aULong;
+rs_allocation aULong2;
+rs_allocation aULong3;
+rs_allocation aULong4;
+rs_allocation aFloat;
+rs_allocation aFloat2;
+rs_allocation aFloat3;
+rs_allocation aFloat4;
+rs_allocation aDouble;
+rs_allocation aDouble2;
+rs_allocation aDouble3;
+rs_allocation aDouble4;
+
+// This function just checks that all of the called functions are
+// able to be linked. It is not intended to be executed!
+void check_api_presence() {
+    /********************************
+     * DO NOT EXECUTE THIS FUNCTION *
+     ********************************/
+    rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+
+    // rs_allocation.rsh
+    c = rsGetElementAt_char(aChar, 0);
+    rsSetElementAt_char(aChar, c, 0);
+    c = rsGetElementAt_char(aChar, 0, 0);
+    rsSetElementAt_char(aChar, c, 0, 0);
+    c = rsGetElementAt_char(aChar, 0, 0, 0);
+    rsSetElementAt_char(aChar, c, 0, 0, 0);
+    c2 = rsGetElementAt_char2(aChar2, 0);
+    rsSetElementAt_char2(aChar2, c2, 0);
+    c2 = rsGetElementAt_char2(aChar2, 0, 0);
+    rsSetElementAt_char2(aChar2, c2, 0, 0);
+    c2 = rsGetElementAt_char2(aChar2, 0, 0, 0);
+    rsSetElementAt_char2(aChar2, c2, 0, 0, 0);
+    c3 = rsGetElementAt_char3(aChar3, 0);
+    rsSetElementAt_char3(aChar3, c3, 0);
+    c3 = rsGetElementAt_char3(aChar3, 0, 0);
+    rsSetElementAt_char3(aChar3, c3, 0, 0);
+    c3 = rsGetElementAt_char3(aChar3, 0, 0, 0);
+    rsSetElementAt_char3(aChar3, c3, 0, 0, 0);
+    c4 = rsGetElementAt_char4(aChar4, 0);
+    rsSetElementAt_char4(aChar4, c4, 0);
+    c4 = rsGetElementAt_char4(aChar4, 0, 0);
+    rsSetElementAt_char4(aChar4, c4, 0, 0);
+    c4 = rsGetElementAt_char4(aChar4, 0, 0, 0);
+    rsSetElementAt_char4(aChar4, c4, 0, 0, 0);
+
+    uc = rsGetElementAt_uchar(aUChar, 0);
+    rsSetElementAt_uchar(aUChar, uc, 0);
+    uc = rsGetElementAt_uchar(aUChar, 0, 0);
+    rsSetElementAt_uchar(aUChar, uc, 0, 0);
+    uc = rsGetElementAt_uchar(aUChar, 0, 0, 0);
+    rsSetElementAt_uchar(aUChar, uc, 0, 0, 0);
+    uc2 = rsGetElementAt_uchar2(aUChar2, 0);
+    rsSetElementAt_uchar2(aUChar2, uc2, 0);
+    uc2 = rsGetElementAt_uchar2(aUChar2, 0, 0);
+    rsSetElementAt_uchar2(aUChar2, uc2, 0, 0);
+    uc2 = rsGetElementAt_uchar2(aUChar2, 0, 0, 0);
+    rsSetElementAt_uchar2(aUChar2, uc2, 0, 0, 0);
+    uc3 = rsGetElementAt_uchar3(aUChar3, 0);
+    rsSetElementAt_uchar3(aUChar3, uc3, 0);
+    uc3 = rsGetElementAt_uchar3(aUChar3, 0, 0);
+    rsSetElementAt_uchar3(aUChar3, uc3, 0, 0);
+    uc3 = rsGetElementAt_uchar3(aUChar3, 0, 0, 0);
+    rsSetElementAt_uchar3(aUChar3, uc3, 0, 0, 0);
+    uc4 = rsGetElementAt_uchar4(aUChar4, 0);
+    rsSetElementAt_uchar4(aUChar4, uc4, 0);
+    uc4 = rsGetElementAt_uchar4(aUChar4, 0, 0);
+    rsSetElementAt_uchar4(aUChar4, uc4, 0, 0);
+    uc4 = rsGetElementAt_uchar4(aUChar4, 0, 0, 0);
+    rsSetElementAt_uchar4(aUChar4, uc4, 0, 0, 0);
+
+    s = rsGetElementAt_short(aShort, 0);
+    rsSetElementAt_short(aShort, s, 0);
+    s = rsGetElementAt_short(aShort, 0, 0);
+    rsSetElementAt_short(aShort, s, 0, 0);
+    s = rsGetElementAt_short(aShort, 0, 0, 0);
+    rsSetElementAt_short(aShort, s, 0, 0, 0);
+    s2 = rsGetElementAt_short2(aShort2, 0);
+    rsSetElementAt_short2(aShort2, s2, 0);
+    s2 = rsGetElementAt_short2(aShort2, 0, 0);
+    rsSetElementAt_short2(aShort2, s2, 0, 0);
+    s2 = rsGetElementAt_short2(aShort2, 0, 0, 0);
+    rsSetElementAt_short2(aShort2, s2, 0, 0, 0);
+    s3 = rsGetElementAt_short3(aShort3, 0);
+    rsSetElementAt_short3(aShort3, s3, 0);
+    s3 = rsGetElementAt_short3(aShort3, 0, 0);
+    rsSetElementAt_short3(aShort3, s3, 0, 0);
+    s3 = rsGetElementAt_short3(aShort3, 0, 0, 0);
+    rsSetElementAt_short3(aShort3, s3, 0, 0, 0);
+    s4 = rsGetElementAt_short4(aShort4, 0);
+    rsSetElementAt_short4(aShort4, s4, 0);
+    s4 = rsGetElementAt_short4(aShort4, 0, 0);
+    rsSetElementAt_short4(aShort4, s4, 0, 0);
+    s4 = rsGetElementAt_short4(aShort4, 0, 0, 0);
+    rsSetElementAt_short4(aShort4, s4, 0, 0, 0);
+
+    us = rsGetElementAt_ushort(aUShort, 0);
+    rsSetElementAt_ushort(aUShort, us, 0);
+    us = rsGetElementAt_ushort(aUShort, 0, 0);
+    rsSetElementAt_ushort(aUShort, us, 0, 0);
+    us = rsGetElementAt_ushort(aUShort, 0, 0, 0);
+    rsSetElementAt_ushort(aUShort, us, 0, 0, 0);
+    us2 = rsGetElementAt_ushort2(aUShort2, 0);
+    rsSetElementAt_ushort2(aUShort2, us2, 0);
+    us2 = rsGetElementAt_ushort2(aUShort2, 0, 0);
+    rsSetElementAt_ushort2(aUShort2, us2, 0, 0);
+    us2 = rsGetElementAt_ushort2(aUShort2, 0, 0, 0);
+    rsSetElementAt_ushort2(aUShort2, us2, 0, 0, 0);
+    us3 = rsGetElementAt_ushort3(aUShort3, 0);
+    rsSetElementAt_ushort3(aUShort3, us3, 0);
+    us3 = rsGetElementAt_ushort3(aUShort3, 0, 0);
+    rsSetElementAt_ushort3(aUShort3, us3, 0, 0);
+    us3 = rsGetElementAt_ushort3(aUShort3, 0, 0, 0);
+    rsSetElementAt_ushort3(aUShort3, us3, 0, 0, 0);
+    us4 = rsGetElementAt_ushort4(aUShort4, 0);
+    rsSetElementAt_ushort4(aUShort4, us4, 0);
+    us4 = rsGetElementAt_ushort4(aUShort4, 0, 0);
+    rsSetElementAt_ushort4(aUShort4, us4, 0, 0);
+    us4 = rsGetElementAt_ushort4(aUShort4, 0, 0, 0);
+    rsSetElementAt_ushort4(aUShort4, us4, 0, 0, 0);
+
+    i = rsGetElementAt_int(aInt, 0);
+    rsSetElementAt_int(aInt, i, 0);
+    i = rsGetElementAt_int(aInt, 0, 0);
+    rsSetElementAt_int(aInt, i, 0, 0);
+    i = rsGetElementAt_int(aInt, 0, 0, 0);
+    rsSetElementAt_int(aInt, i, 0, 0, 0);
+    i2 = rsGetElementAt_int2(aInt2, 0);
+    rsSetElementAt_int2(aInt2, i2, 0);
+    i2 = rsGetElementAt_int2(aInt2, 0, 0);
+    rsSetElementAt_int2(aInt2, i2, 0, 0);
+    i2 = rsGetElementAt_int2(aInt2, 0, 0, 0);
+    rsSetElementAt_int2(aInt2, i2, 0, 0, 0);
+    i3 = rsGetElementAt_int3(aInt3, 0);
+    rsSetElementAt_int3(aInt3, i3, 0);
+    i3 = rsGetElementAt_int3(aInt3, 0, 0);
+    rsSetElementAt_int3(aInt3, i3, 0, 0);
+    i3 = rsGetElementAt_int3(aInt3, 0, 0, 0);
+    rsSetElementAt_int3(aInt3, i3, 0, 0, 0);
+    i4 = rsGetElementAt_int4(aInt4, 0);
+    rsSetElementAt_int4(aInt4, i4, 0);
+    i4 = rsGetElementAt_int4(aInt4, 0, 0);
+    rsSetElementAt_int4(aInt4, i4, 0, 0);
+    i4 = rsGetElementAt_int4(aInt4, 0, 0, 0);
+    rsSetElementAt_int4(aInt4, i4, 0, 0, 0);
+
+    ui = rsGetElementAt_uint(aUInt, 0);
+    rsSetElementAt_uint(aUInt, ui, 0);
+    ui = rsGetElementAt_uint(aUInt, 0, 0);
+    rsSetElementAt_uint(aUInt, ui, 0, 0);
+    ui = rsGetElementAt_uint(aUInt, 0, 0, 0);
+    rsSetElementAt_uint(aUInt, ui, 0, 0, 0);
+    ui2 = rsGetElementAt_uint2(aUInt2, 0);
+    rsSetElementAt_uint2(aUInt2, ui2, 0);
+    ui2 = rsGetElementAt_uint2(aUInt2, 0, 0);
+    rsSetElementAt_uint2(aUInt2, ui2, 0, 0);
+    ui2 = rsGetElementAt_uint2(aUInt2, 0, 0, 0);
+    rsSetElementAt_uint2(aUInt2, ui2, 0, 0, 0);
+    ui3 = rsGetElementAt_uint3(aUInt3, 0);
+    rsSetElementAt_uint3(aUInt3, ui3, 0);
+    ui3 = rsGetElementAt_uint3(aUInt3, 0, 0);
+    rsSetElementAt_uint3(aUInt3, ui3, 0, 0);
+    ui3 = rsGetElementAt_uint3(aUInt3, 0, 0, 0);
+    rsSetElementAt_uint3(aUInt3, ui3, 0, 0, 0);
+    ui4 = rsGetElementAt_uint4(aUInt4, 0);
+    rsSetElementAt_uint4(aUInt4, ui4, 0);
+    ui4 = rsGetElementAt_uint4(aUInt4, 0, 0);
+    rsSetElementAt_uint4(aUInt4, ui4, 0, 0);
+    ui4 = rsGetElementAt_uint4(aUInt4, 0, 0, 0);
+    rsSetElementAt_uint4(aUInt4, ui4, 0, 0, 0);
+
+    l = rsGetElementAt_long(aLong, 0);
+    rsSetElementAt_long(aLong, l, 0);
+    l = rsGetElementAt_long(aLong, 0, 0);
+    rsSetElementAt_long(aLong, l, 0, 0);
+    l = rsGetElementAt_long(aLong, 0, 0, 0);
+    rsSetElementAt_long(aLong, l, 0, 0, 0);
+    l2 = rsGetElementAt_long2(aLong2, 0);
+    rsSetElementAt_long2(aLong2, l2, 0);
+    l2 = rsGetElementAt_long2(aLong2, 0, 0);
+    rsSetElementAt_long2(aLong2, l2, 0, 0);
+    l2 = rsGetElementAt_long2(aLong2, 0, 0, 0);
+    rsSetElementAt_long2(aLong2, l2, 0, 0, 0);
+    l3 = rsGetElementAt_long3(aLong3, 0);
+    rsSetElementAt_long3(aLong3, l3, 0);
+    l3 = rsGetElementAt_long3(aLong3, 0, 0);
+    rsSetElementAt_long3(aLong3, l3, 0, 0);
+    l3 = rsGetElementAt_long3(aLong3, 0, 0, 0);
+    rsSetElementAt_long3(aLong3, l3, 0, 0, 0);
+    l4 = rsGetElementAt_long4(aLong4, 0);
+    rsSetElementAt_long4(aLong4, l4, 0);
+    l4 = rsGetElementAt_long4(aLong4, 0, 0);
+    rsSetElementAt_long4(aLong4, l4, 0, 0);
+    l4 = rsGetElementAt_long4(aLong4, 0, 0, 0);
+    rsSetElementAt_long4(aLong4, l4, 0, 0, 0);
+
+    ul = rsGetElementAt_ulong(aULong, 0);
+    rsSetElementAt_ulong(aULong, ul, 0);
+    ul = rsGetElementAt_ulong(aULong, 0, 0);
+    rsSetElementAt_ulong(aULong, ul, 0, 0);
+    ul = rsGetElementAt_ulong(aULong, 0, 0, 0);
+    rsSetElementAt_ulong(aULong, ul, 0, 0, 0);
+    ul2 = rsGetElementAt_ulong2(aULong2, 0);
+    rsSetElementAt_ulong2(aULong2, ul2, 0);
+    ul2 = rsGetElementAt_ulong2(aULong2, 0, 0);
+    rsSetElementAt_ulong2(aULong2, ul2, 0, 0);
+    ul2 = rsGetElementAt_ulong2(aULong2, 0, 0, 0);
+    rsSetElementAt_ulong2(aULong2, ul2, 0, 0, 0);
+    ul3 = rsGetElementAt_ulong3(aULong3, 0);
+    rsSetElementAt_ulong3(aULong3, ul3, 0);
+    ul3 = rsGetElementAt_ulong3(aULong3, 0, 0);
+    rsSetElementAt_ulong3(aULong3, ul3, 0, 0);
+    ul3 = rsGetElementAt_ulong3(aULong3, 0, 0, 0);
+    rsSetElementAt_ulong3(aULong3, ul3, 0, 0, 0);
+    ul4 = rsGetElementAt_ulong4(aULong4, 0);
+    rsSetElementAt_ulong4(aULong4, ul4, 0);
+    ul4 = rsGetElementAt_ulong4(aULong4, 0, 0);
+    rsSetElementAt_ulong4(aULong4, ul4, 0, 0);
+    ul4 = rsGetElementAt_ulong4(aULong4, 0, 0, 0);
+    rsSetElementAt_ulong4(aULong4, ul4, 0, 0, 0);
+
+    f = rsGetElementAt_float(aFloat, 0);
+    rsSetElementAt_float(aFloat, f, 0);
+    f = rsGetElementAt_float(aFloat, 0, 0);
+    rsSetElementAt_float(aFloat, f, 0, 0);
+    f = rsGetElementAt_float(aFloat, 0, 0, 0);
+    rsSetElementAt_float(aFloat, f, 0, 0, 0);
+    f2 = rsGetElementAt_float2(aFloat2, 0);
+    rsSetElementAt_float2(aFloat2, f2, 0);
+    f2 = rsGetElementAt_float2(aFloat2, 0, 0);
+    rsSetElementAt_float2(aFloat2, f2, 0, 0);
+    f2 = rsGetElementAt_float2(aFloat2, 0, 0, 0);
+    rsSetElementAt_float2(aFloat2, f2, 0, 0, 0);
+    f3 = rsGetElementAt_float3(aFloat3, 0);
+    rsSetElementAt_float3(aFloat3, f3, 0);
+    f3 = rsGetElementAt_float3(aFloat3, 0, 0);
+    rsSetElementAt_float3(aFloat3, f3, 0, 0);
+    f3 = rsGetElementAt_float3(aFloat3, 0, 0, 0);
+    rsSetElementAt_float3(aFloat3, f3, 0, 0, 0);
+    f4 = rsGetElementAt_float4(aFloat4, 0);
+    rsSetElementAt_float4(aFloat4, f4, 0);
+    f4 = rsGetElementAt_float4(aFloat4, 0, 0);
+    rsSetElementAt_float4(aFloat4, f4, 0, 0);
+    f4 = rsGetElementAt_float4(aFloat4, 0, 0, 0);
+    rsSetElementAt_float4(aFloat4, f4, 0, 0, 0);
+
+    d = rsGetElementAt_double(aDouble, 0);
+    rsSetElementAt_double(aDouble, d, 0);
+    d = rsGetElementAt_double(aDouble, 0, 0);
+    rsSetElementAt_double(aDouble, d, 0, 0);
+    d = rsGetElementAt_double(aDouble, 0, 0, 0);
+    rsSetElementAt_double(aDouble, d, 0, 0, 0);
+    d2 = rsGetElementAt_double2(aDouble2, 0);
+    rsSetElementAt_double2(aDouble2, d2, 0);
+    d2 = rsGetElementAt_double2(aDouble2, 0, 0);
+    rsSetElementAt_double2(aDouble2, d2, 0, 0);
+    d2 = rsGetElementAt_double2(aDouble2, 0, 0, 0);
+    rsSetElementAt_double2(aDouble2, d2, 0, 0, 0);
+    d3 = rsGetElementAt_double3(aDouble3, 0);
+    rsSetElementAt_double3(aDouble3, d3, 0);
+    d3 = rsGetElementAt_double3(aDouble3, 0, 0);
+    rsSetElementAt_double3(aDouble3, d3, 0, 0);
+    d3 = rsGetElementAt_double3(aDouble3, 0, 0, 0);
+    rsSetElementAt_double3(aDouble3, d3, 0, 0, 0);
+    d4 = rsGetElementAt_double4(aDouble4, 0);
+    rsSetElementAt_double4(aDouble4, d4, 0);
+    d4 = rsGetElementAt_double4(aDouble4, 0, 0);
+    rsSetElementAt_double4(aDouble4, d4, 0, 0);
+    d4 = rsGetElementAt_double4(aDouble4, 0, 0, 0);
+    rsSetElementAt_double4(aDouble4, d4, 0, 0, 0);
+
+    uc3.x = rsGetElementAtYuv_uchar_Y(aUChar4, 0, 0);
+    uc3.y = rsGetElementAtYuv_uchar_U(aUChar4, 0, 0);
+    uc3.z = rsGetElementAtYuv_uchar_V(aUChar4, 0, 0);
+
+    c3.x = *(char*)rsGetElementAt(aChar3, 0);
+    c3.y = *(char*)rsGetElementAt(aChar3, 0, 0);
+    c3.z = *(char*)rsGetElementAt(aChar3, 0, 0, 0);
+
+    rsAllocationIoSend(aInt);
+    rsAllocationIoReceive(aInt);
+
+    elemNonNull = rsAllocationGetElement(aInt);
+
+    rsAllocationCopy1DRange(allocDst, 0, 0, 0, allocDst, 0, 0);
+    rsAllocationCopy2DRange(allocDst, 0, 0, 0, 0, 0, 0, allocDst, 0, 0, 0, 0);
+
+    // rsSample routines
+    f4 += rsSample(allocDst, samplerNonNull, f);
+    f4 += rsSample(allocDst, samplerNonNull, f, f);
+    f4 += rsSample(allocDst, samplerNonNull, f2);
+    f4 += rsSample(allocDst, samplerNonNull, f2, f);
+
+    // rs_atomic.rsh
+    rsAtomicInc(&i);
+    rsAtomicDec(&i);
+    rsAtomicAdd(&i, 1);
+    rsAtomicSub(&i, 2);
+    rsAtomicAnd(&i, 3);
+    rsAtomicOr(&i, 4);
+    rsAtomicXor(&i, 5);
+    rsAtomicMin(&i, 6);
+    rsAtomicMin(&ui, 6);
+    rsAtomicMax(&i, 7);
+    rsAtomicMax(&ui, 7);
+    rsAtomicCas(&i, 8, 9);
+    rsAtomicCas(&ui, 8, 9);
+
+    // rs_cl.rsh
+    c2 = convert_char2(c2);
+    c2 = convert_char2(uc2);
+    c2 = convert_char2(s2);
+    c2 = convert_char2(us2);
+    c2 = convert_char2(i2);
+    c2 = convert_char2(ui2);
+    c2 = convert_char2(f2);
+    c3 = convert_char3(c3);
+    c3 = convert_char3(uc3);
+    c3 = convert_char3(s3);
+    c3 = convert_char3(us3);
+    c3 = convert_char3(i3);
+    c3 = convert_char3(ui3);
+    c3 = convert_char3(f3);
+    c4 = convert_char4(c4);
+    c4 = convert_char4(uc4);
+    c4 = convert_char4(s4);
+    c4 = convert_char4(us4);
+    c4 = convert_char4(i4);
+    c4 = convert_char4(ui4);
+    c4 = convert_char4(f4);
+
+    uc2 = convert_uchar2(c2);
+    uc2 = convert_uchar2(uc2);
+    uc2 = convert_uchar2(s2);
+    uc2 = convert_uchar2(us2);
+    uc2 = convert_uchar2(i2);
+    uc2 = convert_uchar2(ui2);
+    uc2 = convert_uchar2(f2);
+    uc3 = convert_uchar3(c3);
+    uc3 = convert_uchar3(uc3);
+    uc3 = convert_uchar3(s3);
+    uc3 = convert_uchar3(us3);
+    uc3 = convert_uchar3(i3);
+    uc3 = convert_uchar3(ui3);
+    uc3 = convert_uchar3(f3);
+    uc4 = convert_uchar4(c4);
+    uc4 = convert_uchar4(uc4);
+    uc4 = convert_uchar4(s4);
+    uc4 = convert_uchar4(us4);
+    uc4 = convert_uchar4(i4);
+    uc4 = convert_uchar4(ui4);
+    uc4 = convert_uchar4(f4);
+
+    s2 = convert_short2(c2);
+    s2 = convert_short2(uc2);
+    s2 = convert_short2(s2);
+    s2 = convert_short2(us2);
+    s2 = convert_short2(i2);
+    s2 = convert_short2(ui2);
+    s2 = convert_short2(f2);
+    s3 = convert_short3(c3);
+    s3 = convert_short3(uc3);
+    s3 = convert_short3(s3);
+    s3 = convert_short3(us3);
+    s3 = convert_short3(i3);
+    s3 = convert_short3(ui3);
+    s3 = convert_short3(f3);
+    s4 = convert_short4(c4);
+    s4 = convert_short4(uc4);
+    s4 = convert_short4(s4);
+    s4 = convert_short4(us4);
+    s4 = convert_short4(i4);
+    s4 = convert_short4(ui4);
+    s4 = convert_short4(f4);
+
+    us2 = convert_ushort2(c2);
+    us2 = convert_ushort2(uc2);
+    us2 = convert_ushort2(s2);
+    us2 = convert_ushort2(us2);
+    us2 = convert_ushort2(i2);
+    us2 = convert_ushort2(ui2);
+    us2 = convert_ushort2(f2);
+    us3 = convert_ushort3(c3);
+    us3 = convert_ushort3(uc3);
+    us3 = convert_ushort3(s3);
+    us3 = convert_ushort3(us3);
+    us3 = convert_ushort3(i3);
+    us3 = convert_ushort3(ui3);
+    us3 = convert_ushort3(f3);
+    us4 = convert_ushort4(c4);
+    us4 = convert_ushort4(uc4);
+    us4 = convert_ushort4(s4);
+    us4 = convert_ushort4(us4);
+    us4 = convert_ushort4(i4);
+    us4 = convert_ushort4(ui4);
+    us4 = convert_ushort4(f4);
+
+    i2 = convert_int2(c2);
+    i2 = convert_int2(uc2);
+    i2 = convert_int2(s2);
+    i2 = convert_int2(us2);
+    i2 = convert_int2(i2);
+    i2 = convert_int2(ui2);
+    i2 = convert_int2(f2);
+    i3 = convert_int3(c3);
+    i3 = convert_int3(uc3);
+    i3 = convert_int3(s3);
+    i3 = convert_int3(us3);
+    i3 = convert_int3(i3);
+    i3 = convert_int3(ui3);
+    i3 = convert_int3(f3);
+    i4 = convert_int4(c4);
+    i4 = convert_int4(uc4);
+    i4 = convert_int4(s4);
+    i4 = convert_int4(us4);
+    i4 = convert_int4(i4);
+    i4 = convert_int4(ui4);
+    i4 = convert_int4(f4);
+
+    ui2 = convert_uint2(c2);
+    ui2 = convert_uint2(uc2);
+    ui2 = convert_uint2(s2);
+    ui2 = convert_uint2(us2);
+    ui2 = convert_uint2(i2);
+    ui2 = convert_uint2(ui2);
+    ui2 = convert_uint2(f2);
+    ui3 = convert_uint3(c3);
+    ui3 = convert_uint3(uc3);
+    ui3 = convert_uint3(s3);
+    ui3 = convert_uint3(us3);
+    ui3 = convert_uint3(i3);
+    ui3 = convert_uint3(ui3);
+    ui3 = convert_uint3(f3);
+    ui4 = convert_uint4(c4);
+    ui4 = convert_uint4(uc4);
+    ui4 = convert_uint4(s4);
+    ui4 = convert_uint4(us4);
+    ui4 = convert_uint4(i4);
+    ui4 = convert_uint4(ui4);
+    ui4 = convert_uint4(f4);
+
+    f2 = convert_float2(c2);
+    f2 = convert_float2(uc2);
+    f2 = convert_float2(s2);
+    f2 = convert_float2(us2);
+    f2 = convert_float2(i2);
+    f2 = convert_float2(ui2);
+    f2 = convert_float2(f2);
+    f3 = convert_float3(c3);
+    f3 = convert_float3(uc3);
+    f3 = convert_float3(s3);
+    f3 = convert_float3(us3);
+    f3 = convert_float3(i3);
+    f3 = convert_float3(ui3);
+    f3 = convert_float3(f3);
+    f4 = convert_float4(c4);
+    f4 = convert_float4(uc4);
+    f4 = convert_float4(s4);
+    f4 = convert_float4(us4);
+    f4 = convert_float4(i4);
+    f4 = convert_float4(ui4);
+    f4 = convert_float4(f4);
+
+    // FIXME: No support for long/double (either from/to).
+
+    // math
+    f = acos(f);
+    f2 = acos(f2);
+    f3 = acos(f3);
+    f4 = acos(f4);
+    f = acosh(f);
+    f2 = acosh(f2);
+    f3 = acosh(f3);
+    f4 = acosh(f4);
+    f = acospi(f);
+    f2 = acospi(f2);
+    f3 = acospi(f3);
+    f4 = acospi(f4);
+
+    f = asin(f);
+    f2 = asin(f2);
+    f3 = asin(f3);
+    f4 = asin(f4);
+    f = asinh(f);
+    f2 = asinh(f2);
+    f3 = asinh(f3);
+    f4 = asinh(f4);
+    f = asinpi(f);
+    f2 = asinpi(f2);
+    f3 = asinpi(f3);
+    f4 = asinpi(f4);
+
+    f = atan(f);
+    f2 = atan(f2);
+    f3 = atan(f3);
+    f4 = atan(f4);
+    f = atanh(f);
+    f2 = atanh(f2);
+    f3 = atanh(f3);
+    f4 = atanh(f4);
+    f = atanpi(f);
+    f2 = atanpi(f2);
+    f3 = atanpi(f3);
+    f4 = atanpi(f4);
+
+    f = atan2(f, f);
+    f2 = atan2(f2, f2);
+    f3 = atan2(f3, f3);
+    f4 = atan2(f4, f4);
+    f = atan2pi(f, f);
+    f2 = atan2pi(f2, f2);
+    f3 = atan2pi(f3, f3);
+    f4 = atan2(f4, f4);
+
+    f = cbrt(f);
+    f2 = cbrt(f2);
+    f3 = cbrt(f3);
+    f4 = cbrt(f4);
+
+    f = ceil(f);
+    f2 = ceil(f2);
+    f3 = ceil(f3);
+    f4 = ceil(f4);
+
+    f = copysign(f, f);
+    f2 = copysign(f2, f2);
+    f3 = copysign(f3, f3);
+    f4 = copysign(f4, f4);
+
+    f = cos(f);
+    f2 = cos(f2);
+    f3 = cos(f3);
+    f4 = cos(f4);
+    f = cosh(f);
+    f2 = cosh(f2);
+    f3 = cosh(f3);
+    f4 = cosh(f4);
+    f = cospi(f);
+    f2 = cospi(f2);
+    f3 = cospi(f3);
+    f4 = cospi(f4);
+
+    f = erfc(f);
+    f2 = erfc(f2);
+    f3 = erfc(f3);
+    f4 = erfc(f4);
+    f = erf(f);
+    f2 = erf(f2);
+    f3 = erf(f3);
+    f4 = erf(f4);
+
+    f = exp(f);
+    f2 = exp(f2);
+    f3 = exp(f3);
+    f4 = exp(f4);
+    f = exp2(f);
+    f2 = exp2(f2);
+    f3 = exp2(f3);
+    f4 = exp2(f4);
+
+    f = pow(f, f);
+    f2 = pow(f2, f2);
+    f3 = pow(f3, f3);
+    f4 = pow(f4, f4);
+
+    f = exp10(f);
+    f2 = exp10(f2);
+    f3 = exp10(f3);
+    f4 = exp10(f4);
+
+    f = expm1(f);
+    f2 = expm1(f2);
+    f3 = expm1(f3);
+    f4 = expm1(f4);
+
+    f = fabs(f);
+    f2 = fabs(f2);
+    f3 = fabs(f3);
+    f4 = fabs(f4);
+
+    f = fabs(f);
+    f2 = fabs(f2);
+    f3 = fabs(f3);
+    f4 = fabs(f4);
+
+    f = fdim(f, f);
+    f2 = fdim(f2, f2);
+    f3 = fdim(f3, f3);
+    f4 = fdim(f4, f4);
+
+    f = floor(f);
+    f2 = floor(f2);
+    f3 = floor(f3);
+    f4 = floor(f4);
+
+    f = fma(f, f, f);
+    f2 = fma(f2, f2, f2);
+    f3 = fma(f3, f3, f3);
+    f4 = fma(f4, f4, f4);
+
+    f = fmax(f, f);
+    f2 = fmax(f2, f2);
+    f3 = fmax(f3, f3);
+    f4 = fmax(f4, f4);
+
+    f = fmin(f, f);
+    f2 = fmin(f2, f2);
+    f3 = fmin(f3, f3);
+    f4 = fmin(f4, f4);
+
+    f = fmod(f, f);
+    f2 = fmod(f2, f2);
+    f3 = fmod(f3, f3);
+    f4 = fmod(f4, f4);
+
+    f = fract(f, (float *)&f);
+    f2 = fract(f2, (float2 *)&f2);
+    f3 = fract(f3, (float3 *)&f3);
+    f4 = fract(f4, (float4 *)&f4);
+    f = fract(f);
+    f2 = fract(f2);
+    f3 = fract(f3);
+    f4 = fract(f4);
+
+    f = frexp(f, (int *)&i);
+    f2 = frexp(f2, (int2 *)&i2);
+    f3 = frexp(f3, (int3 *)&i3);
+    f4 = frexp(f4, (int4 *)&i4);
+
+    f = hypot(f, f);
+    f2 = hypot(f2, f2);
+    f3 = hypot(f3, f3);
+    f4 = hypot(f4, f4);
+
+    i = ilogb(f);
+    i2 = ilogb(f2);
+    i3 = ilogb(f3);
+    i4 = ilogb(f4);
+
+    f = ldexp(f, i);
+    f2 = ldexp(f2, i2);
+    f3 = ldexp(f3, i3);
+    f4 = ldexp(f4, i4);
+    f2 = ldexp(f2, i);
+    f3 = ldexp(f3, i);
+    f4 = ldexp(f4, i);
+
+    f = lgamma(f);
+    f2 = lgamma(f2);
+    f3 = lgamma(f3);
+    f4 = lgamma(f4);
+    f = lgamma(f, (int *)&i);
+    f2 = lgamma(f2, (int2 *)&i2);
+    f3 = lgamma(f3, (int3 *)&i3);
+    f4 = lgamma(f4, (int4 *)&i4);
+
+    f = log(f);
+    f2 = log(f2);
+    f3 = log(f3);
+    f4 = log(f4);
+
+    f = log10(f);
+    f2 = log10(f2);
+    f3 = log10(f3);
+    f4 = log10(f4);
+
+    f = log2(f);
+    f2 = log2(f2);
+    f3 = log2(f3);
+    f4 = log2(f4);
+
+    f = log1p(f);
+    f2 = log1p(f2);
+    f3 = log1p(f3);
+    f4 = log1p(f4);
+
+    f = logb(f);
+    f2 = logb(f2);
+    f3 = logb(f3);
+    f4 = logb(f4);
+
+    f = mad(f, f, f);
+    f2 = mad(f2, f2, f2);
+    f3 = mad(f3, f3, f3);
+    f4 = mad(f4, f4, f4);
+
+    f = modf(f, (float *)&f);
+    f2 = modf(f2, (float2 *)&f2);
+    f3 = modf(f3, (float3 *)&f3);
+    f4 = modf(f4, (float4 *)&f4);
+
+    f = nan(ui);
+
+    f = nextafter(f, f);
+    f2 = nextafter(f2, f2);
+    f3 = nextafter(f3, f3);
+    f4 = nextafter(f4, f4);
+
+    f = pown(f, i);
+    f2 = pown(f2, i2);
+    f3 = pown(f3, i3);
+    f4 = pown(f4, i4);
+
+    f = powr(f, f);
+    f2 = powr(f2, f2);
+    f3 = powr(f3, f3);
+    f4 = powr(f4, f4);
+
+    f = remainder(f, f);
+    f2 = remainder(f2, f2);
+    f3 = remainder(f3, f3);
+    f4 = remainder(f4, f4);
+
+    f = remquo(f, f, (int *)&i);
+    f2 = remquo(f2, f2, (int2 *)&i2);
+    f3 = remquo(f3, f3, (int3 *)&i3);
+    f4 = remquo(f4, f4, (int4 *)&i4);
+
+    f = rint(f);
+    f2 = rint(f2);
+    f3 = rint(f3);
+    f4 = rint(f4);
+
+    f = rootn(f, i);
+    f2 = rootn(f2, i2);
+    f3 = rootn(f3, i3);
+    f4 = rootn(f4, i4);
+
+    f = round(f);
+    f2 = round(f2);
+    f3 = round(f3);
+    f4 = round(f4);
+
+    f = rsqrt(f);
+    f2 = rsqrt(f2);
+    f3 = rsqrt(f3);
+    f4 = rsqrt(f4);
+
+    f = sin(f);
+    f2 = sin(f2);
+    f3 = sin(f3);
+    f4 = sin(f4);
+    f = sinh(f);
+    f2 = sinh(f2);
+    f3 = sinh(f3);
+    f4 = sinh(f4);
+    f = sinpi(f);
+    f2 = sinpi(f2);
+    f3 = sinpi(f3);
+    f4 = sinpi(f4);
+
+    f = sincos(f, (float *)&f);
+    f2 = sincos(f2, (float2 *)&f2);
+    f3 = sincos(f3, (float3 *)&f3);
+    f4 = sincos(f4, (float4 *)&f4);
+
+    f = tan(f);
+    f2 = tan(f2);
+    f3 = tan(f3);
+    f4 = tan(f4);
+    f = tanh(f);
+    f2 = tanh(f2);
+    f3 = tanh(f3);
+    f4 = tanh(f4);
+    f = tanpi(f);
+    f2 = tanpi(f2);
+    f3 = tanpi(f3);
+    f4 = tanpi(f4);
+
+    f = tgamma(f);
+    f2 = tgamma(f2);
+    f3 = tgamma(f3);
+    f4 = tgamma(f4);
+
+    f = trunc(f);
+    f2 = trunc(f2);
+    f3 = trunc(f3);
+    f4 = trunc(f4);
+
+    uc = abs(c);
+    uc2 = abs(c2);
+    uc3 = abs(c3);
+    uc4 = abs(c4);
+    us = abs(s);
+    us2 = abs(s2);
+    us3 = abs(s3);
+    us4 = abs(s4);
+    ui = abs(i);
+    ui2 = abs(i2);
+    ui3 = abs(i3);
+    ui4 = abs(i4);
+
+    c = clz(c);
+    c2 = clz(c2);
+    c3 = clz(c3);
+    c4 = clz(c4);
+    uc = clz(uc);
+    uc2 = clz(uc2);
+    uc3 = clz(uc3);
+    uc4 = clz(uc4);
+    s = clz(s);
+    s2 = clz(s2);
+    s3 = clz(s3);
+    s4 = clz(s4);
+    us = clz(us);
+    us2 = clz(us2);
+    us3 = clz(us3);
+    us4 = clz(us4);
+    i = clz(i);
+    i2 = clz(i2);
+    i3 = clz(i3);
+    i4 = clz(i4);
+    ui = clz(ui);
+    ui2 = clz(ui2);
+    ui3 = clz(ui3);
+    ui4 = clz(ui4);
+
+    c = min(c, c);
+    c2 = min(c2, c2);
+    c3 = min(c3, c3);
+    c4 = min(c4, c4);
+    uc = min(uc, uc);
+    uc2 = min(uc2, uc2);
+    uc3 = min(uc3, uc3);
+    uc4 = min(uc4, uc4);
+    s = min(s, s);
+    s2 = min(s2, s2);
+    s3 = min(s3, s3);
+    s4 = min(s4, s4);
+    us = min(us, us);
+    us2 = min(us2, us2);
+    us3 = min(us3, us3);
+    us4 = min(us4, us4);
+    i = min(i, i);
+    i2 = min(i2, i2);
+    i3 = min(i3, i3);
+    i4 = min(i4, i4);
+    ui = min(ui, ui);
+    ui2 = min(ui2, ui2);
+    ui3 = min(ui3, ui3);
+    ui4 = min(ui4, ui4);
+    f = min(f, f);
+    f2 = min(f2, f2);
+    f3 = min(f3, f3);
+    f4 = min(f4, f4);
+    f2 = min(f2, f);
+    f3 = min(f3, f);
+    f4 = min(f4, f);
+
+    c = max(c, c);
+    c2 = max(c2, c2);
+    c3 = max(c3, c3);
+    c4 = max(c4, c4);
+    uc = max(uc, uc);
+    uc2 = max(uc2, uc2);
+    uc3 = max(uc3, uc3);
+    uc4 = max(uc4, uc4);
+    s = max(s, s);
+    s2 = max(s2, s2);
+    s3 = max(s3, s3);
+    s4 = max(s4, s4);
+    us = max(us, us);
+    us2 = max(us2, us2);
+    us3 = max(us3, us3);
+    us4 = max(us4, us4);
+    i = max(i, i);
+    i2 = max(i2, i2);
+    i3 = max(i3, i3);
+    i4 = max(i4, i4);
+    ui = max(ui, ui);
+    ui2 = max(ui2, ui2);
+    ui3 = max(ui3, ui3);
+    ui4 = max(ui4, ui4);
+    f = max(f, f);
+    f2 = max(f2, f2);
+    f3 = max(f3, f3);
+    f4 = max(f4, f4);
+    f2 = max(f2, f);
+    f3 = max(f3, f);
+    f4 = max(f4, f);
+
+    f = clamp(f, f, f);
+    f2 = clamp(f2, f2, f2);
+    f3 = clamp(f3, f3, f3);
+    f4 = clamp(f4, f4, f4);
+    f2 = clamp(f2, f, f);
+    f3 = clamp(f3, f, f);
+    f4 = clamp(f4, f, f);
+    // FIXME: other clamps only in 19+
+
+    f = degrees(f);
+    f2 = degrees(f2);
+    f3 = degrees(f3);
+    f4 = degrees(f4);
+
+    f = mix(f, f, f);
+    f2 = mix(f2, f2, f2);
+    f3 = mix(f3, f3, f3);
+    f4 = mix(f4, f4, f4);
+    f2 = mix(f2, f2, f);
+    f3 = mix(f3, f3, f);
+    f4 = mix(f4, f4, f);
+
+    f = radians(f);
+    f2 = radians(f2);
+    f3 = radians(f3);
+    f4 = radians(f4);
+
+    f = step(f, f);
+    f2 = step(f2, f2);
+    f3 = step(f3, f3);
+    f4 = step(f4, f4);
+    f2 = step(f2, f);
+    f3 = step(f3, f);
+    f4 = step(f4, f);
+
+    f = sign(f);
+    f2 = sign(f2);
+    f3 = sign(f3);
+    f4 = sign(f4);
+
+    f3 = cross(f3, f3);
+    f4 = cross(f4, f4);
+
+    f = dot(f, f);
+    f = dot(f2, f2);
+    f = dot(f3, f3);
+    f = dot(f4, f4);
+
+    f = length(f);
+    f = length(f2);
+    f = length(f3);
+    f = length(f4);
+
+    f = distance(f, f);
+    f = distance(f2, f2);
+    f = distance(f3, f3);
+    f = distance(f4, f4);
+
+    f = normalize(f);
+    f2 = normalize(f2);
+    f3 = normalize(f3);
+    f4 = normalize(f4);
+
+    f = half_recip(f);
+    f2 = half_recip(f2);
+    f3 = half_recip(f3);
+    f4 = half_recip(f4);
+
+    f = half_sqrt(f);
+    f2 = half_sqrt(f2);
+    f3 = half_sqrt(f3);
+    f4 = half_sqrt(f4);
+
+    f = half_rsqrt(f);
+    f2 = half_rsqrt(f2);
+    f3 = half_rsqrt(f3);
+    f4 = half_rsqrt(f4);
+
+    f = fast_length(f);
+    f = fast_length(f2);
+    f = fast_length(f3);
+    f = fast_length(f4);
+
+    f = fast_distance(f, f);
+    f = fast_distance(f2, f2);
+    f = fast_distance(f3, f3);
+    f = fast_distance(f4, f4);
+
+    f = fast_normalize(f);
+    f2 = fast_normalize(f2);
+    f3 = fast_normalize(f3);
+    f4 = fast_normalize(f4);
+
+    f = native_exp2(f);
+    f2 = native_exp2(f2);
+    f3 = native_exp2(f3);
+    f4 = native_exp2(f4);
+
+    f = native_exp(f);
+    f2 = native_exp(f2);
+    f3 = native_exp(f3);
+    f4 = native_exp(f4);
+
+    f = native_exp10(f);
+    f2 = native_exp10(f2);
+    f3 = native_exp10(f3);
+    f4 = native_exp10(f4);
+
+    f = native_log2(f);
+    f2 = native_log2(f2);
+    f3 = native_log2(f3);
+    f4 = native_log2(f4);
+
+    f = native_log(f);
+    f2 = native_log(f2);
+    f3 = native_log(f3);
+    f4 = native_log(f4);
+
+    f = native_log10(f);
+    f2 = native_log10(f2);
+    f3 = native_log10(f3);
+    f4 = native_log10(f4);
+
+    f = native_powr(f, f);
+    f2 = native_powr(f2, f2);
+    f3 = native_powr(f3, f3);
+    f4 = native_powr(f4, f4);
+
+    // rs_core.rsh
+    b = rsSendToClient(0);
+    b = rsSendToClient(0, NULL, 0);
+    rsSendToClientBlocking(0);
+    rsSendToClientBlocking(0, NULL, 0);
+
+    rs_script_call_t sc;
+    rsForEach(scriptNonNull, allocNonNull, allocNonNull, NULL, 0, &sc);
+    rsForEach(scriptNonNull, allocNonNull, allocNonNull, NULL, 0);
+    rsForEach(scriptNonNull, allocNonNull, allocNonNull);
+
+    /********************************
+     * DO NOT EXECUTE THIS FUNCTION *
+     ********************************/
+}
+
+static bool test_obj_api() {
+    bool failed = false;
+
+    _RS_ASSERT(!rsIsObject(elemNull));
+    _RS_ASSERT(rsIsObject(elemNonNull));
+    rsSetObject(&elemNull, elemNonNull);
+    _RS_ASSERT(rsIsObject(elemNull));
+    rsClearObject(&elemNull);
+    _RS_ASSERT(!rsIsObject(elemNull));
+
+    _RS_ASSERT(!rsIsObject(typeNull));
+    _RS_ASSERT(rsIsObject(typeNonNull));
+    rsSetObject(&typeNull, typeNonNull);
+    _RS_ASSERT(rsIsObject(typeNull));
+    rsClearObject(&typeNull);
+    _RS_ASSERT(!rsIsObject(typeNull));
+
+    _RS_ASSERT(!rsIsObject(allocNull));
+    _RS_ASSERT(rsIsObject(allocNonNull));
+    rsSetObject(&allocNull, allocNonNull);
+    _RS_ASSERT(rsIsObject(allocNull));
+    rsClearObject(&allocNull);
+    _RS_ASSERT(!rsIsObject(allocNull));
+
+    _RS_ASSERT(!rsIsObject(samplerNull));
+    _RS_ASSERT(rsIsObject(samplerNonNull));
+    rsSetObject(&samplerNull, samplerNonNull);
+    _RS_ASSERT(rsIsObject(samplerNull));
+    rsClearObject(&samplerNull);
+    _RS_ASSERT(!rsIsObject(samplerNull));
+
+    _RS_ASSERT(!rsIsObject(scriptNull));
+    _RS_ASSERT(rsIsObject(scriptNonNull));
+    rsSetObject(&scriptNull, scriptNonNull);
+    _RS_ASSERT(rsIsObject(scriptNull));
+    rsClearObject(&scriptNull);
+    _RS_ASSERT(!rsIsObject(scriptNull));
+
+    if (failed) {
+        rsDebug("test_obj_api FAILED", -1);
+    }
+    else {
+        rsDebug("test_obj_api PASSED", 0);
+    }
+
+    return failed;
+}
+
+
+static bool test_rs_alloc_api() {
+    bool failed = false;
+    rs_allocation a = rsGetAllocation(allocPtr);
+    _RS_ASSERT(rsIsObject(a));
+    _RS_ASSERT(rsAllocationGetDimX(a) == x);
+    _RS_ASSERT(rsAllocationGetDimY(a) == y);
+    _RS_ASSERT(rsAllocationGetDimZ(a) == z);
+    _RS_ASSERT(rsAllocationGetDimLOD(a) == 0);
+    _RS_ASSERT(rsAllocationGetDimFaces(a) == 0);
+
+    rsSetElementAt_char(a, 5, 1, 0);
+    rsAllocationCopy1DRange(allocDst, 0, 0, x, a, 0, 0);
+    _RS_ASSERT(rsGetElementAt_char(allocDst, 1, 0) == 5);
+
+    if (failed) {
+        rsDebug("test_obj_api FAILED", -1);
+    }
+    else {
+        rsDebug("test_obj_api PASSED", 0);
+    }
+
+    return failed;
+}
+
+
+void api_test() {
+    bool failed = false;
+    failed |= test_obj_api();
+    failed |= test_rs_alloc_api();
+
+    if (failed) {
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    }
+    else {
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+}
+
diff --git a/java/tests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java b/java/tests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
index dd4a98a..feaa81d 100644
--- a/java/tests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
+++ b/java/tests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
@@ -157,7 +157,7 @@
         long t = java.lang.System.currentTimeMillis();
         mScript.invoke_setSampleData(alloc, mTwoByTwoAlloc, sampler);
         mScript.forEach_root(alloc);
-        alloc.ioSendOutput();
+        alloc.ioSend();
         mRS.finish();
         t = java.lang.System.currentTimeMillis() - t;
         Log.i(TAG, "Filter time is: " + t + " ms");
diff --git a/rs.h b/rs.h
index 566d9ea..e31762d 100644
--- a/rs.h
+++ b/rs.h
@@ -45,10 +45,10 @@
     // Allocation update
     const void* rsaAllocationGetType(RsContext con, RsAllocation va);
     // Type update
-    void rsaTypeGetNativeData(RsContext, RsType, uint32_t *typeData, uint32_t typeDataSize);
+    void rsaTypeGetNativeData(RsContext, RsType, uintptr_t *typeData, uint32_t typeDataSize);
     // Element update
-    void rsaElementGetNativeData(RsContext, RsElement, uint32_t *elemData, uint32_t elemDataSize);
-    void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **names,
+    void rsaElementGetNativeData(RsContext, RsElement, uintptr_t *elemData, uint32_t elemDataSize);
+    void rsaElementGetSubElements(RsContext, RsElement, uintptr_t *ids, const char **names,
                                   uint32_t *arraySizes, uint32_t dataSize);
 
     RsDevice rsDeviceCreate();
diff --git a/rsContext.cpp b/rsContext.cpp
index 65ee4d3..145759e 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -319,14 +319,14 @@
 #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");
+        ALOGD("Skipping override driver and loading default CPU driver");
     } else if (rsc->mForceCpu) {
         ALOGV("Application requested CPU execution");
     } else if (rsc->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
         ALOGV("Application requested debug context");
     } else {
         if (loadRuntime(OVERRIDE_RS_DRIVER_STRING, rsc)) {
-            ALOGE("Successfully loaded runtime: %s", OVERRIDE_RS_DRIVER_STRING);
+            ALOGV("Successfully loaded runtime: %s", OVERRIDE_RS_DRIVER_STRING);
             loadDefault = false;
         } else {
             ALOGE("Failed to load runtime %s, loading default", OVERRIDE_RS_DRIVER_STRING);
@@ -510,6 +510,7 @@
     mDPI = 96;
     mIsContextLite = false;
     memset(&watchdog, 0, sizeof(watchdog));
+    memset(&mHal, 0, sizeof(mHal));
     mForceCpu = false;
     mContextType = RS_CONTEXT_TYPE_NORMAL;
     mSynchronous = false;
@@ -721,6 +722,12 @@
 }
 #endif
 
+void Context::finish() {
+    if (mHal.funcs.finish) {
+        mHal.funcs.finish(this);
+    }
+}
+
 void Context::assignName(ObjectBase *obj, const char *name, uint32_t len) {
     rsAssert(!obj->getName());
     obj->setName(name, len);
@@ -785,6 +792,7 @@
 namespace renderscript {
 
 void rsi_ContextFinish(Context *rsc) {
+    rsc->finish();
 }
 
 void rsi_ContextBindRootScript(Context *rsc, RsScript vs) {
diff --git a/rsContext.h b/rsContext.h
index 1dc7c62..ab56c27 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -151,6 +151,7 @@
     void resume();
     void setSurface(uint32_t w, uint32_t h, RsNativeWindow sur);
 #endif
+    void finish();
 
     void setPriority(int32_t p);
     void destroyWorkerThreadResources();
diff --git a/rsRuntime.h b/rsRuntime.h
index 1d81ffb..73cfefb 100644
--- a/rsRuntime.h
+++ b/rsRuntime.h
@@ -109,11 +109,11 @@
 void rsrBindFont(Context *, Font *);
 void rsrFontColor(Context *, float r, float g, float b, float a);
 
+#endif
+
 void rsrAllocationIoSend(Context *, Allocation *);
 void rsrAllocationIoReceive(Context *, Allocation *);
 
-#endif
-
 //////////////////////////////////////////////////////////////////////////////
 // Time routines
 //////////////////////////////////////////////////////////////////////////////
@@ -128,8 +128,12 @@
 // Message routines
 //////////////////////////////////////////////////////////////////////////////
 
-uint32_t rsrToClient(Context *, int cmdID, void *data, int len);
-uint32_t rsrToClientBlocking(Context *, int cmdID, void *data, int len);
+// Keep existing routines to not break current GPU drivers.
+uint32_t __attribute((used)) rsrToClient(Context *, int cmdID, void *data, int len);
+uint32_t __attribute((used)) rsrToClientBlocking(Context *, int cmdID, void *data, int len);
+
+uint32_t rsrToClient(Context *, int cmdID, const void *data, int len);
+uint32_t rsrToClientBlocking(Context *, int cmdID, const void *data, int len);
 
 //////////////////////////////////////////////////////////////////////////////
 //
diff --git a/rsScriptC_Lib.cpp b/rsScriptC_Lib.cpp
index 842d8d2..9435a4a 100644
--- a/rsScriptC_Lib.cpp
+++ b/rsScriptC_Lib.cpp
@@ -161,16 +161,26 @@
 }
 
 
-uint32_t rsrToClient(Context *rsc, int cmdID, void *data, int len) {
+uint32_t rsrToClient(Context *rsc, int cmdID, const void *data, int len) {
     //ALOGE("SC_toClient %i %i %i", cmdID, len);
     return rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, cmdID, len, false);
 }
 
-uint32_t rsrToClientBlocking(Context *rsc, int cmdID, void *data, int len) {
+uint32_t rsrToClientBlocking(Context *rsc, int cmdID, const void *data, int len) {
     //ALOGE("SC_toClientBlocking %i %i", cmdID, len);
     return rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, cmdID, len, true);
 }
 
+// Keep these two routines (using non-const void pointers) so that we can
+// still use existing GPU drivers.
+uint32_t rsrToClient(Context *rsc, int cmdID, void *data, int len) {
+    return rsrToClient(rsc, cmdID, (const void *)data, len);
+}
+
+uint32_t rsrToClientBlocking(Context *rsc, int cmdID, void *data, int len) {
+    return rsrToClientBlocking(rsc, cmdID, (const void *)data, len);
+}
+
 void rsrAllocationIoSend(Context *rsc, Allocation *src) {
     src->ioSend(rsc);
 }
diff --git a/rs_hal.h b/rs_hal.h
index 16bd890..9ae6fed 100644
--- a/rs_hal.h
+++ b/rs_hal.h
@@ -287,6 +287,7 @@
         void (*destroy)(const Context *rsc, const ScriptGroup *sg);
     } scriptgroup;
 
+    void (*finish)(const Context *rsc);
 } RsdHalFunctions;
 
 
diff --git a/scriptc/rs_atomic.rsh b/scriptc/rs_atomic.rsh
index a455edd..99a7353 100644
--- a/scriptc/rs_atomic.rsh
+++ b/scriptc/rs_atomic.rsh
@@ -35,16 +35,6 @@
  */
 extern int32_t __attribute__((overloadable))
     rsAtomicInc(volatile int32_t* addr);
-/**
- * Atomic add one to the value at addr.
- * Equal to rsAtomicAdd(addr, 1)
- *
- * @param addr Address of value to increment
- *
- * @return old value
- */
-extern uint32_t __attribute__((overloadable))
-    rsAtomicInc(volatile uint32_t* addr);
 
 /**
  * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1)
@@ -55,15 +45,6 @@
  */
 extern int32_t __attribute__((overloadable))
     rsAtomicDec(volatile int32_t* addr);
-/**
- * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1)
- *
- * @param addr Address of value to decrement
- *
- * @return old value
- */
-extern uint32_t __attribute__((overloadable))
-    rsAtomicDec(volatile uint32_t* addr);
 
 /**
  * Atomic add a value to the value at addr.  addr[0] += value
@@ -75,16 +56,6 @@
  */
 extern int32_t __attribute__((overloadable))
     rsAtomicAdd(volatile int32_t* addr, int32_t value);
-/**
- * Atomic add a value to the value at addr.  addr[0] += value
- *
- * @param addr Address of value to modify
- * @param value Amount to add to the value at addr
- *
- * @return old value
- */
-extern uint32_t __attribute__((overloadable))
-    rsAtomicAdd(volatile uint32_t* addr, uint32_t value);
 
 /**
  * Atomic Subtract a value from the value at addr.  addr[0] -= value
@@ -96,16 +67,6 @@
  */
 extern int32_t __attribute__((overloadable))
     rsAtomicSub(volatile int32_t* addr, int32_t value);
-/**
- * Atomic Subtract a value from the value at addr.  addr[0] -= value
- *
- * @param addr Address of value to modify
- * @param value Amount to subtract from the value at addr
- *
- * @return old value
- */
-extern uint32_t __attribute__((overloadable))
-    rsAtomicSub(volatile uint32_t* addr, uint32_t value);
 
 /**
  * Atomic Bitwise and a value from the value at addr.  addr[0] &= value
@@ -117,16 +78,6 @@
  */
 extern int32_t __attribute__((overloadable))
     rsAtomicAnd(volatile int32_t* addr, int32_t value);
-/**
- * Atomic Bitwise and a value from the value at addr.  addr[0] &= value
- *
- * @param addr Address of value to modify
- * @param value Amount to and with the value at addr
- *
- * @return old value
- */
-extern uint32_t __attribute__((overloadable))
-    rsAtomicAnd(volatile uint32_t* addr, uint32_t value);
 
 /**
  * Atomic Bitwise or a value from the value at addr.  addr[0] |= value
@@ -138,16 +89,6 @@
  */
 extern int32_t __attribute__((overloadable))
     rsAtomicOr(volatile int32_t* addr, int32_t value);
-/**
- * Atomic Bitwise or a value from the value at addr.  addr[0] |= value
- *
- * @param addr Address of value to modify
- * @param value Amount to or with the value at addr
- *
- * @return old value
- */
-extern uint32_t __attribute__((overloadable))
-    rsAtomicOr(volatile uint32_t* addr, uint32_t value);
 
 /**
  * Atomic Bitwise xor a value from the value at addr.  addr[0] ^= value
@@ -157,16 +98,6 @@
  *
  * @return old value
  */
-extern uint32_t __attribute__((overloadable))
-    rsAtomicXor(volatile uint32_t* addr, uint32_t value);
-/**
- * Atomic Bitwise xor a value from the value at addr.  addr[0] ^= value
- *
- * @param addr Address of value to modify
- * @param value Amount to xor with the value at addr
- *
- * @return old value
- */
 extern int32_t __attribute__((overloadable))
     rsAtomicXor(volatile int32_t* addr, int32_t value);
 
diff --git a/scriptc/rs_cl.rsh b/scriptc/rs_cl.rsh
index 2ff5d8b..7ba2cb6 100644
--- a/scriptc/rs_cl.rsh
+++ b/scriptc/rs_cl.rsh
@@ -926,7 +926,8 @@
 FN_FUNC_FN_FN(step)
 FN_FUNC_FN_F(step)
 
-// not implemented
+// FIXME: not implemented
+#if 0
 extern float __attribute__((const, overloadable)) smoothstep(float, float, float);
 extern float2 __attribute__((const, overloadable)) smoothstep(float2, float2, float2);
 extern float3 __attribute__((const, overloadable)) smoothstep(float3, float3, float3);
@@ -934,6 +935,7 @@
 extern float2 __attribute__((const, overloadable)) smoothstep(float, float, float2);
 extern float3 __attribute__((const, overloadable)) smoothstep(float, float, float3);
 extern float4 __attribute__((const, overloadable)) smoothstep(float, float, float4);
+#endif
 
 /**
  * Return the sign of a value.
diff --git a/tests/cppallocation/Android.mk b/tests/cppallocation/Android.mk
index 191c58d..ddd3ee1 100644
--- a/tests/cppallocation/Android.mk
+++ b/tests/cppallocation/Android.mk
@@ -30,6 +30,7 @@
 LOCAL_C_INCLUDES += frameworks/rs
 LOCAL_C_INCLUDES += $(intermediates)
 
+LOCAL_CLANG := true
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/tests/cppbasic/Android.mk b/tests/cppbasic/Android.mk
index bf7725a..3b19db7 100644
--- a/tests/cppbasic/Android.mk
+++ b/tests/cppbasic/Android.mk
@@ -30,6 +30,7 @@
 LOCAL_C_INCLUDES += frameworks/rs
 LOCAL_C_INCLUDES += $(intermediates)
 
+LOCAL_CLANG := true
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/tests/cppbasic/compute.cpp b/tests/cppbasic/compute.cpp
index 21ffe2b..96aa324 100644
--- a/tests/cppbasic/compute.cpp
+++ b/tests/cppbasic/compute.cpp
@@ -6,9 +6,8 @@
 using namespace android;
 using namespace RSC;
 
-int main(int argc, char** argv)
+int test_compute()
 {
-
     sp<RS> rs = new RS();
     printf("New RS %p\n", rs.get());
 
@@ -32,9 +31,17 @@
     sp<Allocation> aout = Allocation::createTyped(rs, t);
     printf("Allocation %p %p\n", ain.get(), aout.get());
 
-    ScriptC_mono* sc = new ScriptC_mono(rs);
+    sp<ScriptC_mono> sc = new ScriptC_mono(rs);
     printf("new script\n");
 
+    sc->set_alloc(a1);
+    sc->set_elem(e);
+    sc->set_type(t);
+    sc->set_script(sc);
+    sc->set_script(NULL);
+    sp<const Sampler> samp = Sampler::CLAMP_NEAREST(rs);
+    sc->set_sampler(samp);
+
     // We read back the status from the script-side via a "failed" allocation.
     sp<const Element> failed_e = Element::BOOLEAN(rs);
     Type::Builder failed_tb(rs, failed_e);
@@ -88,9 +95,11 @@
         failed_alloc->copy1DTo(&failed);
     }
 
-    printf("Deleting stuff\n");
-    delete sc;
-    printf("Delete OK\n");
+    return failed;
+}
+
+int main() {
+    bool failed = test_compute();
 
     if (failed) {
         printf("TEST FAILED!\n");
diff --git a/tests/cppbasic/mono.rs b/tests/cppbasic/mono.rs
index eab0336..9e262e7 100644
--- a/tests/cppbasic/mono.rs
+++ b/tests/cppbasic/mono.rs
@@ -42,6 +42,12 @@
     char c[3];
 };
 
+rs_allocation alloc;
+rs_element elem;
+rs_type type;
+rs_sampler sampler;
+rs_script script;
+
 void root(const uchar4 *v_in, uchar4 *v_out) {
     float4 f4 = rsUnpackColor8888(*v_in);
 
diff --git a/tests/cppstrided/Android.mk b/tests/cppstrided/Android.mk
index f0c5c4b..66161c4 100644
--- a/tests/cppstrided/Android.mk
+++ b/tests/cppstrided/Android.mk
@@ -30,6 +30,7 @@
 LOCAL_C_INCLUDES += frameworks/rs
 LOCAL_C_INCLUDES += $(intermediates)
 
+LOCAL_CLANG := true
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/tests/latency/Android.mk b/tests/latency/Android.mk
index cdea381..83d5ad8 100644
--- a/tests/latency/Android.mk
+++ b/tests/latency/Android.mk
@@ -30,6 +30,7 @@
 LOCAL_C_INCLUDES += frameworks/rs
 LOCAL_C_INCLUDES += $(intermediates)
 
+LOCAL_CLANG := true
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/tests/typecheck/Android.mk b/tests/typecheck/Android.mk
index 064ccc0..62522a4 100644
--- a/tests/typecheck/Android.mk
+++ b/tests/typecheck/Android.mk
@@ -30,6 +30,7 @@
 LOCAL_C_INCLUDES += frameworks/rs
 LOCAL_C_INCLUDES += $(intermediates)
 
+LOCAL_CLANG := true
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/tests/typecheck/typecheck.cpp b/tests/typecheck/typecheck.cpp
index 17dee1f..d50cbf6 100644
--- a/tests/typecheck/typecheck.cpp
+++ b/tests/typecheck/typecheck.cpp
@@ -71,7 +71,7 @@
 TEST_ELEM_ALL(F32)
 TEST_ELEM_ALL(F64)
 
-int main(int argc, char** argv)
+int main()
 {
     bool failed = false;