Reconcile with honeycomb-release

Change-Id: I83818e0c61f0fcb53b154cd0a85f18924745912f
diff --git a/Android.mk b/Android.mk
index 3835852..29c1447 100644
--- a/Android.mk
+++ b/Android.mk
@@ -28,7 +28,6 @@
 # slangdata_output_var_name := rs_runtime_lib_bc
 # LOCAL_MODULE := librslib_rt
 
-# LOCAL_PRELINK_MODULE := false
 # LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 
 # LOCAL_MODULE_TAGS := optional
@@ -91,11 +90,15 @@
 	rsContext.cpp \
 	rsDevice.cpp \
 	rsElement.cpp \
+	rsFBOCache.cpp \
+	rsFifoSocket.cpp \
 	rsFileA3D.cpp \
 	rsFont.cpp \
 	rsLocklessFifo.cpp \
 	rsObjectBase.cpp \
-	rsMatrix.cpp \
+	rsMatrix2x2.cpp \
+	rsMatrix3x3.cpp \
+	rsMatrix4x4.cpp \
 	rsMesh.cpp \
 	rsMutex.cpp \
 	rsProgram.cpp \
@@ -107,15 +110,26 @@
 	rsScript.cpp \
 	rsScriptC.cpp \
 	rsScriptC_Lib.cpp \
-	rsScriptC_LibCL.cpp \
 	rsScriptC_LibGL.cpp \
-	rsShaderCache.cpp \
 	rsSignal.cpp \
 	rsStream.cpp \
 	rsThreadIO.cpp \
 	rsType.cpp \
-	rsVertexArray.cpp
-
+	driver/rsdBcc.cpp \
+	driver/rsdCore.cpp \
+	driver/rsdFrameBuffer.cpp \
+	driver/rsdGL.cpp \
+	driver/rsdMesh.cpp \
+	driver/rsdMeshObj.cpp \
+	driver/rsdProgram.cpp \
+	driver/rsdProgramRaster.cpp \
+	driver/rsdProgramStore.cpp \
+	driver/rsdRuntimeMath.cpp \
+	driver/rsdRuntimeStubs.cpp \
+	driver/rsdSampler.cpp \
+	driver/rsdShader.cpp \
+	driver/rsdShaderCache.cpp \
+	driver/rsdVertexArray.cpp
 
 LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc
 
@@ -124,15 +138,35 @@
 LOCAL_C_INCLUDES += external/freetype/include external/zlib dalvik
 LOCAL_C_INCLUDES += frameworks/compile/libbcc/include
 
+LOCAL_CFLAGS += -Werror -Wall -Wno-unused-parameter -Wno-unused-variable
+
 LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_MODULE:= libRS
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
 
-# include the java examples
-include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk,\
-    java \
-    ))
+# Now build a host version for serialization
+include $(CLEAR_VARS)
+LOCAL_CFLAGS += -Werror -Wall -Wno-unused-parameter -Wno-unused-variable
+LOCAL_CFLAGS += -DANDROID_RS_SERIALIZE
+
+LOCAL_SRC_FILES:= \
+	rsAllocation.cpp \
+	rsComponent.cpp \
+	rsElement.cpp \
+	rsFileA3D.cpp \
+	rsObjectBase.cpp \
+	rsMesh.cpp \
+	rsStream.cpp \
+	rsType.cpp
+
+LOCAL_STATIC_LIBRARIES := libcutils libutils
+
+LOCAL_LDLIBS := -lpthread
+LOCAL_MODULE:= libRSserialize
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_STATIC_LIBRARY)
 
 endif #simulator
diff --git a/RenderScript.h b/RenderScript.h
index f160ef1..3f2d67a 100644
--- a/RenderScript.h
+++ b/RenderScript.h
@@ -24,313 +24,9 @@
 extern "C" {
 #endif
 
-//////////////////////////////////////////////////////
+#include "RenderScriptDefines.h"
+
 //
-
-typedef void * RsAsyncVoidPtr;
-
-typedef void * RsAdapter1D;
-typedef void * RsAdapter2D;
-typedef void * RsAllocation;
-typedef void * RsAnimation;
-typedef void * RsContext;
-typedef void * RsDevice;
-typedef void * RsElement;
-typedef void * RsFile;
-typedef void * RsFont;
-typedef void * RsSampler;
-typedef void * RsScript;
-typedef void * RsMesh;
-typedef void * RsType;
-typedef void * RsObjectBase;
-
-typedef void * RsProgram;
-typedef void * RsProgramVertex;
-typedef void * RsProgramFragment;
-typedef void * RsProgramStore;
-typedef void * RsProgramRaster;
-
-typedef void (* RsBitmapCallback_t)(void *);
-
-enum RsDeviceParam {
-    RS_DEVICE_PARAM_FORCE_SOFTWARE_GL,
-    RS_DEVICE_PARAM_COUNT
-};
-
-typedef struct {
-    uint32_t colorMin;
-    uint32_t colorPref;
-    uint32_t alphaMin;
-    uint32_t alphaPref;
-    uint32_t depthMin;
-    uint32_t depthPref;
-    uint32_t stencilMin;
-    uint32_t stencilPref;
-    uint32_t samplesMin;
-    uint32_t samplesPref;
-    float samplesQ;
-} RsSurfaceConfig;
-
-RsDevice rsDeviceCreate();
-void rsDeviceDestroy(RsDevice);
-void rsDeviceSetConfig(RsDevice, RsDeviceParam, int32_t value);
-
-RsContext rsContextCreate(RsDevice, uint32_t version);
-RsContext rsContextCreateGL(RsDevice, uint32_t version, RsSurfaceConfig sc);
-void rsContextDestroy(RsContext);
-
-enum RsMessageToClientType {
-    RS_MESSAGE_TO_CLIENT_NONE = 0,
-    RS_MESSAGE_TO_CLIENT_EXCEPTION = 1,
-    RS_MESSAGE_TO_CLIENT_RESIZE = 2,
-    RS_MESSAGE_TO_CLIENT_ERROR = 3,
-    RS_MESSAGE_TO_CLIENT_USER = 4
-};
-
-RsMessageToClientType rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen, bool wait);
-RsMessageToClientType rsContextPeekMessage(RsContext vrsc, size_t *receiveLen, uint32_t *subID, bool wait);
-void rsContextInitToClient(RsContext);
-void rsContextDeinitToClient(RsContext);
-
-#define RS_MAX_TEXTURE 2
-#define RS_MAX_ATTRIBS 16
-
-
-enum RsAllocationUsageType {
-    RS_ALLOCATION_USAGE_SCRIPT = 0x0001,
-    RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE = 0x0002,
-    RS_ALLOCATION_USAGE_GRAPHICS_VERTEX = 0x0004,
-    RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS = 0x0008,
-
-    RS_ALLOCATION_USAGE_ALL = 0x000F
-};
-
-enum RsAllocationMipmapControl {
-    RS_ALLOCATION_MIPMAP_NONE = 0,
-    RS_ALLOCATION_MIPMAP_FULL = 1,
-    RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE = 2
-};
-
-enum RsAllocationCubemapFace {
-    RS_ALLOCATION_CUBMAP_FACE_POSITVE_X = 0,
-    RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_X = 1,
-    RS_ALLOCATION_CUBMAP_FACE_POSITVE_Y = 2,
-    RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_Y = 3,
-    RS_ALLOCATION_CUBMAP_FACE_POSITVE_Z = 4,
-    RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_Z = 5
-};
-
-enum RsDataType {
-    RS_TYPE_NONE,
-    RS_TYPE_FLOAT_16,
-    RS_TYPE_FLOAT_32,
-    RS_TYPE_FLOAT_64,
-    RS_TYPE_SIGNED_8,
-    RS_TYPE_SIGNED_16,
-    RS_TYPE_SIGNED_32,
-    RS_TYPE_SIGNED_64,
-    RS_TYPE_UNSIGNED_8,
-    RS_TYPE_UNSIGNED_16,
-    RS_TYPE_UNSIGNED_32,
-    RS_TYPE_UNSIGNED_64,
-
-    RS_TYPE_BOOLEAN,
-
-    RS_TYPE_UNSIGNED_5_6_5,
-    RS_TYPE_UNSIGNED_5_5_5_1,
-    RS_TYPE_UNSIGNED_4_4_4_4,
-
-    RS_TYPE_MATRIX_4X4,
-    RS_TYPE_MATRIX_3X3,
-    RS_TYPE_MATRIX_2X2,
-
-    RS_TYPE_ELEMENT = 1000,
-    RS_TYPE_TYPE,
-    RS_TYPE_ALLOCATION,
-    RS_TYPE_SAMPLER,
-    RS_TYPE_SCRIPT,
-    RS_TYPE_MESH,
-    RS_TYPE_PROGRAM_FRAGMENT,
-    RS_TYPE_PROGRAM_VERTEX,
-    RS_TYPE_PROGRAM_RASTER,
-    RS_TYPE_PROGRAM_STORE,
-};
-
-enum RsDataKind {
-    RS_KIND_USER,
-
-    RS_KIND_PIXEL_L = 7,
-    RS_KIND_PIXEL_A,
-    RS_KIND_PIXEL_LA,
-    RS_KIND_PIXEL_RGB,
-    RS_KIND_PIXEL_RGBA,
-};
-
-enum RsSamplerParam {
-    RS_SAMPLER_MIN_FILTER,
-    RS_SAMPLER_MAG_FILTER,
-    RS_SAMPLER_WRAP_S,
-    RS_SAMPLER_WRAP_T,
-    RS_SAMPLER_WRAP_R,
-    RS_SAMPLER_ANISO
-};
-
-enum RsSamplerValue {
-    RS_SAMPLER_NEAREST,
-    RS_SAMPLER_LINEAR,
-    RS_SAMPLER_LINEAR_MIP_LINEAR,
-    RS_SAMPLER_WRAP,
-    RS_SAMPLER_CLAMP,
-    RS_SAMPLER_LINEAR_MIP_NEAREST,
-};
-
-enum RsTextureTarget {
-    RS_TEXTURE_2D,
-    RS_TEXTURE_CUBE
-};
-
-enum RsDimension {
-    RS_DIMENSION_X,
-    RS_DIMENSION_Y,
-    RS_DIMENSION_Z,
-    RS_DIMENSION_LOD,
-    RS_DIMENSION_FACE,
-
-    RS_DIMENSION_ARRAY_0 = 100,
-    RS_DIMENSION_ARRAY_1,
-    RS_DIMENSION_ARRAY_2,
-    RS_DIMENSION_ARRAY_3,
-    RS_DIMENSION_MAX = RS_DIMENSION_ARRAY_3
-};
-
-enum RsDepthFunc {
-    RS_DEPTH_FUNC_ALWAYS,
-    RS_DEPTH_FUNC_LESS,
-    RS_DEPTH_FUNC_LEQUAL,
-    RS_DEPTH_FUNC_GREATER,
-    RS_DEPTH_FUNC_GEQUAL,
-    RS_DEPTH_FUNC_EQUAL,
-    RS_DEPTH_FUNC_NOTEQUAL
-};
-
-enum RsBlendSrcFunc {
-    RS_BLEND_SRC_ZERO,                  // 0
-    RS_BLEND_SRC_ONE,                   // 1
-    RS_BLEND_SRC_DST_COLOR,             // 2
-    RS_BLEND_SRC_ONE_MINUS_DST_COLOR,   // 3
-    RS_BLEND_SRC_SRC_ALPHA,             // 4
-    RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA,   // 5
-    RS_BLEND_SRC_DST_ALPHA,             // 6
-    RS_BLEND_SRC_ONE_MINUS_DST_ALPHA,   // 7
-    RS_BLEND_SRC_SRC_ALPHA_SATURATE     // 8
-};
-
-enum RsBlendDstFunc {
-    RS_BLEND_DST_ZERO,                  // 0
-    RS_BLEND_DST_ONE,                   // 1
-    RS_BLEND_DST_SRC_COLOR,             // 2
-    RS_BLEND_DST_ONE_MINUS_SRC_COLOR,   // 3
-    RS_BLEND_DST_SRC_ALPHA,             // 4
-    RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,   // 5
-    RS_BLEND_DST_DST_ALPHA,             // 6
-    RS_BLEND_DST_ONE_MINUS_DST_ALPHA    // 7
-};
-
-enum RsTexEnvMode {
-    RS_TEX_ENV_MODE_NONE,
-    RS_TEX_ENV_MODE_REPLACE,
-    RS_TEX_ENV_MODE_MODULATE,
-    RS_TEX_ENV_MODE_DECAL
-};
-
-enum RsProgramParam {
-    RS_PROGRAM_PARAM_INPUT,
-    RS_PROGRAM_PARAM_OUTPUT,
-    RS_PROGRAM_PARAM_CONSTANT,
-    RS_PROGRAM_PARAM_TEXTURE_TYPE,
-};
-
-enum RsPrimitive {
-    RS_PRIMITIVE_POINT,
-    RS_PRIMITIVE_LINE,
-    RS_PRIMITIVE_LINE_STRIP,
-    RS_PRIMITIVE_TRIANGLE,
-    RS_PRIMITIVE_TRIANGLE_STRIP,
-    RS_PRIMITIVE_TRIANGLE_FAN
-};
-
-enum RsError {
-    RS_ERROR_NONE = 0,
-    RS_ERROR_BAD_SHADER = 1,
-    RS_ERROR_BAD_SCRIPT = 2,
-    RS_ERROR_BAD_VALUE = 3,
-    RS_ERROR_OUT_OF_MEMORY = 4,
-    RS_ERROR_DRIVER = 5,
-
-    RS_ERROR_FATAL_UNKNOWN = 0x1000,
-    RS_ERROR_FATAL_DRIVER = 0x1001,
-    RS_ERROR_FATAL_PROGRAM_LINK = 0x1002
-};
-
-enum RsAnimationInterpolation {
-    RS_ANIMATION_INTERPOLATION_STEP,
-    RS_ANIMATION_INTERPOLATION_LINEAR,
-    RS_ANIMATION_INTERPOLATION_BEZIER,
-    RS_ANIMATION_INTERPOLATION_CARDINAL,
-    RS_ANIMATION_INTERPOLATION_HERMITE,
-    RS_ANIMATION_INTERPOLATION_BSPLINE
-};
-
-enum RsAnimationEdge {
-    RS_ANIMATION_EDGE_UNDEFINED,
-    RS_ANIMATION_EDGE_CONSTANT,
-    RS_ANIMATION_EDGE_GRADIENT,
-    RS_ANIMATION_EDGE_CYCLE,
-    RS_ANIMATION_EDGE_OSCILLATE,
-    RS_ANIMATION_EDGE_CYLE_RELATIVE
-};
-
-enum RsA3DClassID {
-    RS_A3D_CLASS_ID_UNKNOWN,
-    RS_A3D_CLASS_ID_MESH,
-    RS_A3D_CLASS_ID_TYPE,
-    RS_A3D_CLASS_ID_ELEMENT,
-    RS_A3D_CLASS_ID_ALLOCATION,
-    RS_A3D_CLASS_ID_PROGRAM_VERTEX,
-    RS_A3D_CLASS_ID_PROGRAM_RASTER,
-    RS_A3D_CLASS_ID_PROGRAM_FRAGMENT,
-    RS_A3D_CLASS_ID_PROGRAM_STORE,
-    RS_A3D_CLASS_ID_SAMPLER,
-    RS_A3D_CLASS_ID_ANIMATION,
-    RS_A3D_CLASS_ID_ADAPTER_1D,
-    RS_A3D_CLASS_ID_ADAPTER_2D,
-    RS_A3D_CLASS_ID_SCRIPT_C
-};
-
-enum RsCullMode {
-    RS_CULL_BACK,
-    RS_CULL_FRONT,
-    RS_CULL_NONE
-};
-
-typedef struct {
-    RsA3DClassID classID;
-    const char* objectName;
-} RsFileIndexEntry;
-
-// Script to Script
-typedef struct {
-    uint32_t xStart;
-    uint32_t xEnd;
-    uint32_t yStart;
-    uint32_t yEnd;
-    uint32_t zStart;
-    uint32_t zEnd;
-    uint32_t arrayStart;
-    uint32_t arrayEnd;
-
-} RsScriptCall;
-
 // A3D loading and object update code.
 // Should only be called at object creation, not thread safe
 RsObjectBase rsaFileA3DGetEntryByIndex(RsContext, uint32_t idx, RsFile);
@@ -353,18 +49,17 @@
 void rsaElementGetNativeData(RsContext, RsElement, uint32_t *elemData, uint32_t elemDataSize);
 void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **names, uint32_t dataSize);
 
-// Async commands for returning new IDS
-RsType rsaTypeCreate(RsContext, RsElement, uint32_t dimX, uint32_t dimY,
-                     uint32_t dimZ, bool mips, bool faces);
-RsAllocation rsaAllocationCreateTyped(RsContext rsc, RsType vtype,
-                                      RsAllocationMipmapControl mips,
-                                      uint32_t usages);
-RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
-                                           RsAllocationMipmapControl mips,
-                                           const void *data, uint32_t usages);
-RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
-                                               RsAllocationMipmapControl mips,
-                                               const void *data, uint32_t usages);
+RsDevice rsDeviceCreate();
+void rsDeviceDestroy(RsDevice dev);
+void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value);
+RsContext rsContextCreate(RsDevice dev, uint32_t version);
+RsContext rsContextCreateGL(RsDevice dev, uint32_t version, RsSurfaceConfig sc, uint32_t dpi);
+
+
+
+#ifdef ANDROID_RS_SERIALIZE
+#define NO_RS_FUNCS
+#endif
 
 #ifndef NO_RS_FUNCS
 #include "rsgApiFuncDecl.h"
diff --git a/RenderScriptDefines.h b/RenderScriptDefines.h
new file mode 100644
index 0000000..ee9645c
--- /dev/null
+++ b/RenderScriptDefines.h
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RENDER_SCRIPT_DEFINES_H
+#define RENDER_SCRIPT_DEFINES_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//////////////////////////////////////////////////////
+//
+
+typedef void * RsAsyncVoidPtr;
+
+typedef void * RsAdapter1D;
+typedef void * RsAdapter2D;
+typedef void * RsAllocation;
+typedef void * RsAnimation;
+typedef void * RsContext;
+typedef void * RsDevice;
+typedef void * RsElement;
+typedef void * RsFile;
+typedef void * RsFont;
+typedef void * RsSampler;
+typedef void * RsScript;
+typedef void * RsMesh;
+typedef void * RsType;
+typedef void * RsObjectBase;
+
+typedef void * RsProgram;
+typedef void * RsProgramVertex;
+typedef void * RsProgramFragment;
+typedef void * RsProgramStore;
+typedef void * RsProgramRaster;
+
+typedef void * RsNativeWindow;
+
+typedef void (* RsBitmapCallback_t)(void *);
+
+typedef struct {
+    float m[16];
+} rs_matrix4x4;
+
+typedef struct {
+    float m[9];
+} rs_matrix3x3;
+
+typedef struct {
+    float m[4];
+} rs_matrix2x2;
+
+enum RsDeviceParam {
+    RS_DEVICE_PARAM_FORCE_SOFTWARE_GL,
+    RS_DEVICE_PARAM_COUNT
+};
+
+typedef struct {
+    uint32_t colorMin;
+    uint32_t colorPref;
+    uint32_t alphaMin;
+    uint32_t alphaPref;
+    uint32_t depthMin;
+    uint32_t depthPref;
+    uint32_t stencilMin;
+    uint32_t stencilPref;
+    uint32_t samplesMin;
+    uint32_t samplesPref;
+    float samplesQ;
+} RsSurfaceConfig;
+
+enum RsMessageToClientType {
+    RS_MESSAGE_TO_CLIENT_NONE = 0,
+    RS_MESSAGE_TO_CLIENT_EXCEPTION = 1,
+    RS_MESSAGE_TO_CLIENT_RESIZE = 2,
+    RS_MESSAGE_TO_CLIENT_ERROR = 3,
+    RS_MESSAGE_TO_CLIENT_USER = 4
+};
+
+enum RsAllocationUsageType {
+    RS_ALLOCATION_USAGE_SCRIPT = 0x0001,
+    RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE = 0x0002,
+    RS_ALLOCATION_USAGE_GRAPHICS_VERTEX = 0x0004,
+    RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS = 0x0008,
+    RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET = 0x0010,
+
+    RS_ALLOCATION_USAGE_ALL = 0x000F
+};
+
+enum RsAllocationMipmapControl {
+    RS_ALLOCATION_MIPMAP_NONE = 0,
+    RS_ALLOCATION_MIPMAP_FULL = 1,
+    RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE = 2
+};
+
+enum RsAllocationCubemapFace {
+    RS_ALLOCATION_CUBMAP_FACE_POSITVE_X = 0,
+    RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_X = 1,
+    RS_ALLOCATION_CUBMAP_FACE_POSITVE_Y = 2,
+    RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_Y = 3,
+    RS_ALLOCATION_CUBMAP_FACE_POSITVE_Z = 4,
+    RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_Z = 5
+};
+
+enum RsDataType {
+    RS_TYPE_NONE,
+    RS_TYPE_FLOAT_16,
+    RS_TYPE_FLOAT_32,
+    RS_TYPE_FLOAT_64,
+    RS_TYPE_SIGNED_8,
+    RS_TYPE_SIGNED_16,
+    RS_TYPE_SIGNED_32,
+    RS_TYPE_SIGNED_64,
+    RS_TYPE_UNSIGNED_8,
+    RS_TYPE_UNSIGNED_16,
+    RS_TYPE_UNSIGNED_32,
+    RS_TYPE_UNSIGNED_64,
+
+    RS_TYPE_BOOLEAN,
+
+    RS_TYPE_UNSIGNED_5_6_5,
+    RS_TYPE_UNSIGNED_5_5_5_1,
+    RS_TYPE_UNSIGNED_4_4_4_4,
+
+    RS_TYPE_MATRIX_4X4,
+    RS_TYPE_MATRIX_3X3,
+    RS_TYPE_MATRIX_2X2,
+
+    RS_TYPE_ELEMENT = 1000,
+    RS_TYPE_TYPE,
+    RS_TYPE_ALLOCATION,
+    RS_TYPE_SAMPLER,
+    RS_TYPE_SCRIPT,
+    RS_TYPE_MESH,
+    RS_TYPE_PROGRAM_FRAGMENT,
+    RS_TYPE_PROGRAM_VERTEX,
+    RS_TYPE_PROGRAM_RASTER,
+    RS_TYPE_PROGRAM_STORE,
+};
+
+enum RsDataKind {
+    RS_KIND_USER,
+
+    RS_KIND_PIXEL_L = 7,
+    RS_KIND_PIXEL_A,
+    RS_KIND_PIXEL_LA,
+    RS_KIND_PIXEL_RGB,
+    RS_KIND_PIXEL_RGBA,
+    RS_KIND_PIXEL_DEPTH,
+};
+
+enum RsSamplerParam {
+    RS_SAMPLER_MIN_FILTER,
+    RS_SAMPLER_MAG_FILTER,
+    RS_SAMPLER_WRAP_S,
+    RS_SAMPLER_WRAP_T,
+    RS_SAMPLER_WRAP_R,
+    RS_SAMPLER_ANISO
+};
+
+enum RsSamplerValue {
+    RS_SAMPLER_NEAREST,
+    RS_SAMPLER_LINEAR,
+    RS_SAMPLER_LINEAR_MIP_LINEAR,
+    RS_SAMPLER_WRAP,
+    RS_SAMPLER_CLAMP,
+    RS_SAMPLER_LINEAR_MIP_NEAREST,
+};
+
+enum RsTextureTarget {
+    RS_TEXTURE_2D,
+    RS_TEXTURE_CUBE
+};
+
+enum RsDimension {
+    RS_DIMENSION_X,
+    RS_DIMENSION_Y,
+    RS_DIMENSION_Z,
+    RS_DIMENSION_LOD,
+    RS_DIMENSION_FACE,
+
+    RS_DIMENSION_ARRAY_0 = 100,
+    RS_DIMENSION_ARRAY_1,
+    RS_DIMENSION_ARRAY_2,
+    RS_DIMENSION_ARRAY_3,
+    RS_DIMENSION_MAX = RS_DIMENSION_ARRAY_3
+};
+
+enum RsDepthFunc {
+    RS_DEPTH_FUNC_ALWAYS,
+    RS_DEPTH_FUNC_LESS,
+    RS_DEPTH_FUNC_LEQUAL,
+    RS_DEPTH_FUNC_GREATER,
+    RS_DEPTH_FUNC_GEQUAL,
+    RS_DEPTH_FUNC_EQUAL,
+    RS_DEPTH_FUNC_NOTEQUAL
+};
+
+enum RsBlendSrcFunc {
+    RS_BLEND_SRC_ZERO,                  // 0
+    RS_BLEND_SRC_ONE,                   // 1
+    RS_BLEND_SRC_DST_COLOR,             // 2
+    RS_BLEND_SRC_ONE_MINUS_DST_COLOR,   // 3
+    RS_BLEND_SRC_SRC_ALPHA,             // 4
+    RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA,   // 5
+    RS_BLEND_SRC_DST_ALPHA,             // 6
+    RS_BLEND_SRC_ONE_MINUS_DST_ALPHA,   // 7
+    RS_BLEND_SRC_SRC_ALPHA_SATURATE     // 8
+};
+
+enum RsBlendDstFunc {
+    RS_BLEND_DST_ZERO,                  // 0
+    RS_BLEND_DST_ONE,                   // 1
+    RS_BLEND_DST_SRC_COLOR,             // 2
+    RS_BLEND_DST_ONE_MINUS_SRC_COLOR,   // 3
+    RS_BLEND_DST_SRC_ALPHA,             // 4
+    RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,   // 5
+    RS_BLEND_DST_DST_ALPHA,             // 6
+    RS_BLEND_DST_ONE_MINUS_DST_ALPHA    // 7
+};
+
+enum RsTexEnvMode {
+    RS_TEX_ENV_MODE_NONE,
+    RS_TEX_ENV_MODE_REPLACE,
+    RS_TEX_ENV_MODE_MODULATE,
+    RS_TEX_ENV_MODE_DECAL
+};
+
+enum RsProgramParam {
+    RS_PROGRAM_PARAM_INPUT,
+    RS_PROGRAM_PARAM_OUTPUT,
+    RS_PROGRAM_PARAM_CONSTANT,
+    RS_PROGRAM_PARAM_TEXTURE_TYPE,
+};
+
+enum RsPrimitive {
+    RS_PRIMITIVE_POINT,
+    RS_PRIMITIVE_LINE,
+    RS_PRIMITIVE_LINE_STRIP,
+    RS_PRIMITIVE_TRIANGLE,
+    RS_PRIMITIVE_TRIANGLE_STRIP,
+    RS_PRIMITIVE_TRIANGLE_FAN
+};
+
+enum RsError {
+    RS_ERROR_NONE = 0,
+    RS_ERROR_BAD_SHADER = 1,
+    RS_ERROR_BAD_SCRIPT = 2,
+    RS_ERROR_BAD_VALUE = 3,
+    RS_ERROR_OUT_OF_MEMORY = 4,
+    RS_ERROR_DRIVER = 5,
+
+    RS_ERROR_FATAL_UNKNOWN = 0x1000,
+    RS_ERROR_FATAL_DRIVER = 0x1001,
+    RS_ERROR_FATAL_PROGRAM_LINK = 0x1002
+};
+
+enum RsAnimationInterpolation {
+    RS_ANIMATION_INTERPOLATION_STEP,
+    RS_ANIMATION_INTERPOLATION_LINEAR,
+    RS_ANIMATION_INTERPOLATION_BEZIER,
+    RS_ANIMATION_INTERPOLATION_CARDINAL,
+    RS_ANIMATION_INTERPOLATION_HERMITE,
+    RS_ANIMATION_INTERPOLATION_BSPLINE
+};
+
+enum RsAnimationEdge {
+    RS_ANIMATION_EDGE_UNDEFINED,
+    RS_ANIMATION_EDGE_CONSTANT,
+    RS_ANIMATION_EDGE_GRADIENT,
+    RS_ANIMATION_EDGE_CYCLE,
+    RS_ANIMATION_EDGE_OSCILLATE,
+    RS_ANIMATION_EDGE_CYLE_RELATIVE
+};
+
+enum RsA3DClassID {
+    RS_A3D_CLASS_ID_UNKNOWN,
+    RS_A3D_CLASS_ID_MESH,
+    RS_A3D_CLASS_ID_TYPE,
+    RS_A3D_CLASS_ID_ELEMENT,
+    RS_A3D_CLASS_ID_ALLOCATION,
+    RS_A3D_CLASS_ID_PROGRAM_VERTEX,
+    RS_A3D_CLASS_ID_PROGRAM_RASTER,
+    RS_A3D_CLASS_ID_PROGRAM_FRAGMENT,
+    RS_A3D_CLASS_ID_PROGRAM_STORE,
+    RS_A3D_CLASS_ID_SAMPLER,
+    RS_A3D_CLASS_ID_ANIMATION,
+    RS_A3D_CLASS_ID_ADAPTER_1D,
+    RS_A3D_CLASS_ID_ADAPTER_2D,
+    RS_A3D_CLASS_ID_SCRIPT_C
+};
+
+enum RsCullMode {
+    RS_CULL_BACK,
+    RS_CULL_FRONT,
+    RS_CULL_NONE
+};
+
+typedef struct {
+    RsA3DClassID classID;
+    const char* objectName;
+} RsFileIndexEntry;
+
+// Script to Script
+typedef struct {
+    uint32_t xStart;
+    uint32_t xEnd;
+    uint32_t yStart;
+    uint32_t yEnd;
+    uint32_t zStart;
+    uint32_t zEnd;
+    uint32_t arrayStart;
+    uint32_t arrayEnd;
+
+} RsScriptCall;
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // RENDER_SCRIPT_DEFINES_H
+
+
+
+
diff --git a/driver/rsdBcc.cpp b/driver/rsdBcc.cpp
new file mode 100644
index 0000000..8120864
--- /dev/null
+++ b/driver/rsdBcc.cpp
@@ -0,0 +1,553 @@
+/*
+ * Copyright (C) 2011 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 "rsdCore.h"
+#include "rsdBcc.h"
+#include "rsdRuntime.h"
+
+#include "rsContext.h"
+#include "rsScriptC.h"
+
+#include "utils/Timers.h"
+#include "utils/StopWatch.h"
+extern "C" {
+#include "libdex/ZipArchive.h"
+}
+
+
+using namespace android;
+using namespace android::renderscript;
+
+struct DrvScript {
+    int (*mRoot)();
+    void (*mInit)();
+
+    BCCScriptRef mBccScript;
+
+    uint32_t mInvokeFunctionCount;
+    InvokeFunc_t *mInvokeFunctions;
+    uint32_t mFieldCount;
+    void ** mFieldAddress;
+    bool * mFieldIsObject;
+
+    const uint8_t * mScriptText;
+    uint32_t mScriptTextLength;
+
+    //uint32_t * mObjectSlots;
+    //uint32_t mObjectSlotCount;
+
+    uint32_t mPragmaCount;
+    const char ** mPragmaKeys;
+    const char ** mPragmaValues;
+
+};
+
+
+static Script * setTLS(Script *sc) {
+    ScriptTLSStruct * tls = (ScriptTLSStruct *)pthread_getspecific(rsdgThreadTLSKey);
+    rsAssert(tls);
+    Script *old = tls->mScript;
+    tls->mScript = sc;
+    return old;
+}
+
+
+// Input: cacheDir
+// Input: resName
+// Input: extName
+//
+// Note: cacheFile = resName + extName
+//
+// Output: Returns cachePath == cacheDir + cacheFile
+static char *genCacheFileName(const char *cacheDir,
+                              const char *resName,
+                              const char *extName) {
+    char cachePath[512];
+    char cacheFile[sizeof(cachePath)];
+    const size_t kBufLen = sizeof(cachePath) - 1;
+
+    cacheFile[0] = '\0';
+    // Note: resName today is usually something like
+    //       "/com.android.fountain:raw/fountain"
+    if (resName[0] != '/') {
+        // Get the absolute path of the raw/***.bc file.
+
+        // Generate the absolute path.  This doesn't do everything it
+        // should, e.g. if resName is "./out/whatever" it doesn't crunch
+        // the leading "./" out because this if-block is not triggered,
+        // but it'll make do.
+        //
+        if (getcwd(cacheFile, kBufLen) == NULL) {
+            LOGE("Can't get CWD while opening raw/***.bc file\n");
+            return NULL;
+        }
+        // Append "/" at the end of cacheFile so far.
+        strncat(cacheFile, "/", kBufLen);
+    }
+
+    // cacheFile = resName + extName
+    //
+    strncat(cacheFile, resName, kBufLen);
+    if (extName != NULL) {
+        // TODO(srhines): strncat() is a bit dangerous
+        strncat(cacheFile, extName, kBufLen);
+    }
+
+    // Turn the path into a flat filename by replacing
+    // any slashes after the first one with '@' characters.
+    char *cp = cacheFile + 1;
+    while (*cp != '\0') {
+        if (*cp == '/') {
+            *cp = '@';
+        }
+        cp++;
+    }
+
+    // Tack on the file name for the actual cache file path.
+    strncpy(cachePath, cacheDir, kBufLen);
+    strncat(cachePath, cacheFile, kBufLen);
+
+    LOGV("Cache file for '%s' '%s' is '%s'\n", resName, extName, cachePath);
+    return strdup(cachePath);
+}
+
+bool rsdScriptInit(const Context *rsc,
+                     ScriptC *script,
+                     char const *resName,
+                     char const *cacheDir,
+                     uint8_t const *bitcode,
+                     size_t bitcodeSize,
+                     uint32_t flags) {
+    //LOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir, bitcode, bitcodeSize, flags, lookupFunc);
+
+    pthread_mutex_lock(&rsdgInitMutex);
+    char *cachePath = NULL;
+    uint32_t objectSlotCount = 0;
+
+    DrvScript *drv = (DrvScript *)calloc(1, sizeof(DrvScript));
+    if (drv == NULL) {
+        goto error;
+    }
+    script->mHal.drv = drv;
+
+    drv->mBccScript = bccCreateScript();
+    script->mHal.info.isThreadable = true;
+    drv->mScriptText = bitcode;
+    drv->mScriptTextLength = bitcodeSize;
+
+    //LOGE("mBccScript %p", script->mBccScript);
+
+    if (bccRegisterSymbolCallback(drv->mBccScript, &rsdLookupRuntimeStub, script) != 0) {
+        LOGE("bcc: FAILS to register symbol callback");
+        goto error;
+    }
+
+    if (bccReadBC(drv->mBccScript,
+                  resName,
+                  (char const *)drv->mScriptText,
+                  drv->mScriptTextLength, 0) != 0) {
+        LOGE("bcc: FAILS to read bitcode");
+        goto error;
+    }
+
+#if 1
+    if (bccLinkFile(drv->mBccScript, "/system/lib/libclcore.bc", 0) != 0) {
+        LOGE("bcc: FAILS to link bitcode");
+        goto error;
+    }
+#endif
+    cachePath = genCacheFileName(cacheDir, resName, ".oBCC");
+
+    if (bccPrepareExecutable(drv->mBccScript, cachePath, 0) != 0) {
+        LOGE("bcc: FAILS to prepare executable");
+        goto error;
+    }
+
+    free(cachePath);
+
+    drv->mRoot = reinterpret_cast<int (*)()>(bccGetFuncAddr(drv->mBccScript, "root"));
+    drv->mInit = reinterpret_cast<void (*)()>(bccGetFuncAddr(drv->mBccScript, "init"));
+
+    drv->mInvokeFunctionCount = bccGetExportFuncCount(drv->mBccScript);
+    if (drv->mInvokeFunctionCount <= 0)
+        drv->mInvokeFunctions = NULL;
+    else {
+        drv->mInvokeFunctions = (InvokeFunc_t*) calloc(drv->mInvokeFunctionCount, sizeof(InvokeFunc_t));
+        bccGetExportFuncList(drv->mBccScript, drv->mInvokeFunctionCount, (void **) drv->mInvokeFunctions);
+    }
+
+    drv->mFieldCount = bccGetExportVarCount(drv->mBccScript);
+    if (drv->mFieldCount <= 0) {
+        drv->mFieldAddress = NULL;
+        drv->mFieldIsObject = NULL;
+    } else {
+        drv->mFieldAddress = (void **) calloc(drv->mFieldCount, sizeof(void *));
+        drv->mFieldIsObject = (bool *) calloc(drv->mFieldCount, sizeof(bool));
+        bccGetExportVarList(drv->mBccScript, drv->mFieldCount, (void **) drv->mFieldAddress);
+    }
+
+    objectSlotCount = bccGetObjectSlotCount(drv->mBccScript);
+    if (objectSlotCount) {
+        uint32_t * slots = new uint32_t[objectSlotCount];
+        bccGetObjectSlotList(drv->mBccScript, objectSlotCount, slots);
+        for (uint32_t ct=0; ct < objectSlotCount; ct++) {
+            drv->mFieldIsObject[slots[ct]] = true;
+        }
+        delete [] slots;
+    }
+
+    uint32_t mPragmaCount;
+    const char ** mPragmaKeys;
+    const char ** mPragmaValues;
+
+    const static int pragmaMax = 16;
+    drv->mPragmaCount = bccGetPragmaCount(drv->mBccScript);
+    if (drv->mPragmaCount <= 0) {
+        drv->mPragmaKeys = NULL;
+        drv->mPragmaValues = NULL;
+    } else {
+        drv->mPragmaKeys = (const char **) calloc(drv->mFieldCount, sizeof(const char *));
+        drv->mPragmaValues = (const char **) calloc(drv->mFieldCount, sizeof(const char *));
+        bccGetPragmaList(drv->mBccScript, drv->mPragmaCount, drv->mPragmaKeys, drv->mPragmaValues);
+    }
+
+
+
+    // Copy info over to runtime
+    script->mHal.info.exportedFunctionCount = drv->mInvokeFunctionCount;
+    script->mHal.info.exportedVariableCount = drv->mFieldCount;
+    script->mHal.info.exportedPragmaCount = drv->mPragmaCount;
+    script->mHal.info.exportedPragmaKeyList = drv->mPragmaKeys;
+    script->mHal.info.exportedPragmaValueList = drv->mPragmaValues;
+    script->mHal.info.root = drv->mRoot;
+
+
+    pthread_mutex_unlock(&rsdgInitMutex);
+    return true;
+
+error:
+
+    pthread_mutex_unlock(&rsdgInitMutex);
+    free(drv);
+    return false;
+
+}
+
+typedef struct {
+    Context *rsc;
+    Script *script;
+    const Allocation * ain;
+    Allocation * aout;
+    const void * usr;
+
+    uint32_t mSliceSize;
+    volatile int mSliceNum;
+
+    const uint8_t *ptrIn;
+    uint32_t eStrideIn;
+    uint8_t *ptrOut;
+    uint32_t eStrideOut;
+
+    uint32_t xStart;
+    uint32_t xEnd;
+    uint32_t yStart;
+    uint32_t yEnd;
+    uint32_t zStart;
+    uint32_t zEnd;
+    uint32_t arrayStart;
+    uint32_t arrayEnd;
+
+    uint32_t dimX;
+    uint32_t dimY;
+    uint32_t dimZ;
+    uint32_t dimArray;
+} MTLaunchStruct;
+typedef int (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
+
+static void wc_xy(void *usr, uint32_t idx) {
+    MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
+
+    while (1) {
+        uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
+        uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
+        uint32_t yEnd = yStart + mtls->mSliceSize;
+        yEnd = rsMin(yEnd, mtls->yEnd);
+        if (yEnd <= yStart) {
+            return;
+        }
+
+        //LOGE("usr idx %i, x %i,%i  y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
+        //LOGE("usr ptr in %p,  out %p", mtls->ptrIn, mtls->ptrOut);
+        for (uint32_t y = yStart; y < yEnd; y++) {
+            uint32_t offset = mtls->dimX * y;
+            uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * offset);
+            const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * offset);
+
+            for (uint32_t x = mtls->xStart; x < mtls->xEnd; x++) {
+                ((rs_t)mtls->script->mHal.info.root) (xPtrIn, xPtrOut, mtls->usr, x, y, 0, 0);
+                xPtrIn += mtls->eStrideIn;
+                xPtrOut += mtls->eStrideOut;
+            }
+        }
+    }
+}
+
+static void wc_x(void *usr, uint32_t idx) {
+    MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
+
+    while (1) {
+        uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
+        uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize;
+        uint32_t xEnd = xStart + mtls->mSliceSize;
+        xEnd = rsMin(xEnd, mtls->xEnd);
+        if (xEnd <= xStart) {
+            return;
+        }
+
+        //LOGE("usr idx %i, x %i,%i  y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
+        //LOGE("usr ptr in %p,  out %p", mtls->ptrIn, mtls->ptrOut);
+        uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * xStart);
+        const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * xStart);
+        for (uint32_t x = xStart; x < xEnd; x++) {
+            ((rs_t)mtls->script->mHal.info.root) (xPtrIn, xPtrOut, mtls->usr, x, 0, 0, 0);
+            xPtrIn += mtls->eStrideIn;
+            xPtrOut += mtls->eStrideOut;
+        }
+    }
+}
+
+void rsdScriptInvokeForEach(const Context *rsc,
+                            Script *s,
+                            const Allocation * ain,
+                            Allocation * aout,
+                            const void * usr,
+                            uint32_t usrLen,
+                            const RsScriptCall *sc) {
+
+    RsdHal * dc = (RsdHal *)rsc->mHal.drv;
+
+    MTLaunchStruct mtls;
+    memset(&mtls, 0, sizeof(mtls));
+
+    if (ain) {
+        mtls.dimX = ain->getType()->getDimX();
+        mtls.dimY = ain->getType()->getDimY();
+        mtls.dimZ = ain->getType()->getDimZ();
+        //mtls.dimArray = ain->getType()->getDimArray();
+    } else if (aout) {
+        mtls.dimX = aout->getType()->getDimX();
+        mtls.dimY = aout->getType()->getDimY();
+        mtls.dimZ = aout->getType()->getDimZ();
+        //mtls.dimArray = aout->getType()->getDimArray();
+    } else {
+        rsc->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
+        return;
+    }
+
+    if (!sc || (sc->xEnd == 0)) {
+        mtls.xEnd = mtls.dimX;
+    } else {
+        rsAssert(sc->xStart < mtls.dimX);
+        rsAssert(sc->xEnd <= mtls.dimX);
+        rsAssert(sc->xStart < sc->xEnd);
+        mtls.xStart = rsMin(mtls.dimX, sc->xStart);
+        mtls.xEnd = rsMin(mtls.dimX, sc->xEnd);
+        if (mtls.xStart >= mtls.xEnd) return;
+    }
+
+    if (!sc || (sc->yEnd == 0)) {
+        mtls.yEnd = mtls.dimY;
+    } else {
+        rsAssert(sc->yStart < mtls.dimY);
+        rsAssert(sc->yEnd <= mtls.dimY);
+        rsAssert(sc->yStart < sc->yEnd);
+        mtls.yStart = rsMin(mtls.dimY, sc->yStart);
+        mtls.yEnd = rsMin(mtls.dimY, sc->yEnd);
+        if (mtls.yStart >= mtls.yEnd) return;
+    }
+
+    mtls.xEnd = rsMax((uint32_t)1, mtls.xEnd);
+    mtls.yEnd = rsMax((uint32_t)1, mtls.yEnd);
+    mtls.zEnd = rsMax((uint32_t)1, mtls.zEnd);
+    mtls.arrayEnd = rsMax((uint32_t)1, mtls.arrayEnd);
+
+    rsAssert(!ain || (ain->getType()->getDimZ() == 0));
+
+    Context *mrsc = (Context *)rsc;
+    Script * oldTLS = setTLS(s);
+
+    mtls.rsc = mrsc;
+    mtls.ain = ain;
+    mtls.aout = aout;
+    mtls.script = s;
+    mtls.usr = usr;
+    mtls.mSliceSize = 10;
+    mtls.mSliceNum = 0;
+
+    mtls.ptrIn = NULL;
+    mtls.eStrideIn = 0;
+    if (ain) {
+        mtls.ptrIn = (const uint8_t *)ain->getPtr();
+        mtls.eStrideIn = ain->getType()->getElementSizeBytes();
+    }
+
+    mtls.ptrOut = NULL;
+    mtls.eStrideOut = 0;
+    if (aout) {
+        mtls.ptrOut = (uint8_t *)aout->getPtr();
+        mtls.eStrideOut = aout->getType()->getElementSizeBytes();
+    }
+
+    if ((dc->mWorkers.mCount > 1) && s->mHal.info.isThreadable) {
+        if (mtls.dimY > 1) {
+            rsdLaunchThreads(mrsc, wc_xy, &mtls);
+        } else {
+            rsdLaunchThreads(mrsc, wc_x, &mtls);
+        }
+
+        //LOGE("launch 1");
+    } else {
+        //LOGE("launch 3");
+        for (uint32_t ar = mtls.arrayStart; ar < mtls.arrayEnd; ar++) {
+            for (uint32_t z = mtls.zStart; z < mtls.zEnd; z++) {
+                for (uint32_t y = mtls.yStart; y < mtls.yEnd; y++) {
+                    uint32_t offset = mtls.dimX * mtls.dimY * mtls.dimZ * ar +
+                                      mtls.dimX * mtls.dimY * z +
+                                      mtls.dimX * y;
+                    uint8_t *xPtrOut = mtls.ptrOut + (mtls.eStrideOut * offset);
+                    const uint8_t *xPtrIn = mtls.ptrIn + (mtls.eStrideIn * offset);
+
+                    for (uint32_t x = mtls.xStart; x < mtls.xEnd; x++) {
+                        ((rs_t)s->mHal.info.root) (xPtrIn, xPtrOut, usr, x, y, z, ar);
+                        xPtrIn += mtls.eStrideIn;
+                        xPtrOut += mtls.eStrideOut;
+                    }
+                }
+            }
+        }
+    }
+
+    setTLS(oldTLS);
+}
+
+
+int rsdScriptInvokeRoot(const Context *dc, Script *script) {
+    DrvScript *drv = (DrvScript *)script->mHal.drv;
+
+    Script * oldTLS = setTLS(script);
+    int ret = drv->mRoot();
+    setTLS(oldTLS);
+
+    return ret;
+}
+
+void rsdScriptInvokeInit(const Context *dc, Script *script) {
+    DrvScript *drv = (DrvScript *)script->mHal.drv;
+
+    if (drv->mInit) {
+        drv->mInit();
+    }
+}
+
+
+void rsdScriptInvokeFunction(const Context *dc, Script *script,
+                            uint32_t slot,
+                            const void *params,
+                            size_t paramLength) {
+    DrvScript *drv = (DrvScript *)script->mHal.drv;
+    //LOGE("invoke %p %p %i %p %i", dc, script, slot, params, paramLength);
+
+    Script * oldTLS = setTLS(script);
+    ((void (*)(const void *, uint32_t))
+        drv->mInvokeFunctions[slot])(params, paramLength);
+    setTLS(oldTLS);
+}
+
+void rsdScriptSetGlobalVar(const Context *dc, const Script *script,
+                           uint32_t slot, void *data, size_t dataLength) {
+    DrvScript *drv = (DrvScript *)script->mHal.drv;
+    //rsAssert(!script->mFieldIsObject[slot]);
+    //LOGE("setGlobalVar %p %p %i %p %i", dc, script, slot, data, dataLength);
+
+    int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
+    if (!destPtr) {
+        //LOGV("Calling setVar on slot = %i which is null", slot);
+        return;
+    }
+
+    memcpy(destPtr, data, dataLength);
+}
+
+void rsdScriptSetGlobalBind(const Context *dc, const Script *script, uint32_t slot, void *data) {
+    DrvScript *drv = (DrvScript *)script->mHal.drv;
+    //rsAssert(!script->mFieldIsObject[slot]);
+    //LOGE("setGlobalBind %p %p %i %p", dc, script, slot, data);
+
+    int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
+    if (!destPtr) {
+        //LOGV("Calling setVar on slot = %i which is null", slot);
+        return;
+    }
+
+    memcpy(destPtr, &data, sizeof(void *));
+}
+
+void rsdScriptSetGlobalObj(const Context *dc, const Script *script, uint32_t slot, ObjectBase *data) {
+    DrvScript *drv = (DrvScript *)script->mHal.drv;
+    //rsAssert(script->mFieldIsObject[slot]);
+    //LOGE("setGlobalObj %p %p %i %p", dc, script, slot, data);
+
+    int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
+    if (!destPtr) {
+        //LOGV("Calling setVar on slot = %i which is null", slot);
+        return;
+    }
+
+    rsrSetObject(dc, script, (ObjectBase **)destPtr, data);
+}
+
+void rsdScriptDestroy(const Context *dc, Script *script) {
+    DrvScript *drv = (DrvScript *)script->mHal.drv;
+
+    if (drv->mFieldAddress) {
+        for (size_t ct=0; ct < drv->mFieldCount; ct++) {
+            if (drv->mFieldIsObject[ct]) {
+                // The field address can be NULL if the script-side has
+                // optimized the corresponding global variable away.
+                if (drv->mFieldAddress[ct]) {
+                    rsrClearObject(dc, script, (ObjectBase **)drv->mFieldAddress[ct]);
+                }
+            }
+        }
+        delete [] drv->mFieldAddress;
+        delete [] drv->mFieldIsObject;
+        drv->mFieldAddress = NULL;
+        drv->mFieldIsObject = NULL;
+        drv->mFieldCount = 0;
+    }
+
+    if (drv->mInvokeFunctions) {
+        delete [] drv->mInvokeFunctions;
+        drv->mInvokeFunctions = NULL;
+        drv->mInvokeFunctionCount = 0;
+    }
+    free(drv);
+    script->mHal.drv = NULL;
+
+}
+
+
diff --git a/driver/rsdBcc.h b/driver/rsdBcc.h
new file mode 100644
index 0000000..62b50f4
--- /dev/null
+++ b/driver/rsdBcc.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_BCC_H
+#define RSD_BCC_H
+
+#include <rs_hal.h>
+#include <rsRuntime.h>
+
+
+bool rsdScriptInit(const android::renderscript::Context *, android::renderscript::ScriptC *,
+                   char const *resName, char const *cacheDir,
+                   uint8_t const *bitcode, size_t bitcodeSize, uint32_t flags);
+void rsdScriptInvokeFunction(const android::renderscript::Context *dc,
+                             android::renderscript::Script *script,
+                             uint32_t slot,
+                             const void *params,
+                             size_t paramLength);
+
+void rsdScriptInvokeForEach(const android::renderscript::Context *rsc,
+                            android::renderscript::Script *s,
+                            const android::renderscript::Allocation * ain,
+                            android::renderscript::Allocation * aout,
+                            const void * usr,
+                            uint32_t usrLen,
+                            const RsScriptCall *sc);
+
+int rsdScriptInvokeRoot(const android::renderscript::Context *dc,
+                        android::renderscript::Script *script);
+void rsdScriptInvokeInit(const android::renderscript::Context *dc,
+                         android::renderscript::Script *script);
+
+void rsdScriptSetGlobalVar(const android::renderscript::Context *,
+                           const android::renderscript::Script *,
+                           uint32_t slot, void *data, size_t dataLen);
+void rsdScriptSetGlobalBind(const android::renderscript::Context *,
+                            const android::renderscript::Script *,
+                            uint32_t slot, void *data);
+void rsdScriptSetGlobalObj(const android::renderscript::Context *,
+                           const android::renderscript::Script *,
+                           uint32_t slot, android::renderscript::ObjectBase *data);
+
+void rsdScriptSetGlobal(const android::renderscript::Context *dc,
+                        const android::renderscript::Script *script,
+                        uint32_t slot,
+                        void *data,
+                        size_t dataLength);
+void rsdScriptGetGlobal(const android::renderscript::Context *dc,
+                        const android::renderscript::Script *script,
+                        uint32_t slot,
+                        void *data,
+                        size_t dataLength);
+void rsdScriptDestroy(const android::renderscript::Context *dc,
+                      android::renderscript::Script *script);
+
+
+#endif
diff --git a/driver/rsdCore.cpp b/driver/rsdCore.cpp
new file mode 100644
index 0000000..7ef9c30
--- /dev/null
+++ b/driver/rsdCore.cpp
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2011 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 "rsdCore.h"
+#include "rsdBcc.h"
+#include "rsdGL.h"
+#include "rsdProgramStore.h"
+#include "rsdProgramRaster.h"
+#include "rsdProgramVertex.h"
+#include "rsdProgramFragment.h"
+#include "rsdMesh.h"
+#include "rsdSampler.h"
+#include "rsdFrameBuffer.h"
+
+#include <malloc.h>
+#include "rsContext.h"
+
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sched.h>
+#include <cutils/properties.h>
+#include <cutils/sched_policy.h>
+#include <sys/syscall.h>
+#include <string.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+static void Shutdown(Context *rsc);
+static void SetPriority(const Context *rsc, int32_t priority);
+
+static RsdHalFunctions FunctionTable = {
+    rsdGLInit,
+    rsdGLShutdown,
+    rsdGLSetSurface,
+    rsdGLSwap,
+
+    Shutdown,
+    NULL,
+    SetPriority,
+    {
+        rsdScriptInit,
+        rsdScriptInvokeFunction,
+        rsdScriptInvokeRoot,
+        rsdScriptInvokeForEach,
+        rsdScriptInvokeInit,
+        rsdScriptSetGlobalVar,
+        rsdScriptSetGlobalBind,
+        rsdScriptSetGlobalObj,
+        rsdScriptDestroy
+    },
+
+
+    {
+        rsdProgramStoreInit,
+        rsdProgramStoreSetActive,
+        rsdProgramStoreDestroy
+    },
+
+    {
+        rsdProgramRasterInit,
+        rsdProgramRasterSetActive,
+        rsdProgramRasterDestroy
+    },
+
+    {
+        rsdProgramVertexInit,
+        rsdProgramVertexSetActive,
+        rsdProgramVertexDestroy
+    },
+
+    {
+        rsdProgramFragmentInit,
+        rsdProgramFragmentSetActive,
+        rsdProgramFragmentDestroy
+    },
+
+    {
+        rsdMeshInit,
+        rsdMeshDraw,
+        rsdMeshDestroy
+    },
+
+    {
+        rsdSamplerInit,
+        rsdSamplerDestroy
+    },
+
+    {
+        rsdFrameBufferInit,
+        rsdFrameBufferSetActive,
+        rsdFrameBufferDestroy
+    },
+
+};
+
+pthread_key_t rsdgThreadTLSKey = 0;
+uint32_t rsdgThreadTLSKeyCount = 0;
+pthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER;
+
+
+static void * HelperThreadProc(void *vrsc) {
+    Context *rsc = static_cast<Context *>(vrsc);
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+
+    uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
+
+    //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
+
+    dc->mWorkers.mLaunchSignals[idx].init();
+    dc->mWorkers.mNativeThreadId[idx] = gettid();
+
+    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
+    if (status) {
+        LOGE("pthread_setspecific %i", status);
+    }
+
+#if 0
+    typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
+    cpu_set_t cpuset;
+    memset(&cpuset, 0, sizeof(cpuset));
+    cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
+    int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
+              sizeof(cpuset), &cpuset);
+    LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
+#endif
+
+    while (!dc->mExit) {
+        dc->mWorkers.mLaunchSignals[idx].wait();
+        if (dc->mWorkers.mLaunchCallback) {
+           dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx);
+        }
+        android_atomic_dec(&dc->mWorkers.mRunningCount);
+        dc->mWorkers.mCompleteSignal.set();
+    }
+
+    //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
+    return NULL;
+}
+
+void rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+    dc->mWorkers.mLaunchData = data;
+    dc->mWorkers.mLaunchCallback = cbk;
+    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
+    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
+        dc->mWorkers.mLaunchSignals[ct].set();
+    }
+    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
+        dc->mWorkers.mCompleteSignal.wait();
+    }
+}
+
+bool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) {
+    rsc->mHal.funcs = FunctionTable;
+
+    RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal));
+    if (!dc) {
+        LOGE("Calloc for driver hal failed.");
+        return false;
+    }
+    rsc->mHal.drv = dc;
+
+    pthread_mutex_lock(&rsdgInitMutex);
+    if (!rsdgThreadTLSKeyCount) {
+        int status = pthread_key_create(&rsdgThreadTLSKey, NULL);
+        if (status) {
+            LOGE("Failed to init thread tls key.");
+            pthread_mutex_unlock(&rsdgInitMutex);
+            return false;
+        }
+    }
+    rsdgThreadTLSKeyCount++;
+    pthread_mutex_unlock(&rsdgInitMutex);
+
+    dc->mTlsStruct.mContext = rsc;
+    dc->mTlsStruct.mScript = NULL;
+    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
+    if (status) {
+        LOGE("pthread_setspecific %i", status);
+    }
+
+
+    int cpu = sysconf(_SC_NPROCESSORS_ONLN);
+    LOGV("RS Launching thread(s), reported CPU count %i", cpu);
+    if (cpu < 2) cpu = 0;
+
+    dc->mWorkers.mCount = (uint32_t)cpu;
+    dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
+    dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
+    dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
+    dc->mWorkers.mLaunchCallback = NULL;
+
+    dc->mWorkers.mCompleteSignal.init();
+
+    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
+    android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
+
+    pthread_attr_t threadAttr;
+    status = pthread_attr_init(&threadAttr);
+    if (status) {
+        LOGE("Failed to init thread attribute.");
+        return false;
+    }
+
+    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
+        status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
+        if (status) {
+            dc->mWorkers.mCount = ct;
+            LOGE("Created fewer than expected number of RS threads.");
+            break;
+        }
+    }
+    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
+        usleep(100);
+    }
+
+    pthread_attr_destroy(&threadAttr);
+    return true;
+}
+
+
+void SetPriority(const Context *rsc, int32_t priority) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
+        setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
+    }
+}
+
+void Shutdown(Context *rsc) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+    dc->mExit = true;
+    dc->mWorkers.mLaunchData = NULL;
+    dc->mWorkers.mLaunchCallback = NULL;
+    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
+    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
+        dc->mWorkers.mLaunchSignals[ct].set();
+    }
+    int status;
+    void *res;
+    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
+        status = pthread_join(dc->mWorkers.mThreadId[ct], &res);
+    }
+    rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
+
+    // Global structure cleanup.
+    pthread_mutex_lock(&rsdgInitMutex);
+    --rsdgThreadTLSKeyCount;
+    if (!rsdgThreadTLSKeyCount) {
+        pthread_key_delete(rsdgThreadTLSKey);
+    }
+    pthread_mutex_unlock(&rsdgInitMutex);
+
+}
+
+
diff --git a/driver/rsdCore.h b/driver/rsdCore.h
new file mode 100644
index 0000000..422bb1b
--- /dev/null
+++ b/driver/rsdCore.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_CORE_H
+#define RSD_CORE_H
+
+#include <rs_hal.h>
+#include <bcc/bcc.h>
+
+#include "rsMutex.h"
+#include "rsSignal.h"
+
+#include "rsdGL.h"
+
+typedef void (* InvokeFunc_t)(void);
+typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
+
+typedef struct RsdSymbolTableRec {
+    const char * mName;
+    void * mPtr;
+    bool threadable;
+} RsdSymbolTable;
+
+typedef struct ScriptTLSStructRec {
+    android::renderscript::Context * mContext;
+    android::renderscript::Script * mScript;
+} ScriptTLSStruct;
+
+typedef struct RsdHalRec {
+    uint32_t version_major;
+    uint32_t version_minor;
+
+    struct Workers {
+        volatile int mRunningCount;
+        volatile int mLaunchCount;
+        uint32_t mCount;
+        pthread_t *mThreadId;
+        pid_t *mNativeThreadId;
+        android::renderscript::Signal mCompleteSignal;
+
+        android::renderscript::Signal *mLaunchSignals;
+        WorkerCallback_t mLaunchCallback;
+        void *mLaunchData;
+    };
+    Workers mWorkers;
+    bool mExit;
+
+    ScriptTLSStruct mTlsStruct;
+
+    RsdGL gl;
+} RsdHal;
+
+extern pthread_key_t rsdgThreadTLSKey;
+extern uint32_t rsdgThreadTLSKeyCount;
+extern pthread_mutex_t rsdgInitMutex;
+
+
+void rsdLaunchThreads(android::renderscript::Context *rsc, WorkerCallback_t cbk, void *data);
+
+#endif
+
diff --git a/driver/rsdFrameBuffer.cpp b/driver/rsdFrameBuffer.cpp
new file mode 100644
index 0000000..6a7dac4
--- /dev/null
+++ b/driver/rsdFrameBuffer.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2011 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 "rsdCore.h"
+#include "rsdFrameBuffer.h"
+
+#include "rsContext.h"
+#include "rsFBOCache.h"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+struct DrvFrameBuffer {
+    GLuint mFBOId;
+};
+
+void checkError(const Context *rsc) {
+    GLenum status;
+    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    switch (status) {
+    case GL_FRAMEBUFFER_COMPLETE:
+        break;
+    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+        rsc->setError(RS_ERROR_BAD_VALUE,
+                      "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT");
+        break;
+    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+        rsc->setError(RS_ERROR_BAD_VALUE,
+                      "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
+        break;
+    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+        rsc->setError(RS_ERROR_BAD_VALUE,
+                      "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
+        break;
+    case GL_FRAMEBUFFER_UNSUPPORTED:
+        rsc->setError(RS_ERROR_BAD_VALUE,
+                      "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED");
+        break;
+    }
+}
+
+
+void setDepthAttachment(const Context *rsc, const FBOCache *fb) {
+    if (fb->mHal.state.depthTarget.get() != NULL) {
+        if (fb->mHal.state.depthTarget->getIsTexture()) {
+            uint32_t texID = fb->mHal.state.depthTarget->getTextureID();
+            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                   GL_TEXTURE_2D, texID, 0);
+        } else {
+            uint32_t texID = fb->mHal.state.depthTarget->getRenderTargetID();
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                      GL_RENDERBUFFER, texID);
+        }
+    } else {
+        // Reset last attachment
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                  GL_RENDERBUFFER, 0);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                               GL_TEXTURE_2D, 0, 0);
+    }
+}
+
+void setColorAttachment(const Context *rsc, const FBOCache *fb) {
+    // Now attach color targets
+    for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) {
+        uint32_t texID = 0;
+        if (fb->mHal.state.colorTargets[i].get() != NULL) {
+            if (fb->mHal.state.colorTargets[i]->getIsTexture()) {
+                uint32_t texID = fb->mHal.state.colorTargets[i]->getTextureID();
+                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
+                                       GL_TEXTURE_2D, texID, 0);
+            } else {
+                uint32_t texID = fb->mHal.state.depthTarget->getRenderTargetID();
+                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
+                                          GL_RENDERBUFFER, texID);
+            }
+        } else {
+            // Reset last attachment
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
+                                      GL_RENDERBUFFER, 0);
+            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
+                                   GL_TEXTURE_2D, 0, 0);
+        }
+    }
+}
+
+bool renderToFramebuffer(const FBOCache *fb) {
+    if (fb->mHal.state.depthTarget.get() != NULL) {
+        return false;
+    }
+
+    for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) {
+        if (fb->mHal.state.colorTargets[i].get() != NULL) {
+            return false;
+        }
+    }
+    return true;
+}
+
+
+bool rsdFrameBufferInit(const Context *rsc, const FBOCache *fb) {
+    DrvFrameBuffer *drv = (DrvFrameBuffer *)calloc(1, sizeof(DrvFrameBuffer));
+    if (drv == NULL) {
+        return false;
+    }
+    fb->mHal.drv = drv;
+    drv->mFBOId = 0;
+
+    return true;
+}
+
+void rsdFrameBufferSetActive(const Context *rsc, const FBOCache *fb) {
+    DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv;
+
+    bool framebuffer = renderToFramebuffer(fb);
+    if (!framebuffer) {
+        if(drv->mFBOId == 0) {
+            glGenFramebuffers(1, &drv->mFBOId);
+        }
+        glBindFramebuffer(GL_FRAMEBUFFER, drv->mFBOId);
+
+        setDepthAttachment(rsc, fb);
+        setColorAttachment(rsc, fb);
+
+        glViewport(0, 0, fb->mHal.state.colorTargets[0]->getType()->getDimX(),
+                         fb->mHal.state.colorTargets[0]->getType()->getDimY());
+
+        checkError(rsc);
+    } else {
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+        glViewport(0, 0, rsc->getWidth(), rsc->getHeight());
+    }
+}
+
+void rsdFrameBufferDestroy(const Context *rsc, const FBOCache *fb) {
+    DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv;
+    if(drv->mFBOId != 0) {
+        glDeleteFramebuffers(1, &drv->mFBOId);
+    }
+
+    free(fb->mHal.drv);
+    fb->mHal.drv = NULL;
+}
+
+
diff --git a/driver/rsdFrameBuffer.h b/driver/rsdFrameBuffer.h
new file mode 100644
index 0000000..dec59fc
--- /dev/null
+++ b/driver/rsdFrameBuffer.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_FRAME_BUFFER_H
+#define RSD_FRAME_BUFFER_H
+
+#include <rs_hal.h>
+
+bool rsdFrameBufferInit(const android::renderscript::Context *rsc,
+                         const android::renderscript::FBOCache *fb);
+void rsdFrameBufferSetActive(const android::renderscript::Context *rsc,
+                              const android::renderscript::FBOCache *fb);
+void rsdFrameBufferDestroy(const android::renderscript::Context *rsc,
+                            const android::renderscript::FBOCache *fb);
+
+
+#endif // RSD_FRAME_BUFFER_H
diff --git a/driver/rsdGL.cpp b/driver/rsdGL.cpp
new file mode 100644
index 0000000..a70589b
--- /dev/null
+++ b/driver/rsdGL.cpp
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2011 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 <ui/FramebufferNativeWindow.h>
+#include <ui/PixelFormat.h>
+#include <ui/EGLUtils.h>
+#include <ui/egl/android_natives.h>
+
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sched.h>
+
+#include <cutils/properties.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <string.h>
+
+#include "rsdCore.h"
+#include "rsdGL.h"
+
+#include <malloc.h>
+#include "rsContext.h"
+#include "rsdShaderCache.h"
+#include "rsdVertexArray.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+static int32_t gGLContextCount = 0;
+
+static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+    if (returnVal != EGL_TRUE) {
+        fprintf(stderr, "%s() returned %d\n", op, returnVal);
+    }
+
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
+        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
+                error);
+    }
+}
+
+static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
+
+#define X(VAL) {VAL, #VAL}
+    struct {EGLint attribute; const char* name;} names[] = {
+    X(EGL_BUFFER_SIZE),
+    X(EGL_ALPHA_SIZE),
+    X(EGL_BLUE_SIZE),
+    X(EGL_GREEN_SIZE),
+    X(EGL_RED_SIZE),
+    X(EGL_DEPTH_SIZE),
+    X(EGL_STENCIL_SIZE),
+    X(EGL_CONFIG_CAVEAT),
+    X(EGL_CONFIG_ID),
+    X(EGL_LEVEL),
+    X(EGL_MAX_PBUFFER_HEIGHT),
+    X(EGL_MAX_PBUFFER_PIXELS),
+    X(EGL_MAX_PBUFFER_WIDTH),
+    X(EGL_NATIVE_RENDERABLE),
+    X(EGL_NATIVE_VISUAL_ID),
+    X(EGL_NATIVE_VISUAL_TYPE),
+    X(EGL_SAMPLES),
+    X(EGL_SAMPLE_BUFFERS),
+    X(EGL_SURFACE_TYPE),
+    X(EGL_TRANSPARENT_TYPE),
+    X(EGL_TRANSPARENT_RED_VALUE),
+    X(EGL_TRANSPARENT_GREEN_VALUE),
+    X(EGL_TRANSPARENT_BLUE_VALUE),
+    X(EGL_BIND_TO_TEXTURE_RGB),
+    X(EGL_BIND_TO_TEXTURE_RGBA),
+    X(EGL_MIN_SWAP_INTERVAL),
+    X(EGL_MAX_SWAP_INTERVAL),
+    X(EGL_LUMINANCE_SIZE),
+    X(EGL_ALPHA_MASK_SIZE),
+    X(EGL_COLOR_BUFFER_TYPE),
+    X(EGL_RENDERABLE_TYPE),
+    X(EGL_CONFORMANT),
+   };
+#undef X
+
+    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
+        EGLint value = -1;
+        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
+        EGLint error = eglGetError();
+        if (returnVal && error == EGL_SUCCESS) {
+            LOGV(" %s: %d (0x%x)", names[j].name, value, value);
+        }
+    }
+}
+
+static void DumpDebug(RsdHal *dc) {
+    LOGE(" EGL ver %i %i", dc->gl.egl.majorVersion, dc->gl.egl.minorVersion);
+    LOGE(" EGL context %p  surface %p,  Display=%p", dc->gl.egl.context, dc->gl.egl.surface,
+         dc->gl.egl.display);
+    LOGE(" GL vendor: %s", dc->gl.gl.vendor);
+    LOGE(" GL renderer: %s", dc->gl.gl.renderer);
+    LOGE(" GL Version: %s", dc->gl.gl.version);
+    LOGE(" GL Extensions: %s", dc->gl.gl.extensions);
+    LOGE(" GL int Versions %i %i", dc->gl.gl.majorVersion, dc->gl.gl.minorVersion);
+
+    LOGV("MAX Textures %i, %i  %i", dc->gl.gl.maxVertexTextureUnits,
+         dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
+    LOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
+    LOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
+         dc->gl.gl.maxFragmentUniformVectors);
+    LOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
+}
+
+void rsdGLShutdown(const Context *rsc) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+    dc->gl.shaderCache->cleanupAll();
+    delete dc->gl.shaderCache;
+
+    delete dc->gl.vertexArrayState;
+
+    LOGV("%p, deinitEGL", rsc);
+
+    if (dc->gl.egl.context != EGL_NO_CONTEXT) {
+        eglMakeCurrent(dc->gl.egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surfaceDefault);
+        if (dc->gl.egl.surface != EGL_NO_SURFACE) {
+            eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
+        }
+        eglDestroyContext(dc->gl.egl.display, dc->gl.egl.context);
+        checkEglError("eglDestroyContext");
+    }
+
+    gGLContextCount--;
+    if (!gGLContextCount) {
+        eglTerminate(dc->gl.egl.display);
+    }
+}
+
+bool rsdGLInit(const Context *rsc) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+    dc->gl.egl.numConfigs = -1;
+    EGLint configAttribs[128];
+    EGLint *configAttribsPtr = configAttribs;
+    EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+
+    memset(configAttribs, 0, sizeof(configAttribs));
+
+    configAttribsPtr[0] = EGL_SURFACE_TYPE;
+    configAttribsPtr[1] = EGL_WINDOW_BIT;
+    configAttribsPtr += 2;
+
+    configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
+    configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
+    configAttribsPtr += 2;
+
+    if (rsc->mUserSurfaceConfig.depthMin > 0) {
+        configAttribsPtr[0] = EGL_DEPTH_SIZE;
+        configAttribsPtr[1] = rsc->mUserSurfaceConfig.depthMin;
+        configAttribsPtr += 2;
+    }
+
+    if (rsc->mDev->mForceSW) {
+        configAttribsPtr[0] = EGL_CONFIG_CAVEAT;
+        configAttribsPtr[1] = EGL_SLOW_CONFIG;
+        configAttribsPtr += 2;
+    }
+
+    configAttribsPtr[0] = EGL_NONE;
+    rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint))));
+
+    LOGV("%p initEGL start", rsc);
+    dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    checkEglError("eglGetDisplay");
+
+    eglInitialize(dc->gl.egl.display, &dc->gl.egl.majorVersion, &dc->gl.egl.minorVersion);
+    checkEglError("eglInitialize");
+
+    PixelFormat pf = PIXEL_FORMAT_RGBA_8888;
+    if (rsc->mUserSurfaceConfig.alphaMin == 0) {
+        pf = PIXEL_FORMAT_RGBX_8888;
+    }
+
+    status_t err = EGLUtils::selectConfigForPixelFormat(dc->gl.egl.display, configAttribs,
+                                                        pf, &dc->gl.egl.config);
+    if (err) {
+       LOGE("%p, couldn't find an EGLConfig matching the screen format\n", rsc);
+    }
+    //if (props.mLogVisual) {
+    if (0) {
+        printEGLConfiguration(dc->gl.egl.display, dc->gl.egl.config);
+    }
+    //}
+
+    dc->gl.egl.context = eglCreateContext(dc->gl.egl.display, dc->gl.egl.config,
+                                          EGL_NO_CONTEXT, context_attribs2);
+    checkEglError("eglCreateContext");
+    if (dc->gl.egl.context == EGL_NO_CONTEXT) {
+        LOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", rsc);
+        return false;
+    }
+    gGLContextCount++;
+
+
+    EGLint pbuffer_attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
+    dc->gl.egl.surfaceDefault = eglCreatePbufferSurface(dc->gl.egl.display, dc->gl.egl.config,
+                                                        pbuffer_attribs);
+    checkEglError("eglCreatePbufferSurface");
+    if (dc->gl.egl.surfaceDefault == EGL_NO_SURFACE) {
+        LOGE("eglCreatePbufferSurface returned EGL_NO_SURFACE");
+        rsdGLShutdown(rsc);
+        return false;
+    }
+
+    EGLBoolean ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
+                                    dc->gl.egl.surfaceDefault, dc->gl.egl.context);
+    if (ret == EGL_FALSE) {
+        LOGE("eglMakeCurrent returned EGL_FALSE");
+        checkEglError("eglMakeCurrent", ret);
+        rsdGLShutdown(rsc);
+        return false;
+    }
+
+    dc->gl.gl.version = glGetString(GL_VERSION);
+    dc->gl.gl.vendor = glGetString(GL_VENDOR);
+    dc->gl.gl.renderer = glGetString(GL_RENDERER);
+    dc->gl.gl.extensions = glGetString(GL_EXTENSIONS);
+
+    //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
+    //LOGV("GL Version %s", mGL.mVersion);
+    //LOGV("GL Vendor %s", mGL.mVendor);
+    //LOGV("GL Renderer %s", mGL.mRenderer);
+    //LOGV("GL Extensions %s", mGL.mExtensions);
+
+    const char *verptr = NULL;
+    if (strlen((const char *)dc->gl.gl.version) > 9) {
+        if (!memcmp(dc->gl.gl.version, "OpenGL ES-CM", 12)) {
+            verptr = (const char *)dc->gl.gl.version + 12;
+        }
+        if (!memcmp(dc->gl.gl.version, "OpenGL ES ", 10)) {
+            verptr = (const char *)dc->gl.gl.version + 9;
+        }
+    }
+
+    if (!verptr) {
+        LOGE("Error, OpenGL ES Lite not supported");
+        rsdGLShutdown(rsc);
+        return false;
+    } else {
+        sscanf(verptr, " %i.%i", &dc->gl.gl.majorVersion, &dc->gl.gl.minorVersion);
+    }
+
+    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &dc->gl.gl.maxVertexAttribs);
+    glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &dc->gl.gl.maxVertexUniformVectors);
+    glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxVertexTextureUnits);
+
+    glGetIntegerv(GL_MAX_VARYING_VECTORS, &dc->gl.gl.maxVaryingVectors);
+    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxTextureImageUnits);
+
+    glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxFragmentTextureImageUnits);
+    glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &dc->gl.gl.maxFragmentUniformVectors);
+
+    dc->gl.gl.OES_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
+                                                "GL_OES_texture_npot");
+    dc->gl.gl.GL_IMG_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
+                                                   "GL_IMG_texture_npot");
+    dc->gl.gl.GL_NV_texture_npot_2D_mipmap = NULL != strstr((const char *)dc->gl.gl.extensions,
+                                                            "GL_NV_texture_npot_2D_mipmap");
+    dc->gl.gl.EXT_texture_max_aniso = 1.0f;
+    bool hasAniso = NULL != strstr((const char *)dc->gl.gl.extensions,
+                                   "GL_EXT_texture_filter_anisotropic");
+    if (hasAniso) {
+        glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &dc->gl.gl.EXT_texture_max_aniso);
+    }
+
+    if (0) {
+        DumpDebug(dc);
+    }
+
+    dc->gl.shaderCache = new RsdShaderCache();
+    dc->gl.vertexArrayState = new RsdVertexArrayState();
+    dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
+
+    LOGV("initGLThread end %p", rsc);
+    return true;
+}
+
+
+bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+    EGLBoolean ret;
+    // WAR: Some drivers fail to handle 0 size surfaces correcntly.
+    // Use the pbuffer to avoid this pitfall.
+    if ((dc->gl.egl.surface != NULL) || (w == 0) || (h == 0)) {
+        ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
+                             dc->gl.egl.surfaceDefault, dc->gl.egl.context);
+        checkEglError("eglMakeCurrent", ret);
+
+        ret = eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
+        checkEglError("eglDestroySurface", ret);
+
+        dc->gl.egl.surface = NULL;
+        dc->gl.width = 1;
+        dc->gl.height = 1;
+    }
+
+    dc->gl.wndSurface = (ANativeWindow *)sur;
+    if (dc->gl.wndSurface != NULL) {
+        dc->gl.width = w;
+        dc->gl.height = h;
+
+        dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
+                                                    dc->gl.wndSurface, NULL);
+        checkEglError("eglCreateWindowSurface");
+        if (dc->gl.egl.surface == EGL_NO_SURFACE) {
+            LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
+        }
+
+        ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surface,
+                             dc->gl.egl.surface, dc->gl.egl.context);
+        checkEglError("eglMakeCurrent", ret);
+    }
+    return true;
+}
+
+void rsdGLSwap(const android::renderscript::Context *rsc) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+    eglSwapBuffers(dc->gl.egl.display, dc->gl.egl.surface);
+}
+
+void rsdGLCheckError(const android::renderscript::Context *rsc,
+                     const char *msg, bool isFatal) {
+    GLenum err = glGetError();
+    if (err != GL_NO_ERROR) {
+        char buf[1024];
+        snprintf(buf, sizeof(buf), "GL Error = 0x%08x, from: %s", err, msg);
+
+        if (isFatal) {
+            rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
+        } else {
+            switch (err) {
+            case GL_OUT_OF_MEMORY:
+                rsc->setError(RS_ERROR_OUT_OF_MEMORY, buf);
+                break;
+            default:
+                rsc->setError(RS_ERROR_DRIVER, buf);
+                break;
+            }
+        }
+
+        LOGE("%p, %s", rsc, buf);
+    }
+
+}
diff --git a/driver/rsdGL.h b/driver/rsdGL.h
new file mode 100644
index 0000000..01c8438
--- /dev/null
+++ b/driver/rsdGL.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_GL_H
+#define RSD_GL_H
+
+#include <rs_hal.h>
+#include <EGL/egl.h>
+
+class RsdShaderCache;
+class RsdVertexArrayState;
+
+typedef void (* InvokeFunc_t)(void);
+typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
+
+typedef struct RsdGLRec {
+    struct {
+        EGLint numConfigs;
+        EGLint majorVersion;
+        EGLint minorVersion;
+        EGLConfig config;
+        EGLContext context;
+        EGLSurface surface;
+        EGLSurface surfaceDefault;
+        EGLDisplay display;
+    } egl;
+
+    struct {
+        const uint8_t * vendor;
+        const uint8_t * renderer;
+        const uint8_t * version;
+        const uint8_t * extensions;
+
+        uint32_t majorVersion;
+        uint32_t minorVersion;
+
+        int32_t maxVaryingVectors;
+        int32_t maxTextureImageUnits;
+
+        int32_t maxFragmentTextureImageUnits;
+        int32_t maxFragmentUniformVectors;
+
+        int32_t maxVertexAttribs;
+        int32_t maxVertexUniformVectors;
+        int32_t maxVertexTextureUnits;
+
+        bool OES_texture_npot;
+        bool GL_IMG_texture_npot;
+        bool GL_NV_texture_npot_2D_mipmap;
+        float EXT_texture_max_aniso;
+    } gl;
+
+    ANativeWindow *wndSurface;
+    uint32_t width;
+    uint32_t height;
+    RsdShaderCache *shaderCache;
+    RsdVertexArrayState *vertexArrayState;
+} RsdGL;
+
+
+
+bool rsdGLInit(const android::renderscript::Context *rsc);
+void rsdGLShutdown(const android::renderscript::Context *rsc);
+bool rsdGLSetSurface(const android::renderscript::Context *rsc,
+                     uint32_t w, uint32_t h, RsNativeWindow sur);
+void rsdGLSwap(const android::renderscript::Context *rsc);
+void rsdGLCheckError(const android::renderscript::Context *rsc,
+                     const char *msg, bool isFatal = false);
+
+#endif
+
diff --git a/driver/rsdMesh.cpp b/driver/rsdMesh.cpp
new file mode 100644
index 0000000..eb62ddb
--- /dev/null
+++ b/driver/rsdMesh.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <rs_hal.h>
+#include <rsContext.h>
+#include <rsMesh.h>
+
+#include "rsdCore.h"
+#include "rsdMesh.h"
+#include "rsdMeshObj.h"
+#include "rsdShaderCache.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+bool rsdMeshInit(const Context *rsc, const Mesh *m) {
+    RsdMeshObj *drv = NULL;
+    if(m->mHal.drv) {
+        drv = (RsdMeshObj*)m->mHal.drv;
+        delete drv;
+    }
+    drv = new RsdMeshObj(rsc, m);
+    m->mHal.drv = drv;
+    return drv->init();
+}
+
+void rsdMeshDraw(const Context *rsc, const Mesh *m, uint32_t primIndex, uint32_t start, uint32_t len) {
+    if(m->mHal.drv) {
+        RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+        if (!dc->gl.shaderCache->setup(rsc)) {
+            return;
+        }
+
+        RsdMeshObj *drv = (RsdMeshObj*)m->mHal.drv;
+        drv->renderPrimitiveRange(rsc, primIndex, start, len);
+    }
+}
+
+void rsdMeshDestroy(const Context *rsc, const Mesh *m) {
+    if(m->mHal.drv) {
+        RsdMeshObj *drv = (RsdMeshObj*)m->mHal.drv;
+        delete drv;
+    }
+}
+
+
diff --git a/driver/rsdMesh.h b/driver/rsdMesh.h
new file mode 100644
index 0000000..d2714fd
--- /dev/null
+++ b/driver/rsdMesh.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_MESH_H
+#define RSD_MESH_H
+
+#include <rs_hal.h>
+
+
+bool rsdMeshInit(const android::renderscript::Context *rsc,
+                 const android::renderscript::Mesh *m);
+void rsdMeshDraw(const android::renderscript::Context *rsc,
+                 const android::renderscript::Mesh *m,
+                 uint32_t primIndex, uint32_t start, uint32_t len);
+void rsdMeshDestroy(const android::renderscript::Context *rsc,
+                    const android::renderscript::Mesh *m);
+
+
+#endif
diff --git a/driver/rsdMeshObj.cpp b/driver/rsdMeshObj.cpp
new file mode 100644
index 0000000..2c07784
--- /dev/null
+++ b/driver/rsdMeshObj.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2011 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 <GLES/gl.h>
+#include <GLES2/gl2.h>
+#include <GLES/glext.h>
+
+#include <rs_hal.h>
+#include <rsContext.h>
+#include <rsMesh.h>
+
+#include "rsdMeshObj.h"
+#include "rsdGL.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+RsdMeshObj::RsdMeshObj(const Context *rsc, const Mesh *rsMesh) {
+    mRSMesh = rsMesh;
+
+    mAttribs = NULL;
+    mAttribAllocationIndex = NULL;
+    mGLPrimitives = NULL;
+
+    mAttribCount = 0;
+}
+
+RsdMeshObj::~RsdMeshObj() {
+    if (mAttribs) {
+        delete[] mAttribs;
+        delete[] mAttribAllocationIndex;
+    }
+    if (mGLPrimitives) {
+        delete[] mGLPrimitives;
+    }
+}
+
+bool RsdMeshObj::isValidGLComponent(const Element *elem, uint32_t fieldIdx) {
+    // Do not create attribs for padding
+    if (elem->getFieldName(fieldIdx)[0] == '#') {
+        return false;
+    }
+
+    // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted.
+    // Filter rs types accordingly
+    RsDataType dt = elem->getField(fieldIdx)->getComponent().getType();
+    if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 &&
+        dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 &&
+        dt != RS_TYPE_SIGNED_16) {
+        return false;
+    }
+
+    // Now make sure they are not arrays
+    uint32_t arraySize = elem->getFieldArraySize(fieldIdx);
+    if (arraySize != 1) {
+        return false;
+    }
+
+    return true;
+}
+
+bool RsdMeshObj::init() {
+
+    updateGLPrimitives();
+
+    // Count the number of gl attrs to initialize
+    mAttribCount = 0;
+    for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
+        const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
+        for (uint32_t ct=0; ct < elem->getFieldCount(); ct++) {
+            if (isValidGLComponent(elem, ct)) {
+                mAttribCount ++;
+            }
+        }
+    }
+
+    if (mAttribs) {
+        delete [] mAttribs;
+        delete [] mAttribAllocationIndex;
+        mAttribs = NULL;
+        mAttribAllocationIndex = NULL;
+    }
+    if (!mAttribCount) {
+        return false;
+    }
+
+    mAttribs = new RsdVertexArray::Attrib[mAttribCount];
+    mAttribAllocationIndex = new uint32_t[mAttribCount];
+
+    uint32_t userNum = 0;
+    for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
+        const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
+        uint32_t stride = elem->getSizeBytes();
+        for (uint32_t fieldI=0; fieldI < elem->getFieldCount(); fieldI++) {
+            const Component &c = elem->getField(fieldI)->getComponent();
+
+            if (!isValidGLComponent(elem, fieldI)) {
+                continue;
+            }
+
+            mAttribs[userNum].size = c.getVectorSize();
+            mAttribs[userNum].offset = elem->getFieldOffsetBytes(fieldI);
+            mAttribs[userNum].type = c.getGLType();
+            mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
+            mAttribs[userNum].stride = stride;
+            String8 tmp(RS_SHADER_ATTR);
+            tmp.append(elem->getFieldName(fieldI));
+            mAttribs[userNum].name.setTo(tmp.string());
+
+            // Remember which allocation this attribute came from
+            mAttribAllocationIndex[userNum] = ct;
+            userNum ++;
+        }
+    }
+
+    return true;
+}
+
+void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const {
+    if (len < 1 || primIndex >= mRSMesh->mHal.state.primitivesCount || mAttribCount == 0) {
+        LOGE("Invalid mesh or parameters");
+        return;
+    }
+
+    rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange 1");
+    // update attributes with either buffer information or data ptr based on their current state
+    for (uint32_t ct=0; ct < mAttribCount; ct++) {
+        uint32_t allocIndex = mAttribAllocationIndex[ct];
+        Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex].get();
+        if (alloc->getIsBufferObject() && alloc->getBufferObjectID()) {
+            mAttribs[ct].buffer = alloc->getBufferObjectID();
+            mAttribs[ct].ptr = NULL;
+        } else {
+            mAttribs[ct].buffer = 0;
+            mAttribs[ct].ptr = (const uint8_t*)alloc->getPtr();
+        }
+    }
+
+    RsdVertexArray va(mAttribs, mAttribCount);
+    va.setup(rsc);
+
+    rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange 2");
+    Mesh::Primitive_t *prim = mRSMesh->mHal.state.primitives[primIndex];
+    if (prim->mIndexBuffer.get()) {
+        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prim->mIndexBuffer->getBufferObjectID());
+        glDrawElements(mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2));
+    } else {
+        glDrawArrays(mGLPrimitives[primIndex], start, len);
+    }
+
+    rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange");
+}
+
+void RsdMeshObj::updateGLPrimitives() {
+    mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount];
+    for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) {
+        switch (mRSMesh->mHal.state.primitives[i]->mPrimitive) {
+            case RS_PRIMITIVE_POINT:          mGLPrimitives[i] = GL_POINTS; break;
+            case RS_PRIMITIVE_LINE:           mGLPrimitives[i] = GL_LINES; break;
+            case RS_PRIMITIVE_LINE_STRIP:     mGLPrimitives[i] = GL_LINE_STRIP; break;
+            case RS_PRIMITIVE_TRIANGLE:       mGLPrimitives[i] = GL_TRIANGLES; break;
+            case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitives[i] = GL_TRIANGLE_STRIP; break;
+            case RS_PRIMITIVE_TRIANGLE_FAN:   mGLPrimitives[i] = GL_TRIANGLE_FAN; break;
+        }
+    }
+}
diff --git a/driver/rsdMeshObj.h b/driver/rsdMeshObj.h
new file mode 100644
index 0000000..8b1271b
--- /dev/null
+++ b/driver/rsdMeshObj.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RSD_MESH_OBJ_H
+#define ANDROID_RSD_MESH_OBJ_H
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+    class Context;
+    class Mesh;
+    class Element;
+
+}
+}
+
+#include "driver/rsdVertexArray.h"
+
+// An element is a group of Components that occupies one cell in a structure.
+class RsdMeshObj {
+public:
+    RsdMeshObj(const android::renderscript::Context *,
+            const android::renderscript::Mesh *);
+    ~RsdMeshObj();
+
+    void renderPrimitiveRange(const android::renderscript::Context *, uint32_t primIndex, uint32_t start, uint32_t len) const;
+
+    bool init();
+
+protected:
+    const android::renderscript::Mesh *mRSMesh;
+
+    uint32_t *mGLPrimitives;
+    void updateGLPrimitives();
+
+    bool isValidGLComponent(const android::renderscript::Element *elem, uint32_t fieldIdx);
+    // Attribues that allow us to map to GL
+    RsdVertexArray::Attrib *mAttribs;
+    // This allows us to figure out which allocation the attribute
+    // belongs to. In the event the allocation is uploaded to GL
+    // buffer, it lets us properly map it
+    uint32_t *mAttribAllocationIndex;
+    uint32_t mAttribCount;
+};
+
+#endif //ANDROID_RSD_MESH_OBJ_H
+
+
+
diff --git a/driver/rsdProgram.cpp b/driver/rsdProgram.cpp
new file mode 100644
index 0000000..502c5ee
--- /dev/null
+++ b/driver/rsdProgram.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 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 "rsdCore.h"
+#include "rsdProgramVertex.h"
+#include "rsdShader.h"
+#include "rsdShaderCache.h"
+
+#include "rsContext.h"
+#include "rsProgramVertex.h"
+#include "rsProgramFragment.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+bool rsdProgramVertexInit(const Context *rsc, const ProgramVertex *pv,
+                          const char* shader, uint32_t shaderLen) {
+    RsdShader *drv = new RsdShader(pv, GL_VERTEX_SHADER, shader, shaderLen);
+    pv->mHal.drv = drv;
+
+    return drv->createShader();
+}
+
+void rsdProgramVertexSetActive(const Context *rsc, const ProgramVertex *pv) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+    dc->gl.shaderCache->setActiveVertex((RsdShader*)pv->mHal.drv);
+}
+
+void rsdProgramVertexDestroy(const Context *rsc, const ProgramVertex *pv) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+    RsdShader *drv = NULL;
+    if(pv->mHal.drv) {
+        drv = (RsdShader*)pv->mHal.drv;
+        if (rsc->props.mLogShaders) {
+            LOGV("Destroying vertex shader with ID %u", drv->getShaderID());
+        }
+        if (drv->getShaderID()) {
+            dc->gl.shaderCache->cleanupVertex(drv->getShaderID());
+        }
+        delete drv;
+    }
+}
+
+bool rsdProgramFragmentInit(const Context *rsc, const ProgramFragment *pf,
+                          const char* shader, uint32_t shaderLen) {
+    RsdShader *drv = new RsdShader(pf, GL_FRAGMENT_SHADER, shader, shaderLen);
+    pf->mHal.drv = drv;
+
+    return drv->createShader();
+}
+
+void rsdProgramFragmentSetActive(const Context *rsc, const ProgramFragment *pf) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+    dc->gl.shaderCache->setActiveFragment((RsdShader*)pf->mHal.drv);
+}
+
+void rsdProgramFragmentDestroy(const Context *rsc, const ProgramFragment *pf) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+    RsdShader *drv = NULL;
+    if(pf->mHal.drv) {
+        drv = (RsdShader*)pf->mHal.drv;
+        if (rsc->props.mLogShaders) {
+            LOGV("Destroying fragment shader with ID %u", drv->getShaderID());
+        }
+        if (drv->getShaderID()) {
+            dc->gl.shaderCache->cleanupFragment(drv->getShaderID());
+        }
+        delete drv;
+    }
+}
+
+
diff --git a/driver/rsdProgramFragment.h b/driver/rsdProgramFragment.h
new file mode 100644
index 0000000..366cb40
--- /dev/null
+++ b/driver/rsdProgramFragment.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_PROGRAM_FRAGMENT_H
+#define RSD_PROGRAM_FRAGMENT_H
+
+#include <rs_hal.h>
+
+
+bool rsdProgramFragmentInit(const android::renderscript::Context *rsc,
+                            const android::renderscript::ProgramFragment *,
+                            const char* shader, uint32_t shaderLen);
+void rsdProgramFragmentSetActive(const android::renderscript::Context *rsc,
+                                 const android::renderscript::ProgramFragment *);
+void rsdProgramFragmentDestroy(const android::renderscript::Context *rsc,
+                               const android::renderscript::ProgramFragment *);
+
+
+#endif //RSD_PROGRAM_Fragment_H
diff --git a/driver/rsdProgramRaster.cpp b/driver/rsdProgramRaster.cpp
new file mode 100644
index 0000000..65995be
--- /dev/null
+++ b/driver/rsdProgramRaster.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 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 "rsdCore.h"
+#include "rsdProgramStore.h"
+
+#include "rsContext.h"
+#include "rsProgramStore.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+
+using namespace android;
+using namespace android::renderscript;
+
+bool rsdProgramRasterInit(const Context *, const ProgramRaster *) {
+    return true;
+}
+
+void rsdProgramRasterSetActive(const Context *, const ProgramRaster *pr) {
+    switch (pr->mHal.state.cull) {
+        case RS_CULL_BACK:
+            glEnable(GL_CULL_FACE);
+            glCullFace(GL_BACK);
+            break;
+        case RS_CULL_FRONT:
+            glEnable(GL_CULL_FACE);
+            glCullFace(GL_FRONT);
+            break;
+        case RS_CULL_NONE:
+            glDisable(GL_CULL_FACE);
+            break;
+    }
+
+}
+
+void rsdProgramRasterDestroy(const Context *, const ProgramRaster *) {
+}
+
+
diff --git a/driver/rsdProgramRaster.h b/driver/rsdProgramRaster.h
new file mode 100644
index 0000000..20adaad
--- /dev/null
+++ b/driver/rsdProgramRaster.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_PROGRAM_RASTER_H
+#define RSD_PROGRAM_RASTER_H
+
+#include <rs_hal.h>
+
+
+bool rsdProgramRasterInit(const android::renderscript::Context *rsc,
+                         const android::renderscript::ProgramRaster *);
+void rsdProgramRasterSetActive(const android::renderscript::Context *rsc,
+                              const android::renderscript::ProgramRaster *);
+void rsdProgramRasterDestroy(const android::renderscript::Context *rsc,
+                            const android::renderscript::ProgramRaster *);
+
+
+#endif
diff --git a/driver/rsdProgramStore.cpp b/driver/rsdProgramStore.cpp
new file mode 100644
index 0000000..e591453
--- /dev/null
+++ b/driver/rsdProgramStore.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2011 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 "rsdCore.h"
+#include "rsdProgramStore.h"
+
+#include "rsContext.h"
+#include "rsProgramStore.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+
+using namespace android;
+using namespace android::renderscript;
+
+struct DrvProgramStore {
+    GLenum blendSrc;
+    GLenum blendDst;
+    bool blendEnable;
+
+    GLenum depthFunc;
+    bool depthTestEnable;
+};
+
+bool rsdProgramStoreInit(const Context *rsc, const ProgramStore *ps) {
+    DrvProgramStore *drv = (DrvProgramStore *)calloc(1, sizeof(DrvProgramStore));
+    if (drv == NULL) {
+        return false;
+    }
+
+    ps->mHal.drv = drv;
+    drv->depthTestEnable = true;
+
+    switch (ps->mHal.state.depthFunc) {
+    case RS_DEPTH_FUNC_ALWAYS:
+        drv->depthTestEnable = false;
+        drv->depthFunc = GL_ALWAYS;
+        break;
+    case RS_DEPTH_FUNC_LESS:
+        drv->depthFunc = GL_LESS;
+        break;
+    case RS_DEPTH_FUNC_LEQUAL:
+        drv->depthFunc = GL_LEQUAL;
+        break;
+    case RS_DEPTH_FUNC_GREATER:
+        drv->depthFunc = GL_GREATER;
+        break;
+    case RS_DEPTH_FUNC_GEQUAL:
+        drv->depthFunc = GL_GEQUAL;
+        break;
+    case RS_DEPTH_FUNC_EQUAL:
+        drv->depthFunc = GL_EQUAL;
+        break;
+    case RS_DEPTH_FUNC_NOTEQUAL:
+        drv->depthFunc = GL_NOTEQUAL;
+        break;
+    default:
+        LOGE("Unknown depth function.");
+        goto error;
+    }
+
+
+
+    drv->blendEnable = true;
+    if ((ps->mHal.state.blendSrc == RS_BLEND_SRC_ONE) &&
+        (ps->mHal.state.blendDst == RS_BLEND_DST_ZERO)) {
+        drv->blendEnable = false;
+    }
+
+    switch (ps->mHal.state.blendSrc) {
+    case RS_BLEND_SRC_ZERO:
+        drv->blendSrc = GL_ZERO;
+        break;
+    case RS_BLEND_SRC_ONE:
+        drv->blendSrc = GL_ONE;
+        break;
+    case RS_BLEND_SRC_DST_COLOR:
+        drv->blendSrc = GL_DST_COLOR;
+        break;
+    case RS_BLEND_SRC_ONE_MINUS_DST_COLOR:
+        drv->blendSrc = GL_ONE_MINUS_DST_COLOR;
+        break;
+    case RS_BLEND_SRC_SRC_ALPHA:
+        drv->blendSrc = GL_SRC_ALPHA;
+        break;
+    case RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA:
+        drv->blendSrc = GL_ONE_MINUS_SRC_ALPHA;
+        break;
+    case RS_BLEND_SRC_DST_ALPHA:
+        drv->blendSrc = GL_DST_ALPHA;
+        break;
+    case RS_BLEND_SRC_ONE_MINUS_DST_ALPHA:
+        drv->blendSrc = GL_ONE_MINUS_DST_ALPHA;
+        break;
+    case RS_BLEND_SRC_SRC_ALPHA_SATURATE:
+        drv->blendSrc = GL_SRC_ALPHA_SATURATE;
+        break;
+    default:
+        LOGE("Unknown blend src mode.");
+        goto error;
+    }
+
+    switch (ps->mHal.state.blendDst) {
+    case RS_BLEND_DST_ZERO:
+        drv->blendDst = GL_ZERO;
+        break;
+    case RS_BLEND_DST_ONE:
+        drv->blendDst = GL_ONE;
+        break;
+    case RS_BLEND_DST_SRC_COLOR:
+        drv->blendDst = GL_SRC_COLOR;
+        break;
+    case RS_BLEND_DST_ONE_MINUS_SRC_COLOR:
+        drv->blendDst = GL_ONE_MINUS_SRC_COLOR;
+        break;
+    case RS_BLEND_DST_SRC_ALPHA:
+        drv->blendDst = GL_SRC_ALPHA;
+        break;
+    case RS_BLEND_DST_ONE_MINUS_SRC_ALPHA:
+        drv->blendDst = GL_ONE_MINUS_SRC_ALPHA;
+        break;
+    case RS_BLEND_DST_DST_ALPHA:
+        drv->blendDst = GL_DST_ALPHA;
+        break;
+    case RS_BLEND_DST_ONE_MINUS_DST_ALPHA:
+        drv->blendDst = GL_ONE_MINUS_DST_ALPHA;
+        break;
+    default:
+        LOGE("Unknown blend dst mode.");
+        goto error;
+    }
+
+    return true;
+
+error:
+    free(drv);
+    ps->mHal.drv = NULL;
+    return false;
+}
+
+void rsdProgramStoreSetActive(const Context *rsc, const ProgramStore *ps) {
+    DrvProgramStore *drv = (DrvProgramStore *)ps->mHal.drv;
+
+    glColorMask(ps->mHal.state.colorRWriteEnable,
+                ps->mHal.state.colorGWriteEnable,
+                ps->mHal.state.colorBWriteEnable,
+                ps->mHal.state.colorAWriteEnable);
+
+    if (drv->blendEnable) {
+        glEnable(GL_BLEND);
+        glBlendFunc(drv->blendSrc, drv->blendDst);
+    } else {
+        glDisable(GL_BLEND);
+    }
+
+    if (rsc->mUserSurfaceConfig.depthMin > 0) {
+        glDepthMask(ps->mHal.state.depthWriteEnable);
+        if (drv->depthTestEnable || ps->mHal.state.depthWriteEnable) {
+            glEnable(GL_DEPTH_TEST);
+            glDepthFunc(drv->depthFunc);
+        } else {
+            glDisable(GL_DEPTH_TEST);
+        }
+    } else {
+        glDepthMask(false);
+        glDisable(GL_DEPTH_TEST);
+    }
+
+    /*
+    if (rsc->mUserSurfaceConfig.stencilMin > 0) {
+    } else {
+        glStencilMask(0);
+        glDisable(GL_STENCIL_TEST);
+    }
+    */
+
+    if (ps->mHal.state.ditherEnable) {
+        glEnable(GL_DITHER);
+    } else {
+        glDisable(GL_DITHER);
+    }
+}
+
+void rsdProgramStoreDestroy(const Context *rsc, const ProgramStore *ps) {
+    free(ps->mHal.drv);
+    ps->mHal.drv = NULL;
+}
+
+
diff --git a/driver/rsdProgramStore.h b/driver/rsdProgramStore.h
new file mode 100644
index 0000000..217a0ce
--- /dev/null
+++ b/driver/rsdProgramStore.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_PROGRAM_STORE_H
+#define RSD_PROGRAM_STORE_H
+
+#include <rs_hal.h>
+
+
+bool rsdProgramStoreInit(const android::renderscript::Context *rsc,
+                         const android::renderscript::ProgramStore *ps);
+void rsdProgramStoreSetActive(const android::renderscript::Context *rsc,
+                              const android::renderscript::ProgramStore *ps);
+void rsdProgramStoreDestroy(const android::renderscript::Context *rsc,
+                            const android::renderscript::ProgramStore *ps);
+
+
+#endif
diff --git a/driver/rsdProgramVertex.h b/driver/rsdProgramVertex.h
new file mode 100644
index 0000000..e998572
--- /dev/null
+++ b/driver/rsdProgramVertex.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_PROGRAM_VERTEX_H
+#define RSD_PROGRAM_VERTEX_H
+
+#include <rs_hal.h>
+
+bool rsdProgramVertexInit(const android::renderscript::Context *rsc,
+                          const android::renderscript::ProgramVertex *,
+                          const char* shader, uint32_t shaderLen);
+void rsdProgramVertexSetActive(const android::renderscript::Context *rsc,
+                               const android::renderscript::ProgramVertex *);
+void rsdProgramVertexDestroy(const android::renderscript::Context *rsc,
+                             const android::renderscript::ProgramVertex *);
+
+
+#endif //RSD_PROGRAM_VERTEX_H
diff --git a/driver/rsdRuntime.h b/driver/rsdRuntime.h
new file mode 100644
index 0000000..840eced
--- /dev/null
+++ b/driver/rsdRuntime.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_RUNTIME_STUBS_H
+#define RSD_RUNTIME_STUBS_H
+
+#include <rs_hal.h>
+#include <bcc/bcc.h>
+
+#include "rsMutex.h"
+
+const RsdSymbolTable * rsdLookupSymbolMath(const char *sym);
+
+void* rsdLookupRuntimeStub(void* pContext, char const* name);
+
+#endif
diff --git a/driver/rsdRuntimeMath.cpp b/driver/rsdRuntimeMath.cpp
new file mode 100644
index 0000000..acb990d
--- /dev/null
+++ b/driver/rsdRuntimeMath.cpp
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2011 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 "rsContext.h"
+#include "rsScriptC.h"
+#include "rsMatrix4x4.h"
+#include "rsMatrix3x3.h"
+#include "rsMatrix2x2.h"
+
+#include "rsdCore.h"
+#include "rsdRuntime.h"
+
+
+using namespace android;
+using namespace android::renderscript;
+
+
+static float SC_exp10(float v) {
+    return pow(10.f, v);
+}
+
+static float SC_fract(float v, int *iptr) {
+    int i = (int)floor(v);
+    iptr[0] = i;
+    return fmin(v - i, 0x1.fffffep-1f);
+}
+
+static float SC_log2(float v) {
+    return log10(v) / log10(2.f);
+}
+
+static float SC_mad(float v1, float v2, float v3) {
+    return v1 * v2 + v3;
+}
+
+#if 0
+static float SC_pown(float v, int p) {
+    return powf(v, (float)p);
+}
+
+static float SC_powr(float v, float p) {
+    return powf(v, p);
+}
+#endif
+
+float SC_rootn(float v, int r) {
+    return pow(v, 1.f / r);
+}
+
+float SC_rsqrt(float v) {
+    return 1.f / sqrtf(v);
+}
+
+float SC_sincos(float v, float *cosptr) {
+    *cosptr = cosf(v);
+    return sinf(v);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Integer
+//////////////////////////////////////////////////////////////////////////////
+
+
+static uint32_t SC_abs_i32(int32_t v) {return abs(v);}
+static uint16_t SC_abs_i16(int16_t v) {return (uint16_t)abs(v);}
+static uint8_t SC_abs_i8(int8_t v) {return (uint8_t)abs(v);}
+
+static uint32_t SC_clz_u32(uint32_t v) {return __builtin_clz(v);}
+static uint16_t SC_clz_u16(uint16_t v) {return (uint16_t)__builtin_clz(v);}
+static uint8_t SC_clz_u8(uint8_t v) {return (uint8_t)__builtin_clz(v);}
+static int32_t SC_clz_i32(int32_t v) {return (int32_t)__builtin_clz((uint32_t)v);}
+static int16_t SC_clz_i16(int16_t v) {return (int16_t)__builtin_clz(v);}
+static int8_t SC_clz_i8(int8_t v) {return (int8_t)__builtin_clz(v);}
+
+static uint32_t SC_max_u32(uint32_t v, uint32_t v2) {return rsMax(v, v2);}
+static uint16_t SC_max_u16(uint16_t v, uint16_t v2) {return rsMax(v, v2);}
+static uint8_t SC_max_u8(uint8_t v, uint8_t v2) {return rsMax(v, v2);}
+static int32_t SC_max_i32(int32_t v, int32_t v2) {return rsMax(v, v2);}
+static int16_t SC_max_i16(int16_t v, int16_t v2) {return rsMax(v, v2);}
+static int8_t SC_max_i8(int8_t v, int8_t v2) {return rsMax(v, v2);}
+
+static uint32_t SC_min_u32(uint32_t v, uint32_t v2) {return rsMin(v, v2);}
+static uint16_t SC_min_u16(uint16_t v, uint16_t v2) {return rsMin(v, v2);}
+static uint8_t SC_min_u8(uint8_t v, uint8_t v2) {return rsMin(v, v2);}
+static int32_t SC_min_i32(int32_t v, int32_t v2) {return rsMin(v, v2);}
+static int16_t SC_min_i16(int16_t v, int16_t v2) {return rsMin(v, v2);}
+static int8_t SC_min_i8(int8_t v, int8_t v2) {return rsMin(v, v2);}
+
+//////////////////////////////////////////////////////////////////////////////
+// Float util
+//////////////////////////////////////////////////////////////////////////////
+
+static float SC_clamp_f32(float amount, float low, float high) {
+    return amount < low ? low : (amount > high ? high : amount);
+}
+
+static float SC_degrees(float radians) {
+    return radians * (180.f / M_PI);
+}
+
+static float SC_max_f32(float v, float v2) {
+    return rsMax(v, v2);
+}
+
+static float SC_min_f32(float v, float v2) {
+    return rsMin(v, v2);
+}
+
+static float SC_mix_f32(float start, float stop, float amount) {
+    //LOGE("lerpf %f  %f  %f", start, stop, amount);
+    return start + (stop - start) * amount;
+}
+
+static float SC_radians(float degrees) {
+    return degrees * (M_PI / 180.f);
+}
+
+static float SC_step_f32(float edge, float v) {
+    if (v < edge) return 0.f;
+    return 1.f;
+}
+
+static float SC_sign_f32(float value) {
+    if (value > 0) return 1.f;
+    if (value < 0) return -1.f;
+    return value;
+}
+
+static void SC_MatrixLoadIdentity_4x4(Matrix4x4 *m) {
+    m->loadIdentity();
+}
+static void SC_MatrixLoadIdentity_3x3(Matrix3x3 *m) {
+    m->loadIdentity();
+}
+static void SC_MatrixLoadIdentity_2x2(Matrix2x2 *m) {
+    m->loadIdentity();
+}
+
+static void SC_MatrixLoad_4x4_f(Matrix4x4 *m, const float *f) {
+    m->load(f);
+}
+static void SC_MatrixLoad_3x3_f(Matrix3x3 *m, const float *f) {
+    m->load(f);
+}
+static void SC_MatrixLoad_2x2_f(Matrix2x2 *m, const float *f) {
+    m->load(f);
+}
+
+static void SC_MatrixLoad_4x4_4x4(Matrix4x4 *m, const Matrix4x4 *s) {
+    m->load(s);
+}
+static void SC_MatrixLoad_4x4_3x3(Matrix4x4 *m, const Matrix3x3 *s) {
+    m->load(s);
+}
+static void SC_MatrixLoad_4x4_2x2(Matrix4x4 *m, const Matrix2x2 *s) {
+    m->load(s);
+}
+static void SC_MatrixLoad_3x3_3x3(Matrix3x3 *m, const Matrix3x3 *s) {
+    m->load(s);
+}
+static void SC_MatrixLoad_2x2_2x2(Matrix2x2 *m, const Matrix2x2 *s) {
+    m->load(s);
+}
+
+static void SC_MatrixLoadRotate(Matrix4x4 *m, float rot, float x, float y, float z) {
+    m->loadRotate(rot, x, y, z);
+}
+static void SC_MatrixLoadScale(Matrix4x4 *m, float x, float y, float z) {
+    m->loadScale(x, y, z);
+}
+static void SC_MatrixLoadTranslate(Matrix4x4 *m, float x, float y, float z) {
+    m->loadTranslate(x, y, z);
+}
+static void SC_MatrixRotate(Matrix4x4 *m, float rot, float x, float y, float z) {
+    m->rotate(rot, x, y, z);
+}
+static void SC_MatrixScale(Matrix4x4 *m, float x, float y, float z) {
+    m->scale(x, y, z);
+}
+static void SC_MatrixTranslate(Matrix4x4 *m, float x, float y, float z) {
+    m->translate(x, y, z);
+}
+
+static void SC_MatrixLoadMultiply_4x4_4x4_4x4(Matrix4x4 *m, const Matrix4x4 *lhs, const Matrix4x4 *rhs) {
+    m->loadMultiply(lhs, rhs);
+}
+static void SC_MatrixLoadMultiply_3x3_3x3_3x3(Matrix3x3 *m, const Matrix3x3 *lhs, const Matrix3x3 *rhs) {
+    m->loadMultiply(lhs, rhs);
+}
+static void SC_MatrixLoadMultiply_2x2_2x2_2x2(Matrix2x2 *m, const Matrix2x2 *lhs, const Matrix2x2 *rhs) {
+    m->loadMultiply(lhs, rhs);
+}
+
+static void SC_MatrixMultiply_4x4_4x4(Matrix4x4 *m, const Matrix4x4 *rhs) {
+    m->multiply(rhs);
+}
+static void SC_MatrixMultiply_3x3_3x3(Matrix3x3 *m, const Matrix3x3 *rhs) {
+    m->multiply(rhs);
+}
+static void SC_MatrixMultiply_2x2_2x2(Matrix2x2 *m, const Matrix2x2 *rhs) {
+    m->multiply(rhs);
+}
+
+static void SC_MatrixLoadOrtho(Matrix4x4 *m, float l, float r, float b, float t, float n, float f) {
+    m->loadOrtho(l, r, b, t, n, f);
+}
+static void SC_MatrixLoadFrustum(Matrix4x4 *m, float l, float r, float b, float t, float n, float f) {
+    m->loadFrustum(l, r, b, t, n, f);
+}
+static void SC_MatrixLoadPerspective(Matrix4x4 *m, float fovy, float aspect, float near, float far) {
+    m->loadPerspective(fovy, aspect, near, far);
+}
+
+static bool SC_MatrixInverse_4x4(Matrix4x4 *m) {
+    return m->inverse();
+}
+static bool SC_MatrixInverseTranspose_4x4(Matrix4x4 *m) {
+    return m->inverseTranspose();
+}
+static void SC_MatrixTranspose_4x4(Matrix4x4 *m) {
+    m->transpose();
+}
+static void SC_MatrixTranspose_3x3(Matrix3x3 *m) {
+    m->transpose();
+}
+static void SC_MatrixTranspose_2x2(Matrix2x2 *m) {
+    m->transpose();
+}
+
+static float SC_randf(float max) {
+    float r = (float)rand();
+    r *= max;
+    r /= RAND_MAX;
+    return r;
+}
+
+static float SC_randf2(float min, float max) {
+    float r = (float)rand();
+    r /= RAND_MAX;
+    r = r * (max - min) + min;
+    return r;
+}
+
+static int SC_randi(int max) {
+    return (int)SC_randf(max);
+}
+
+static int SC_randi2(int min, int max) {
+    return (int)SC_randf2(min, max);
+}
+
+static float SC_frac(float v) {
+    int i = (int)floor(v);
+    return fmin(v - i, 0x1.fffffep-1f);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Class implementation
+//////////////////////////////////////////////////////////////////////////////
+
+// llvm name mangling ref
+//  <builtin-type> ::= v  # void
+//                 ::= b  # bool
+//                 ::= c  # char
+//                 ::= a  # signed char
+//                 ::= h  # unsigned char
+//                 ::= s  # short
+//                 ::= t  # unsigned short
+//                 ::= i  # int
+//                 ::= j  # unsigned int
+//                 ::= l  # long
+//                 ::= m  # unsigned long
+//                 ::= x  # long long, __int64
+//                 ::= y  # unsigned long long, __int64
+//                 ::= f  # float
+//                 ::= d  # double
+
+static RsdSymbolTable gSyms[] = {
+    { "_Z4acosf", (void *)&acosf, true },
+    { "_Z5acoshf", (void *)&acoshf, true },
+    { "_Z4asinf", (void *)&asinf, true },
+    { "_Z5asinhf", (void *)&asinhf, true },
+    { "_Z4atanf", (void *)&atanf, true },
+    { "_Z5atan2ff", (void *)&atan2f, true },
+    { "_Z5atanhf", (void *)&atanhf, true },
+    { "_Z4cbrtf", (void *)&cbrtf, true },
+    { "_Z4ceilf", (void *)&ceilf, true },
+    { "_Z8copysignff", (void *)&copysignf, true },
+    { "_Z3cosf", (void *)&cosf, true },
+    { "_Z4coshf", (void *)&coshf, true },
+    { "_Z4erfcf", (void *)&erfcf, true },
+    { "_Z3erff", (void *)&erff, true },
+    { "_Z3expf", (void *)&expf, true },
+    { "_Z4exp2f", (void *)&exp2f, true },
+    { "_Z5exp10f", (void *)&SC_exp10, true },
+    { "_Z5expm1f", (void *)&expm1f, true },
+    { "_Z4fabsf", (void *)&fabsf, true },
+    { "_Z4fdimff", (void *)&fdimf, true },
+    { "_Z5floorf", (void *)&floorf, true },
+    { "_Z3fmafff", (void *)&fmaf, true },
+    { "_Z4fmaxff", (void *)&fmaxf, true },
+    { "_Z4fminff", (void *)&fminf, true },  // float fmin(float, float)
+    { "_Z4fmodff", (void *)&fmodf, true },
+    { "_Z5fractfPf", (void *)&SC_fract, true },
+    { "_Z5frexpfPi", (void *)&frexpf, true },
+    { "_Z5hypotff", (void *)&hypotf, true },
+    { "_Z5ilogbf", (void *)&ilogbf, true },
+    { "_Z5ldexpfi", (void *)&ldexpf, true },
+    { "_Z6lgammaf", (void *)&lgammaf, true },
+    { "_Z6lgammafPi", (void *)&lgammaf_r, true },
+    { "_Z3logf", (void *)&logf, true },
+    { "_Z4log2f", (void *)&SC_log2, true },
+    { "_Z5log10f", (void *)&log10f, true },
+    { "_Z5log1pf", (void *)&log1pf, true },
+    { "_Z4logbf", (void *)&logbf, true },
+    { "_Z3madfff", (void *)&SC_mad, true },
+    { "_Z4modffPf", (void *)&modff, true },
+    //{ "_Z3nanj", (void *)&SC_nan, true },
+    { "_Z9nextafterff", (void *)&nextafterf, true },
+    { "_Z3powff", (void *)&powf, true },
+    { "_Z9remainderff", (void *)&remainderf, true },
+    { "_Z6remquoffPi", (void *)&remquof, true },
+    { "_Z4rintf", (void *)&rintf, true },
+    { "_Z5rootnfi", (void *)&SC_rootn, true },
+    { "_Z5roundf", (void *)&roundf, true },
+    { "_Z5rsqrtf", (void *)&SC_rsqrt, true },
+    { "_Z3sinf", (void *)&sinf, true },
+    { "_Z6sincosfPf", (void *)&SC_sincos, true },
+    { "_Z4sinhf", (void *)&sinhf, true },
+    { "_Z4sqrtf", (void *)&sqrtf, true },
+    { "_Z3tanf", (void *)&tanf, true },
+    { "_Z4tanhf", (void *)&tanhf, true },
+    { "_Z6tgammaf", (void *)&tgammaf, true },
+    { "_Z5truncf", (void *)&truncf, true },
+
+    { "_Z3absi", (void *)&SC_abs_i32, true },
+    { "_Z3abss", (void *)&SC_abs_i16, true },
+    { "_Z3absc", (void *)&SC_abs_i8, true },
+    { "_Z3clzj", (void *)&SC_clz_u32, true },
+    { "_Z3clzt", (void *)&SC_clz_u16, true },
+    { "_Z3clzh", (void *)&SC_clz_u8, true },
+    { "_Z3clzi", (void *)&SC_clz_i32, true },
+    { "_Z3clzs", (void *)&SC_clz_i16, true },
+    { "_Z3clzc", (void *)&SC_clz_i8, true },
+    { "_Z3maxjj", (void *)&SC_max_u32, true },
+    { "_Z3maxtt", (void *)&SC_max_u16, true },
+    { "_Z3maxhh", (void *)&SC_max_u8, true },
+    { "_Z3maxii", (void *)&SC_max_i32, true },
+    { "_Z3maxss", (void *)&SC_max_i16, true },
+    { "_Z3maxcc", (void *)&SC_max_i8, true },
+    { "_Z3minjj", (void *)&SC_min_u32, true },
+    { "_Z3mintt", (void *)&SC_min_u16, true },
+    { "_Z3minhh", (void *)&SC_min_u8, true },
+    { "_Z3minii", (void *)&SC_min_i32, true },
+    { "_Z3minss", (void *)&SC_min_i16, true },
+    { "_Z3mincc", (void *)&SC_min_i8, true },
+
+    { "_Z5clampfff", (void *)&SC_clamp_f32, true },
+    { "_Z7degreesf", (void *)&SC_degrees, true },
+    { "_Z3maxff", (void *)&SC_max_f32, true },
+    { "_Z3minff", (void *)&SC_min_f32, true },
+    { "_Z3mixfff", (void *)&SC_mix_f32, true },
+    { "_Z7radiansf", (void *)&SC_radians, true },
+    { "_Z4stepff", (void *)&SC_step_f32, true },
+    //{ "smoothstep", (void *)&, true },
+    { "_Z4signf", (void *)&SC_sign_f32, true },
+
+    // matrix
+    { "_Z20rsMatrixLoadIdentityP12rs_matrix4x4", (void *)&SC_MatrixLoadIdentity_4x4, true },
+    { "_Z20rsMatrixLoadIdentityP12rs_matrix3x3", (void *)&SC_MatrixLoadIdentity_3x3, true },
+    { "_Z20rsMatrixLoadIdentityP12rs_matrix2x2", (void *)&SC_MatrixLoadIdentity_2x2, true },
+
+    { "_Z12rsMatrixLoadP12rs_matrix4x4PKf", (void *)&SC_MatrixLoad_4x4_f, true },
+    { "_Z12rsMatrixLoadP12rs_matrix3x3PKf", (void *)&SC_MatrixLoad_3x3_f, true },
+    { "_Z12rsMatrixLoadP12rs_matrix2x2PKf", (void *)&SC_MatrixLoad_2x2_f, true },
+
+    { "_Z12rsMatrixLoadP12rs_matrix4x4PKS_", (void *)&SC_MatrixLoad_4x4_4x4, true },
+    { "_Z12rsMatrixLoadP12rs_matrix4x4PK12rs_matrix3x3", (void *)&SC_MatrixLoad_4x4_3x3, true },
+    { "_Z12rsMatrixLoadP12rs_matrix4x4PK12rs_matrix2x2", (void *)&SC_MatrixLoad_4x4_2x2, true },
+    { "_Z12rsMatrixLoadP12rs_matrix3x3PKS_", (void *)&SC_MatrixLoad_3x3_3x3, true },
+    { "_Z12rsMatrixLoadP12rs_matrix2x2PKS_", (void *)&SC_MatrixLoad_2x2_2x2, true },
+
+    { "_Z18rsMatrixLoadRotateP12rs_matrix4x4ffff", (void *)&SC_MatrixLoadRotate, true },
+    { "_Z17rsMatrixLoadScaleP12rs_matrix4x4fff", (void *)&SC_MatrixLoadScale, true },
+    { "_Z21rsMatrixLoadTranslateP12rs_matrix4x4fff", (void *)&SC_MatrixLoadTranslate, true },
+    { "_Z14rsMatrixRotateP12rs_matrix4x4ffff", (void *)&SC_MatrixRotate, true },
+    { "_Z13rsMatrixScaleP12rs_matrix4x4fff", (void *)&SC_MatrixScale, true },
+    { "_Z17rsMatrixTranslateP12rs_matrix4x4fff", (void *)&SC_MatrixTranslate, true },
+
+    { "_Z20rsMatrixLoadMultiplyP12rs_matrix4x4PKS_S2_", (void *)&SC_MatrixLoadMultiply_4x4_4x4_4x4, true },
+    { "_Z16rsMatrixMultiplyP12rs_matrix4x4PKS_", (void *)&SC_MatrixMultiply_4x4_4x4, true },
+    { "_Z20rsMatrixLoadMultiplyP12rs_matrix3x3PKS_S2_", (void *)&SC_MatrixLoadMultiply_3x3_3x3_3x3, true },
+    { "_Z16rsMatrixMultiplyP12rs_matrix3x3PKS_", (void *)&SC_MatrixMultiply_3x3_3x3, true },
+    { "_Z20rsMatrixLoadMultiplyP12rs_matrix2x2PKS_S2_", (void *)&SC_MatrixLoadMultiply_2x2_2x2_2x2, true },
+    { "_Z16rsMatrixMultiplyP12rs_matrix2x2PKS_", (void *)&SC_MatrixMultiply_2x2_2x2, true },
+
+    { "_Z17rsMatrixLoadOrthoP12rs_matrix4x4ffffff", (void *)&SC_MatrixLoadOrtho, true },
+    { "_Z19rsMatrixLoadFrustumP12rs_matrix4x4ffffff", (void *)&SC_MatrixLoadFrustum, true },
+    { "_Z23rsMatrixLoadPerspectiveP12rs_matrix4x4ffff", (void *)&SC_MatrixLoadPerspective, true },
+
+    { "_Z15rsMatrixInverseP12rs_matrix4x4", (void *)&SC_MatrixInverse_4x4, true },
+    { "_Z24rsMatrixInverseTransposeP12rs_matrix4x4", (void *)&SC_MatrixInverseTranspose_4x4, true },
+    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_4x4, true },
+    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_3x3, true },
+    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_2x2, true },
+
+    // RS Math
+    { "_Z6rsRandi", (void *)&SC_randi, true },
+    { "_Z6rsRandii", (void *)&SC_randi2, true },
+    { "_Z6rsRandf", (void *)&SC_randf, true },
+    { "_Z6rsRandff", (void *)&SC_randf2, true },
+    { "_Z6rsFracf", (void *)&SC_frac, true },
+
+    { NULL, NULL, false }
+};
+
+const RsdSymbolTable * rsdLookupSymbolMath(const char *sym) {
+    const RsdSymbolTable *syms = gSyms;
+
+    while (syms->mPtr) {
+        if (!strcmp(syms->mName, sym)) {
+            return syms;
+        }
+        syms++;
+    }
+    return NULL;
+}
+
diff --git a/driver/rsdRuntimeStubs.cpp b/driver/rsdRuntimeStubs.cpp
new file mode 100644
index 0000000..9cbff95
--- /dev/null
+++ b/driver/rsdRuntimeStubs.cpp
@@ -0,0 +1,692 @@
+/*
+ * Copyright (C) 2011 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 "rsContext.h"
+#include "rsScriptC.h"
+#include "rsMatrix4x4.h"
+#include "rsMatrix3x3.h"
+#include "rsMatrix2x2.h"
+#include "rsRuntime.h"
+
+#include "utils/Timers.h"
+#include "rsdCore.h"
+
+#include "rsdRuntime.h"
+
+#include <time.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+#define GET_TLS()  ScriptTLSStruct * tls = \
+    (ScriptTLSStruct *)pthread_getspecific(rsdgThreadTLSKey); \
+    Context * rsc = tls->mContext; \
+    ScriptC * sc = (ScriptC *) tls->mScript
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Allocation
+//////////////////////////////////////////////////////////////////////////////
+
+static uint32_t SC_allocGetDimX(Allocation *a) {
+    return a->mHal.state.dimensionX;
+}
+
+static uint32_t SC_allocGetDimY(Allocation *a) {
+    return a->mHal.state.dimensionY;
+}
+
+static uint32_t SC_allocGetDimZ(Allocation *a) {
+    return a->mHal.state.dimensionZ;
+}
+
+static uint32_t SC_allocGetDimLOD(Allocation *a) {
+    return a->mHal.state.hasMipmaps;
+}
+
+static uint32_t SC_allocGetDimFaces(Allocation *a) {
+    return a->mHal.state.hasFaces;
+}
+
+static const void * SC_getElementAtX(Allocation *a, uint32_t x) {
+    const uint8_t *p = (const uint8_t *)a->getPtr();
+    return &p[a->mHal.state.elementSizeBytes * x];
+}
+
+static const void * SC_getElementAtXY(Allocation *a, uint32_t x, uint32_t y) {
+    const uint8_t *p = (const uint8_t *)a->getPtr();
+    return &p[a->mHal.state.elementSizeBytes * (x + y * a->mHal.state.dimensionX)];
+}
+
+static const void * SC_getElementAtXYZ(Allocation *a, uint32_t x, uint32_t y, uint32_t z) {
+    const uint8_t *p = (const uint8_t *)a->getPtr();
+    return &p[a->mHal.state.elementSizeBytes * (x + y * a->mHal.state.dimensionX +
+              z * a->mHal.state.dimensionX * a->mHal.state.dimensionY)];
+}
+
+static void SC_AllocationSyncAll2(Allocation *a, RsAllocationUsageType source) {
+    GET_TLS();
+    rsrAllocationSyncAll(rsc, sc, a, source);
+}
+
+static void SC_AllocationSyncAll(Allocation *a) {
+    GET_TLS();
+    rsrAllocationSyncAll(rsc, sc, a, RS_ALLOCATION_USAGE_SCRIPT);
+}
+
+const Allocation * SC_getAllocation(const void *ptr) {
+    GET_TLS();
+    return rsrGetAllocation(rsc, sc, ptr);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Context
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_BindTexture(ProgramFragment *pf, uint32_t slot, Allocation *a) {
+    GET_TLS();
+    rsrBindTexture(rsc, sc, pf, slot, a);
+}
+
+static void SC_BindSampler(ProgramFragment *pf, uint32_t slot, Sampler *s) {
+    GET_TLS();
+    rsrBindSampler(rsc, sc, pf, slot, s);
+}
+
+static void SC_BindProgramStore(ProgramStore *ps) {
+    GET_TLS();
+    rsrBindProgramStore(rsc, sc, ps);
+}
+
+static void SC_BindProgramFragment(ProgramFragment *pf) {
+    GET_TLS();
+    rsrBindProgramFragment(rsc, sc, pf);
+}
+
+static void SC_BindProgramVertex(ProgramVertex *pv) {
+    GET_TLS();
+    rsrBindProgramVertex(rsc, sc, pv);
+}
+
+static void SC_BindProgramRaster(ProgramRaster *pr) {
+    GET_TLS();
+    rsrBindProgramRaster(rsc, sc, pr);
+}
+
+static void SC_BindFrameBufferObjectColorTarget(Allocation *a, uint32_t slot) {
+    GET_TLS();
+    rsrBindFrameBufferObjectColorTarget(rsc, sc, a, slot);
+}
+
+static void SC_BindFrameBufferObjectDepthTarget(Allocation *a) {
+    GET_TLS();
+    rsrBindFrameBufferObjectDepthTarget(rsc, sc, a);
+}
+
+static void SC_ClearFrameBufferObjectColorTarget(uint32_t slot) {
+    GET_TLS();
+    rsrClearFrameBufferObjectColorTarget(rsc, sc, slot);
+}
+
+static void SC_ClearFrameBufferObjectDepthTarget(Context *, Script *) {
+    GET_TLS();
+    rsrClearFrameBufferObjectDepthTarget(rsc, sc);
+}
+
+static void SC_ClearFrameBufferObjectTargets(Context *, Script *) {
+    GET_TLS();
+    rsrClearFrameBufferObjectTargets(rsc, sc);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// VP
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_VpLoadProjectionMatrix(const rsc_Matrix *m) {
+    GET_TLS();
+    rsrVpLoadProjectionMatrix(rsc, sc, m);
+}
+
+static void SC_VpLoadModelMatrix(const rsc_Matrix *m) {
+    GET_TLS();
+    rsrVpLoadModelMatrix(rsc, sc, m);
+}
+
+static void SC_VpLoadTextureMatrix(const rsc_Matrix *m) {
+    GET_TLS();
+    rsrVpLoadTextureMatrix(rsc, sc, m);
+}
+
+static void SC_PfConstantColor(ProgramFragment *pf, float r, float g, float b, float a) {
+    GET_TLS();
+    rsrPfConstantColor(rsc, sc, pf, r, g, b, a);
+}
+
+static void SC_VpGetProjectionMatrix(rsc_Matrix *m) {
+    GET_TLS();
+    rsrVpGetProjectionMatrix(rsc, sc, m);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Drawing
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_DrawQuadTexCoords(float x1, float y1, float z1, float u1, float v1,
+                                 float x2, float y2, float z2, float u2, float v2,
+                                 float x3, float y3, float z3, float u3, float v3,
+                                 float x4, float y4, float z4, float u4, float v4) {
+    GET_TLS();
+    rsrDrawQuadTexCoords(rsc, sc,
+                         x1, y1, z1, u1, v1,
+                         x2, y2, z2, u2, v2,
+                         x3, y3, z3, u3, v3,
+                         x4, y4, z4, u4, v4);
+}
+
+static void SC_DrawQuad(float x1, float y1, float z1,
+                        float x2, float y2, float z2,
+                        float x3, float y3, float z3,
+                        float x4, float y4, float z4) {
+    GET_TLS();
+    rsrDrawQuad(rsc, sc, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4);
+}
+
+static void SC_DrawSpriteScreenspace(float x, float y, float z, float w, float h) {
+    GET_TLS();
+    rsrDrawSpriteScreenspace(rsc, sc, x, y, z, w, h);
+}
+
+static void SC_DrawRect(float x1, float y1, float x2, float y2, float z) {
+    GET_TLS();
+    rsrDrawRect(rsc, sc, x1, y1, x2, y2, z);
+}
+
+static void SC_DrawMesh(Mesh *m) {
+    GET_TLS();
+    rsrDrawMesh(rsc, sc, m);
+}
+
+static void SC_DrawMeshPrimitive(Mesh *m, uint32_t primIndex) {
+    GET_TLS();
+    rsrDrawMeshPrimitive(rsc, sc, m, primIndex);
+}
+
+static void SC_DrawMeshPrimitiveRange(Mesh *m, uint32_t primIndex, uint32_t start, uint32_t len) {
+    GET_TLS();
+    rsrDrawMeshPrimitiveRange(rsc, sc, m, primIndex, start, len);
+}
+
+static void SC_MeshComputeBoundingBox(Mesh *m,
+                               float *minX, float *minY, float *minZ,
+                               float *maxX, float *maxY, float *maxZ) {
+    GET_TLS();
+    rsrMeshComputeBoundingBox(rsc, sc, m, minX, minY, minZ, maxX, maxY, maxZ);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+static void SC_Color(float r, float g, float b, float a) {
+    GET_TLS();
+    rsrColor(rsc, sc, r, g, b, a);
+}
+
+static void SC_Finish() {
+    GET_TLS();
+    rsrFinish(rsc, sc);
+}
+
+static void SC_ClearColor(float r, float g, float b, float a) {
+    GET_TLS();
+    rsrClearColor(rsc, sc, r, g, b, a);
+}
+
+static void SC_ClearDepth(float v) {
+    GET_TLS();
+    rsrClearDepth(rsc, sc, v);
+}
+
+static uint32_t SC_GetWidth() {
+    GET_TLS();
+    return rsrGetWidth(rsc, sc);
+}
+
+static uint32_t SC_GetHeight() {
+    GET_TLS();
+    return rsrGetHeight(rsc, sc);
+}
+
+static void SC_DrawTextAlloc(Allocation *a, int x, int y) {
+    GET_TLS();
+    rsrDrawTextAlloc(rsc, sc, a, x, y);
+}
+
+static void SC_DrawText(const char *text, int x, int y) {
+    GET_TLS();
+    rsrDrawText(rsc, sc, text, x, y);
+}
+
+static void SC_MeasureTextAlloc(Allocation *a,
+                         int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
+    GET_TLS();
+    rsrMeasureTextAlloc(rsc, sc, a, left, right, top, bottom);
+}
+
+static void SC_MeasureText(const char *text,
+                    int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
+    GET_TLS();
+    rsrMeasureText(rsc, sc, text, left, right, top, bottom);
+}
+
+static void SC_BindFont(Font *f) {
+    GET_TLS();
+    rsrBindFont(rsc, sc, f);
+}
+
+static void SC_FontColor(float r, float g, float b, float a) {
+    GET_TLS();
+    rsrFontColor(rsc, sc, r, g, b, a);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_SetObject(ObjectBase **dst, ObjectBase * src) {
+    GET_TLS();
+    rsrSetObject(rsc, sc, dst, src);
+}
+
+static void SC_ClearObject(ObjectBase **dst) {
+    GET_TLS();
+    rsrClearObject(rsc, sc, dst);
+}
+
+static bool SC_IsObject(const ObjectBase *src) {
+    GET_TLS();
+    return rsrIsObject(rsc, sc, src);
+}
+
+
+
+
+static const Allocation * SC_GetAllocation(const void *ptr) {
+    GET_TLS();
+    return rsrGetAllocation(rsc, sc, ptr);
+}
+
+static void SC_ForEach(Script *target,
+                Allocation *in,
+                Allocation *out,
+                const void *usr,
+                const RsScriptCall *call) {
+    GET_TLS();
+    rsrForEach(rsc, sc, target, in, out, usr, 0, NULL);
+}
+
+static void SC_ForEach2(Script *target,
+                 Allocation *in,
+                 Allocation *out,
+                 const void *usr,
+                 const RsScriptCall *call) {
+    GET_TLS();
+    rsrForEach(rsc, sc, target, in, out, usr, 0, call);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Time routines
+//////////////////////////////////////////////////////////////////////////////
+
+static float SC_GetDt() {
+    GET_TLS();
+    return rsrGetDt(rsc, sc);
+}
+
+time_t SC_Time(time_t *timer) {
+    GET_TLS();
+    return rsrTime(rsc, sc, timer);
+}
+
+tm* SC_LocalTime(tm *local, time_t *timer) {
+    GET_TLS();
+    return rsrLocalTime(rsc, sc, local, timer);
+}
+
+int64_t SC_UptimeMillis() {
+    GET_TLS();
+    return rsrUptimeMillis(rsc, sc);
+}
+
+int64_t SC_UptimeNanos() {
+    GET_TLS();
+    return rsrUptimeNanos(rsc, sc);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Message routines
+//////////////////////////////////////////////////////////////////////////////
+
+static uint32_t SC_ToClient2(int cmdID, void *data, int len) {
+    GET_TLS();
+    return rsrToClient(rsc, sc, cmdID, data, len);
+}
+
+static uint32_t SC_ToClient(int cmdID) {
+    GET_TLS();
+    return rsrToClient(rsc, sc, cmdID, NULL, 0);
+}
+
+static uint32_t SC_ToClientBlocking2(int cmdID, void *data, int len) {
+    GET_TLS();
+    return rsrToClientBlocking(rsc, sc, cmdID, data, len);
+}
+
+static uint32_t SC_ToClientBlocking(int cmdID) {
+    GET_TLS();
+    return rsrToClientBlocking(rsc, sc, cmdID, NULL, 0);
+}
+
+int SC_divsi3(int a, int b) {
+    return a / b;
+}
+
+int SC_modsi3(int a, int b) {
+    return a % b;
+}
+
+unsigned int SC_udivsi3(unsigned int a, unsigned int b) {
+    return a / b;
+}
+
+unsigned int SC_umodsi3(unsigned int a, unsigned int b) {
+    return a % b;
+}
+
+static void SC_debugF(const char *s, float f) {
+    LOGD("%s %f, 0x%08x", s, f, *((int *) (&f)));
+}
+static void SC_debugFv2(const char *s, float f1, float f2) {
+    LOGD("%s {%f, %f}", s, f1, f2);
+}
+static void SC_debugFv3(const char *s, float f1, float f2, float f3) {
+    LOGD("%s {%f, %f, %f}", s, f1, f2, f3);
+}
+static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) {
+    LOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
+}
+static void SC_debugD(const char *s, double d) {
+    LOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
+}
+static void SC_debugFM4v4(const char *s, const float *f) {
+    LOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
+    LOGD("%s  %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
+    LOGD("%s  %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
+    LOGD("%s  %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
+}
+static void SC_debugFM3v3(const char *s, const float *f) {
+    LOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
+    LOGD("%s  %f, %f, %f", s, f[1], f[4], f[7]);
+    LOGD("%s  %f, %f, %f}",s, f[2], f[5], f[8]);
+}
+static void SC_debugFM2v2(const char *s, const float *f) {
+    LOGD("%s {%f, %f", s, f[0], f[2]);
+    LOGD("%s  %f, %f}",s, f[1], f[3]);
+}
+
+static void SC_debugI32(const char *s, int32_t i) {
+    LOGD("%s %i  0x%x", s, i, i);
+}
+static void SC_debugU32(const char *s, uint32_t i) {
+    LOGD("%s %u  0x%x", s, i, i);
+}
+static void SC_debugLL64(const char *s, long long ll) {
+    LOGD("%s %lld  0x%llx", s, ll, ll);
+}
+static void SC_debugULL64(const char *s, unsigned long long ll) {
+    LOGD("%s %llu  0x%llx", s, ll, ll);
+}
+
+static void SC_debugP(const char *s, const void *p) {
+    LOGD("%s %p", s, p);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Stub implementation
+//////////////////////////////////////////////////////////////////////////////
+
+// llvm name mangling ref
+//  <builtin-type> ::= v  # void
+//                 ::= b  # bool
+//                 ::= c  # char
+//                 ::= a  # signed char
+//                 ::= h  # unsigned char
+//                 ::= s  # short
+//                 ::= t  # unsigned short
+//                 ::= i  # int
+//                 ::= j  # unsigned int
+//                 ::= l  # long
+//                 ::= m  # unsigned long
+//                 ::= x  # long long, __int64
+//                 ::= y  # unsigned long long, __int64
+//                 ::= f  # float
+//                 ::= d  # double
+
+static RsdSymbolTable gSyms[] = {
+    { "__divsi3", (void *)&SC_divsi3, true },
+    { "__modsi3", (void *)&SC_modsi3, true },
+    { "__udivsi3", (void *)&SC_udivsi3, true },
+    { "__umodsi3", (void *)&SC_umodsi3, true },
+    { "memset", (void *)&memset, true },
+    { "memcpy", (void *)&memcpy, true },
+
+    // Refcounting
+    { "_Z11rsSetObjectP10rs_elementS_", (void *)&SC_SetObject, true },
+    { "_Z13rsClearObjectP10rs_element", (void *)&SC_ClearObject, true },
+    { "_Z10rsIsObject10rs_element", (void *)&SC_IsObject, true },
+
+    { "_Z11rsSetObjectP7rs_typeS_", (void *)&SC_SetObject, true },
+    { "_Z13rsClearObjectP7rs_type", (void *)&SC_ClearObject, true },
+    { "_Z10rsIsObject7rs_type", (void *)&SC_IsObject, true },
+
+    { "_Z11rsSetObjectP13rs_allocationS_", (void *)&SC_SetObject, true },
+    { "_Z13rsClearObjectP13rs_allocation", (void *)&SC_ClearObject, true },
+    { "_Z10rsIsObject13rs_allocation", (void *)&SC_IsObject, true },
+
+    { "_Z11rsSetObjectP10rs_samplerS_", (void *)&SC_SetObject, true },
+    { "_Z13rsClearObjectP10rs_sampler", (void *)&SC_ClearObject, true },
+    { "_Z10rsIsObject10rs_sampler", (void *)&SC_IsObject, true },
+
+    { "_Z11rsSetObjectP9rs_scriptS_", (void *)&SC_SetObject, true },
+    { "_Z13rsClearObjectP9rs_script", (void *)&SC_ClearObject, true },
+    { "_Z10rsIsObject9rs_script", (void *)&SC_IsObject, true },
+
+    { "_Z11rsSetObjectP7rs_meshS_", (void *)&SC_SetObject, true },
+    { "_Z13rsClearObjectP7rs_mesh", (void *)&SC_ClearObject, true },
+    { "_Z10rsIsObject7rs_mesh", (void *)&SC_IsObject, true },
+
+    { "_Z11rsSetObjectP19rs_program_fragmentS_", (void *)&SC_SetObject, true },
+    { "_Z13rsClearObjectP19rs_program_fragment", (void *)&SC_ClearObject, true },
+    { "_Z10rsIsObject19rs_program_fragment", (void *)&SC_IsObject, true },
+
+    { "_Z11rsSetObjectP17rs_program_vertexS_", (void *)&SC_SetObject, true },
+    { "_Z13rsClearObjectP17rs_program_vertex", (void *)&SC_ClearObject, true },
+    { "_Z10rsIsObject17rs_program_vertex", (void *)&SC_IsObject, true },
+
+    { "_Z11rsSetObjectP17rs_program_rasterS_", (void *)&SC_SetObject, true },
+    { "_Z13rsClearObjectP17rs_program_raster", (void *)&SC_ClearObject, true },
+    { "_Z10rsIsObject17rs_program_raster", (void *)&SC_IsObject, true },
+
+    { "_Z11rsSetObjectP16rs_program_storeS_", (void *)&SC_SetObject, true },
+    { "_Z13rsClearObjectP16rs_program_store", (void *)&SC_ClearObject, true },
+    { "_Z10rsIsObject16rs_program_store", (void *)&SC_IsObject, true },
+
+    { "_Z11rsSetObjectP7rs_fontS_", (void *)&SC_SetObject, true },
+    { "_Z13rsClearObjectP7rs_font", (void *)&SC_ClearObject, true },
+    { "_Z10rsIsObject7rs_font", (void *)&SC_IsObject, true },
+
+    // Allocation ops
+    { "_Z19rsAllocationGetDimX13rs_allocation", (void *)&SC_allocGetDimX, true },
+    { "_Z19rsAllocationGetDimY13rs_allocation", (void *)&SC_allocGetDimY, true },
+    { "_Z19rsAllocationGetDimZ13rs_allocation", (void *)&SC_allocGetDimZ, true },
+    { "_Z21rsAllocationGetDimLOD13rs_allocation", (void *)&SC_allocGetDimLOD, true },
+    { "_Z23rsAllocationGetDimFaces13rs_allocation", (void *)&SC_allocGetDimFaces, true },
+
+    { "_Z14rsGetElementAt13rs_allocationj", (void *)&SC_getElementAtX, true },
+    { "_Z14rsGetElementAt13rs_allocationjj", (void *)&SC_getElementAtXY, true },
+    { "_Z14rsGetElementAt13rs_allocationjjj", (void *)&SC_getElementAtXYZ, true },
+
+    { "_Z15rsGetAllocationPKv", (void *)&SC_getAllocation, true },
+
+    { "_Z21rsAllocationMarkDirty13rs_allocation", (void *)&SC_AllocationSyncAll, true },
+    { "_Z20rsgAllocationSyncAll13rs_allocation", (void *)&SC_AllocationSyncAll, false },
+    { "_Z20rsgAllocationSyncAll13rs_allocationj", (void *)&SC_AllocationSyncAll2, false },
+    { "_Z15rsGetAllocationPKv", (void *)&SC_GetAllocation, true },
+
+
+    // Messaging
+
+    { "_Z14rsSendToClienti", (void *)&SC_ToClient, false },
+    { "_Z14rsSendToClientiPKvj", (void *)&SC_ToClient2, false },
+    { "_Z22rsSendToClientBlockingi", (void *)&SC_ToClientBlocking, false },
+    { "_Z22rsSendToClientBlockingiPKvj", (void *)&SC_ToClientBlocking2, false },
+
+    { "_Z22rsgBindProgramFragment19rs_program_fragment", (void *)&SC_BindProgramFragment, false },
+    { "_Z19rsgBindProgramStore16rs_program_store", (void *)&SC_BindProgramStore, false },
+    { "_Z20rsgBindProgramVertex17rs_program_vertex", (void *)&SC_BindProgramVertex, false },
+    { "_Z20rsgBindProgramRaster17rs_program_raster", (void *)&SC_BindProgramRaster, false },
+    { "_Z14rsgBindSampler19rs_program_fragmentj10rs_sampler", (void *)&SC_BindSampler, false },
+    { "_Z14rsgBindTexture19rs_program_fragmentj13rs_allocation", (void *)&SC_BindTexture, false },
+
+    { "_Z36rsgProgramVertexLoadProjectionMatrixPK12rs_matrix4x4", (void *)&SC_VpLoadProjectionMatrix, false },
+    { "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4", (void *)&SC_VpLoadModelMatrix, false },
+    { "_Z33rsgProgramVertexLoadTextureMatrixPK12rs_matrix4x4", (void *)&SC_VpLoadTextureMatrix, false },
+
+    { "_Z35rsgProgramVertexGetProjectionMatrixP12rs_matrix4x4", (void *)&SC_VpGetProjectionMatrix, false },
+
+    { "_Z31rsgProgramFragmentConstantColor19rs_program_fragmentffff", (void *)&SC_PfConstantColor, false },
+
+    { "_Z11rsgGetWidthv", (void *)&SC_GetWidth, false },
+    { "_Z12rsgGetHeightv", (void *)&SC_GetHeight, false },
+
+
+    { "_Z11rsgDrawRectfffff", (void *)&SC_DrawRect, false },
+    { "_Z11rsgDrawQuadffffffffffff", (void *)&SC_DrawQuad, false },
+    { "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff", (void *)&SC_DrawQuadTexCoords, false },
+    { "_Z24rsgDrawSpriteScreenspacefffff", (void *)&SC_DrawSpriteScreenspace, false },
+
+    { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_DrawMesh, false },
+    { "_Z11rsgDrawMesh7rs_meshj", (void *)&SC_DrawMeshPrimitive, false },
+    { "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_DrawMeshPrimitiveRange, false },
+    { "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_MeshComputeBoundingBox, false },
+
+    { "_Z13rsgClearColorffff", (void *)&SC_ClearColor, false },
+    { "_Z13rsgClearDepthf", (void *)&SC_ClearDepth, false },
+
+    { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText, false },
+    { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc, false },
+    { "_Z14rsgMeasureTextPKcPiS1_S1_S1_", (void *)&SC_MeasureText, false },
+    { "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_", (void *)&SC_MeasureTextAlloc, false },
+
+    { "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont, false },
+    { "_Z12rsgFontColorffff", (void *)&SC_FontColor, false },
+
+    { "_Z18rsgBindColorTarget13rs_allocationj", (void *)&SC_BindFrameBufferObjectColorTarget, false },
+    { "_Z18rsgBindDepthTarget13rs_allocation", (void *)&SC_BindFrameBufferObjectDepthTarget, false },
+    { "_Z19rsgClearColorTargetj", (void *)&SC_ClearFrameBufferObjectColorTarget, false },
+    { "_Z19rsgClearDepthTargetv", (void *)&SC_ClearFrameBufferObjectDepthTarget, false },
+    { "_Z24rsgClearAllRenderTargetsv", (void *)&SC_ClearFrameBufferObjectTargets, false },
+
+    { "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach, false },
+    { "_Z9rsForEach9rs_script13rs_allocationS0_PKvj", (void *)&SC_ForEach2, false },
+
+    // time
+    { "_Z6rsTimePi", (void *)&SC_Time, true },
+    { "_Z11rsLocaltimeP5rs_tmPKi", (void *)&SC_LocalTime, true },
+    { "_Z14rsUptimeMillisv", (void*)&SC_UptimeMillis, true },
+    { "_Z13rsUptimeNanosv", (void*)&SC_UptimeNanos, true },
+    { "_Z7rsGetDtv", (void*)&SC_GetDt, false },
+
+    // misc
+    { "_Z5colorffff", (void *)&SC_Color, false },
+    { "_Z9rsgFinishv", (void *)&SC_Finish, false },
+
+    // Debug
+    { "_Z7rsDebugPKcf", (void *)&SC_debugF, true },
+    { "_Z7rsDebugPKcff", (void *)&SC_debugFv2, true },
+    { "_Z7rsDebugPKcfff", (void *)&SC_debugFv3, true },
+    { "_Z7rsDebugPKcffff", (void *)&SC_debugFv4, true },
+    { "_Z7rsDebugPKcd", (void *)&SC_debugD, true },
+    { "_Z7rsDebugPKcPK12rs_matrix4x4", (void *)&SC_debugFM4v4, true },
+    { "_Z7rsDebugPKcPK12rs_matrix3x3", (void *)&SC_debugFM3v3, true },
+    { "_Z7rsDebugPKcPK12rs_matrix2x2", (void *)&SC_debugFM2v2, true },
+    { "_Z7rsDebugPKci", (void *)&SC_debugI32, true },
+    { "_Z7rsDebugPKcj", (void *)&SC_debugU32, true },
+    // Both "long" and "unsigned long" need to be redirected to their
+    // 64-bit counterparts, since we have hacked Slang to use 64-bit
+    // for "long" on Arm (to be similar to Java).
+    { "_Z7rsDebugPKcl", (void *)&SC_debugLL64, true },
+    { "_Z7rsDebugPKcm", (void *)&SC_debugULL64, true },
+    { "_Z7rsDebugPKcx", (void *)&SC_debugLL64, true },
+    { "_Z7rsDebugPKcy", (void *)&SC_debugULL64, true },
+    { "_Z7rsDebugPKcPKv", (void *)&SC_debugP, true },
+
+    { NULL, NULL, false }
+};
+
+
+void* rsdLookupRuntimeStub(void* pContext, char const* name) {
+    ScriptC *s = (ScriptC *)pContext;
+    if (!strcmp(name, "__isThreadable")) {
+      return (void*) s->mHal.info.isThreadable;
+    } else if (!strcmp(name, "__clearThreadable")) {
+      s->mHal.info.isThreadable = false;
+      return NULL;
+    }
+
+    RsdSymbolTable *syms = gSyms;
+    const RsdSymbolTable *sym = rsdLookupSymbolMath(name);
+
+    if (!sym) {
+        while (syms->mPtr) {
+            if (!strcmp(syms->mName, name)) {
+                sym = syms;
+            }
+            syms++;
+        }
+    }
+
+    if (sym) {
+        s->mHal.info.isThreadable &= sym->threadable;
+        return sym->mPtr;
+    }
+    LOGE("ScriptC sym lookup failed for %s", name);
+    return NULL;
+}
+
+
diff --git a/driver/rsdSampler.cpp b/driver/rsdSampler.cpp
new file mode 100644
index 0000000..af48c61
--- /dev/null
+++ b/driver/rsdSampler.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2011 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 "rsdCore.h"
+#include "rsdSampler.h"
+
+#include "rsContext.h"
+#include "rsSampler.h"
+#include "rsProgramVertex.h"
+#include "rsProgramFragment.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+
+using namespace android;
+using namespace android::renderscript;
+
+bool rsdSamplerInit(const android::renderscript::Context *,
+                    const android::renderscript::Sampler *) {
+    return true;
+}
+
+void rsdSamplerDestroy(const android::renderscript::Context *rsc,
+                       const android::renderscript::Sampler *s) {
+}
diff --git a/driver/rsdSampler.h b/driver/rsdSampler.h
new file mode 100644
index 0000000..3a64e9e
--- /dev/null
+++ b/driver/rsdSampler.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_SAMPLER_H
+#define RSD_SAMPLER_H
+
+#include <rs_hal.h>
+
+
+bool rsdSamplerInit(const android::renderscript::Context *rsc,
+                    const android::renderscript::Sampler *);
+
+void rsdSamplerDestroy(const android::renderscript::Context *rsc,
+                       const android::renderscript::Sampler *);
+
+
+#endif // RSD_SAMPLER_H
diff --git a/driver/rsdShader.cpp b/driver/rsdShader.cpp
new file mode 100644
index 0000000..371266b
--- /dev/null
+++ b/driver/rsdShader.cpp
@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 2011 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 <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <rs_hal.h>
+#include <rsContext.h>
+#include <rsProgram.h>
+
+#include "rsdCore.h"
+#include "rsdShader.h"
+#include "rsdShaderCache.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+RsdShader::RsdShader(const Program *p, uint32_t type,
+                       const char * shaderText, uint32_t shaderLength) {
+
+    mUserShader.setTo(shaderText, shaderLength);
+    mRSProgram = p;
+    mType = type;
+    initMemberVars();
+    initAttribAndUniformArray();
+    init();
+}
+
+RsdShader::~RsdShader() {
+    if (mShaderID) {
+        glDeleteShader(mShaderID);
+    }
+
+    delete[] mAttribNames;
+    delete[] mUniformNames;
+    delete[] mUniformArraySizes;
+}
+
+void RsdShader::initMemberVars() {
+    mDirty = true;
+    mShaderID = 0;
+    mAttribCount = 0;
+    mUniformCount = 0;
+
+    mAttribNames = NULL;
+    mUniformNames = NULL;
+    mUniformArraySizes = NULL;
+
+    mIsValid = false;
+}
+
+void RsdShader::init() {
+    uint32_t attribCount = 0;
+    uint32_t uniformCount = 0;
+    for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
+        initAddUserElement(mRSProgram->mHal.state.inputElements[ct].get(), mAttribNames, NULL, &attribCount, RS_SHADER_ATTR);
+    }
+    for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
+        initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
+    }
+
+    mTextureUniformIndexStart = uniformCount;
+    char buf[256];
+    for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
+        snprintf(buf, sizeof(buf), "UNI_Tex%i", ct);
+        mUniformNames[uniformCount].setTo(buf);
+        mUniformArraySizes[uniformCount] = 1;
+        uniformCount++;
+    }
+}
+
+String8 RsdShader::getGLSLInputString() const {
+    String8 s;
+    for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
+        const Element *e = mRSProgram->mHal.state.inputElements[ct].get();
+        for (uint32_t field=0; field < e->getFieldCount(); field++) {
+            const Element *f = e->getField(field);
+
+            // Cannot be complex
+            rsAssert(!f->getFieldCount());
+            switch (f->getComponent().getVectorSize()) {
+            case 1: s.append("attribute float ATTRIB_"); break;
+            case 2: s.append("attribute vec2 ATTRIB_"); break;
+            case 3: s.append("attribute vec3 ATTRIB_"); break;
+            case 4: s.append("attribute vec4 ATTRIB_"); break;
+            default:
+                rsAssert(0);
+            }
+
+            s.append(e->getFieldName(field));
+            s.append(";\n");
+        }
+    }
+    return s;
+}
+
+void RsdShader::appendAttributes() {
+    for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
+        const Element *e = mRSProgram->mHal.state.inputElements[ct].get();
+        for (uint32_t field=0; field < e->getFieldCount(); field++) {
+            const Element *f = e->getField(field);
+            const char *fn = e->getFieldName(field);
+
+            if (fn[0] == '#') {
+                continue;
+            }
+
+            // Cannot be complex
+            rsAssert(!f->getFieldCount());
+            switch (f->getComponent().getVectorSize()) {
+            case 1: mShader.append("attribute float ATTRIB_"); break;
+            case 2: mShader.append("attribute vec2 ATTRIB_"); break;
+            case 3: mShader.append("attribute vec3 ATTRIB_"); break;
+            case 4: mShader.append("attribute vec4 ATTRIB_"); break;
+            default:
+                rsAssert(0);
+            }
+
+            mShader.append(fn);
+            mShader.append(";\n");
+        }
+    }
+}
+
+void RsdShader::appendTextures() {
+    char buf[256];
+    for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
+        if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
+            snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
+        } else {
+            snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
+        }
+        mShader.append(buf);
+    }
+}
+
+bool RsdShader::createShader() {
+
+    if (mType == GL_FRAGMENT_SHADER) {
+        mShader.append("precision mediump float;\n");
+    }
+    appendUserConstants();
+    appendAttributes();
+    appendTextures();
+
+    mShader.append(mUserShader);
+
+    return true;
+}
+
+bool RsdShader::loadShader(const Context *rsc) {
+    mShaderID = glCreateShader(mType);
+    rsAssert(mShaderID);
+
+    if (rsc->props.mLogShaders) {
+        LOGV("Loading shader type %x, ID %i", mType, mShaderID);
+        LOGV("%s", mShader.string());
+    }
+
+    if (mShaderID) {
+        const char * ss = mShader.string();
+        glShaderSource(mShaderID, 1, &ss, NULL);
+        glCompileShader(mShaderID);
+
+        GLint compiled = 0;
+        glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
+        if (!compiled) {
+            GLint infoLen = 0;
+            glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
+            if (infoLen) {
+                char* buf = (char*) malloc(infoLen);
+                if (buf) {
+                    glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
+                    LOGE("Could not compile shader \n%s\n", buf);
+                    free(buf);
+                }
+                glDeleteShader(mShaderID);
+                mShaderID = 0;
+                rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,");
+                return false;
+            }
+        }
+    }
+
+    if (rsc->props.mLogShaders) {
+        LOGV("--Shader load result %x ", glGetError());
+    }
+    mIsValid = true;
+    return true;
+}
+
+void RsdShader::appendUserConstants() {
+    for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
+        const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
+        for (uint32_t field=0; field < e->getFieldCount(); field++) {
+            const Element *f = e->getField(field);
+            const char *fn = e->getFieldName(field);
+
+            if (fn[0] == '#') {
+                continue;
+            }
+
+            // Cannot be complex
+            rsAssert(!f->getFieldCount());
+            if (f->getType() == RS_TYPE_MATRIX_4X4) {
+                mShader.append("uniform mat4 UNI_");
+            } else if (f->getType() == RS_TYPE_MATRIX_3X3) {
+                mShader.append("uniform mat3 UNI_");
+            } else if (f->getType() == RS_TYPE_MATRIX_2X2) {
+                mShader.append("uniform mat2 UNI_");
+            } else {
+                switch (f->getComponent().getVectorSize()) {
+                case 1: mShader.append("uniform float UNI_"); break;
+                case 2: mShader.append("uniform vec2 UNI_"); break;
+                case 3: mShader.append("uniform vec3 UNI_"); break;
+                case 4: mShader.append("uniform vec4 UNI_"); break;
+                default:
+                    rsAssert(0);
+                }
+            }
+
+            mShader.append(fn);
+            if (e->getFieldArraySize(field) > 1) {
+                mShader.appendFormat("[%d]", e->getFieldArraySize(field));
+            }
+            mShader.append(";\n");
+        }
+    }
+}
+
+void RsdShader::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
+    RsDataType dataType = field->getType();
+    uint32_t elementSize = field->getSizeBytes() / sizeof(float);
+    for (uint32_t i = 0; i < arraySize; i ++) {
+        if (arraySize > 1) {
+            LOGV("Array Element [%u]", i);
+        }
+        if (dataType == RS_TYPE_MATRIX_4X4) {
+            LOGV("Matrix4x4");
+            LOGV("{%f, %f, %f, %f",  fd[0], fd[4], fd[8], fd[12]);
+            LOGV(" %f, %f, %f, %f",  fd[1], fd[5], fd[9], fd[13]);
+            LOGV(" %f, %f, %f, %f",  fd[2], fd[6], fd[10], fd[14]);
+            LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
+        } else if (dataType == RS_TYPE_MATRIX_3X3) {
+            LOGV("Matrix3x3");
+            LOGV("{%f, %f, %f",  fd[0], fd[3], fd[6]);
+            LOGV(" %f, %f, %f",  fd[1], fd[4], fd[7]);
+            LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
+        } else if (dataType == RS_TYPE_MATRIX_2X2) {
+            LOGV("Matrix2x2");
+            LOGV("{%f, %f",  fd[0], fd[2]);
+            LOGV(" %f, %f}", fd[1], fd[3]);
+        } else {
+            switch (field->getComponent().getVectorSize()) {
+            case 1:
+                LOGV("Uniform 1 = %f", fd[0]);
+                break;
+            case 2:
+                LOGV("Uniform 2 = %f %f", fd[0], fd[1]);
+                break;
+            case 3:
+                LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
+                break;
+            case 4:
+                LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
+                break;
+            default:
+                rsAssert(0);
+            }
+        }
+        LOGE("Element size %u data=%p", elementSize, fd);
+        fd += elementSize;
+        LOGE("New data=%p", fd);
+    }
+}
+
+void RsdShader::setUniform(const Context *rsc, const Element *field, const float *fd,
+                         int32_t slot, uint32_t arraySize ) {
+    RsDataType dataType = field->getType();
+    if (dataType == RS_TYPE_MATRIX_4X4) {
+        glUniformMatrix4fv(slot, arraySize, GL_FALSE, fd);
+    } else if (dataType == RS_TYPE_MATRIX_3X3) {
+        glUniformMatrix3fv(slot, arraySize, GL_FALSE, fd);
+    } else if (dataType == RS_TYPE_MATRIX_2X2) {
+        glUniformMatrix2fv(slot, arraySize, GL_FALSE, fd);
+    } else {
+        switch (field->getComponent().getVectorSize()) {
+        case 1:
+            glUniform1fv(slot, arraySize, fd);
+            break;
+        case 2:
+            glUniform2fv(slot, arraySize, fd);
+            break;
+        case 3:
+            glUniform3fv(slot, arraySize, fd);
+            break;
+        case 4:
+            glUniform4fv(slot, arraySize, fd);
+            break;
+        default:
+            rsAssert(0);
+        }
+    }
+}
+
+void RsdShader::setupSampler(const Context *rsc, const Sampler *s, const Allocation *tex) {
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+    GLenum trans[] = {
+        GL_NEAREST, //RS_SAMPLER_NEAREST,
+        GL_LINEAR, //RS_SAMPLER_LINEAR,
+        GL_LINEAR_MIPMAP_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
+        GL_REPEAT, //RS_SAMPLER_WRAP,
+        GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
+        GL_LINEAR_MIPMAP_NEAREST, //RS_SAMPLER_LINEAR_MIP_NEAREST
+    };
+
+    GLenum transNP[] = {
+        GL_NEAREST, //RS_SAMPLER_NEAREST,
+        GL_LINEAR, //RS_SAMPLER_LINEAR,
+        GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
+        GL_CLAMP_TO_EDGE, //RS_SAMPLER_WRAP,
+        GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
+        GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_NEAREST,
+    };
+
+    // This tells us the correct texture type
+    GLenum target = (GLenum)tex->getGLTarget();
+
+    if (!dc->gl.gl.OES_texture_npot && tex->getType()->getIsNp2()) {
+        if (tex->getHasGraphicsMipmaps() &&
+            (dc->gl.gl.GL_NV_texture_npot_2D_mipmap || dc->gl.gl.GL_IMG_texture_npot)) {
+            if (dc->gl.gl.GL_NV_texture_npot_2D_mipmap) {
+                glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[s->mHal.state.minFilter]);
+            } else {
+                switch (trans[s->mHal.state.minFilter]) {
+                case GL_LINEAR_MIPMAP_LINEAR:
+                    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+                    break;
+                default:
+                    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[s->mHal.state.minFilter]);
+                    break;
+                }
+            }
+        } else {
+            glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[s->mHal.state.minFilter]);
+        }
+        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, transNP[s->mHal.state.magFilter]);
+        glTexParameteri(target, GL_TEXTURE_WRAP_S, transNP[s->mHal.state.wrapS]);
+        glTexParameteri(target, GL_TEXTURE_WRAP_T, transNP[s->mHal.state.wrapT]);
+    } else {
+        if (tex->getHasGraphicsMipmaps()) {
+            glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[s->mHal.state.minFilter]);
+        } else {
+            glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[s->mHal.state.minFilter]);
+        }
+        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, trans[s->mHal.state.magFilter]);
+        glTexParameteri(target, GL_TEXTURE_WRAP_S, trans[s->mHal.state.wrapS]);
+        glTexParameteri(target, GL_TEXTURE_WRAP_T, trans[s->mHal.state.wrapT]);
+    }
+
+    float anisoValue = rsMin(dc->gl.gl.EXT_texture_max_aniso, s->mHal.state.aniso);
+    if (dc->gl.gl.EXT_texture_max_aniso > 1.0f) {
+        glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue);
+    }
+
+    rsdGLCheckError(rsc, "Sampler::setup tex env");
+}
+
+void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) {
+    if (mRSProgram->mHal.state.texturesCount == 0) {
+        return;
+    }
+
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+    uint32_t numTexturesToBind = mRSProgram->mHal.state.texturesCount;
+    uint32_t numTexturesAvailable = dc->gl.gl.maxFragmentTextureImageUnits;
+    if (numTexturesToBind >= numTexturesAvailable) {
+        LOGE("Attempting to bind %u textures on shader id %u, but only %u are available",
+             mRSProgram->mHal.state.texturesCount, (uint32_t)this, numTexturesAvailable);
+        rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available");
+        numTexturesToBind = numTexturesAvailable;
+    }
+
+    for (uint32_t ct=0; ct < numTexturesToBind; ct++) {
+        glActiveTexture(GL_TEXTURE0 + ct);
+        if (!mRSProgram->mHal.state.textures[ct].get()) {
+            LOGE("No texture bound for shader id %u, texture unit %u", (uint)this, ct);
+            rsc->setError(RS_ERROR_BAD_SHADER, "No texture bound");
+            continue;
+        }
+
+        GLenum target = (GLenum)mRSProgram->mHal.state.textures[ct]->getGLTarget();
+        if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) {
+            LOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct);
+            rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
+        }
+        glBindTexture(target, mRSProgram->mHal.state.textures[ct]->getTextureID());
+        rsdGLCheckError(rsc, "ProgramFragment::setup tex bind");
+        if (mRSProgram->mHal.state.samplers[ct].get()) {
+            setupSampler(rsc, mRSProgram->mHal.state.samplers[ct].get(), mRSProgram->mHal.state.textures[ct].get());
+        } else {
+            glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+            glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+            glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+            glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+            rsdGLCheckError(rsc, "ProgramFragment::setup tex env");
+        }
+
+        glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
+        rsdGLCheckError(rsc, "ProgramFragment::setup uniforms");
+    }
+
+    glActiveTexture(GL_TEXTURE0);
+    mDirty = false;
+    rsdGLCheckError(rsc, "ProgramFragment::setup");
+}
+
+void RsdShader::setupUserConstants(const Context *rsc, RsdShaderCache *sc, bool isFragment) {
+    uint32_t uidx = 0;
+    for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
+        Allocation *alloc = mRSProgram->mHal.state.constants[ct].get();
+        if (!alloc) {
+            LOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set", (uint32_t)this, ct);
+            rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
+            continue;
+        }
+
+        const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
+        const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
+        for (uint32_t field=0; field < e->getFieldCount(); field++) {
+            const Element *f = e->getField(field);
+            const char *fieldName = e->getFieldName(field);
+            // If this field is padding, skip it
+            if (fieldName[0] == '#') {
+                continue;
+            }
+
+            uint32_t offset = e->getFieldOffsetBytes(field);
+            const float *fd = reinterpret_cast<const float *>(&data[offset]);
+
+            int32_t slot = -1;
+            uint32_t arraySize = 1;
+            if (!isFragment) {
+                slot = sc->vtxUniformSlot(uidx);
+                arraySize = sc->vtxUniformSize(uidx);
+            } else {
+                slot = sc->fragUniformSlot(uidx);
+                arraySize = sc->fragUniformSize(uidx);
+            }
+            if (rsc->props.mLogShadersUniforms) {
+                LOGV("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
+            }
+            uidx ++;
+            if (slot < 0) {
+                continue;
+            }
+
+            if (rsc->props.mLogShadersUniforms) {
+                logUniform(f, fd, arraySize);
+            }
+            setUniform(rsc, f, fd, slot, arraySize);
+        }
+    }
+}
+
+void RsdShader::setup(const android::renderscript::Context *rsc, RsdShaderCache *sc) {
+
+    setupUserConstants(rsc, sc, mType == GL_FRAGMENT_SHADER);
+    setupTextures(rsc, sc);
+}
+
+void RsdShader::initAttribAndUniformArray() {
+    mAttribCount = 0;
+    for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
+        const Element *elem = mRSProgram->mHal.state.inputElements[ct].get();
+        for (uint32_t field=0; field < elem->getFieldCount(); field++) {
+            if (elem->getFieldName(field)[0] != '#') {
+                mAttribCount ++;
+            }
+        }
+    }
+
+    mUniformCount = 0;
+    for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
+        const Element *elem = mRSProgram->mHal.state.constantTypes[ct]->getElement();
+
+        for (uint32_t field=0; field < elem->getFieldCount(); field++) {
+            if (elem->getFieldName(field)[0] != '#') {
+                mUniformCount ++;
+            }
+        }
+    }
+    mUniformCount += mRSProgram->mHal.state.texturesCount;
+
+    if (mAttribCount) {
+        mAttribNames = new String8[mAttribCount];
+    }
+    if (mUniformCount) {
+        mUniformNames = new String8[mUniformCount];
+        mUniformArraySizes = new uint32_t[mUniformCount];
+    }
+}
+
+void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix) {
+    rsAssert(e->getFieldCount());
+    for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
+        const Element *ce = e->getField(ct);
+        if (ce->getFieldCount()) {
+            initAddUserElement(ce, names, arrayLengths, count, prefix);
+        } else if (e->getFieldName(ct)[0] != '#') {
+            String8 tmp(prefix);
+            tmp.append(e->getFieldName(ct));
+            names[*count].setTo(tmp.string());
+            if (arrayLengths) {
+                arrayLengths[*count] = e->getFieldArraySize(ct);
+            }
+            (*count)++;
+        }
+    }
+}
diff --git a/driver/rsdShader.h b/driver/rsdShader.h
new file mode 100644
index 0000000..63c4231
--- /dev/null
+++ b/driver/rsdShader.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RSD_SHADER_H
+#define ANDROID_RSD_SHADER_H
+
+#include <utils/String8.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class Element;
+class Context;
+class Program;
+
+}
+}
+
+class RsdShaderCache;
+
+#define RS_SHADER_ATTR "ATTRIB_"
+#define RS_SHADER_UNI "UNI_"
+
+class RsdShader {
+public:
+
+    RsdShader(const android::renderscript::Program *p, uint32_t type,
+               const char * shaderText, uint32_t shaderLength);
+    virtual ~RsdShader();
+
+    bool createShader();
+
+    uint32_t getShaderID() const {return mShaderID;}
+
+    uint32_t getAttribCount() const {return mAttribCount;}
+    uint32_t getUniformCount() const {return mUniformCount;}
+    const android::String8 & getAttribName(uint32_t i) const {return mAttribNames[i];}
+    const android::String8 & getUniformName(uint32_t i) const {return mUniformNames[i];}
+    uint32_t getUniformArraySize(uint32_t i) const {return mUniformArraySizes[i];}
+
+    android::String8 getGLSLInputString() const;
+
+    bool isValid() const {return mIsValid;}
+    void forceDirty() const {mDirty = true;}
+
+    bool loadShader(const android::renderscript::Context *);
+    void setup(const android::renderscript::Context *, RsdShaderCache *sc);
+
+protected:
+
+    const android::renderscript::Program *mRSProgram;
+    bool mIsValid;
+
+    // Applies to vertex and fragment shaders only
+    void appendUserConstants();
+    void setupUserConstants(const android::renderscript::Context *rsc, RsdShaderCache *sc, bool isFragment);
+    void initAddUserElement(const android::renderscript::Element *e, android::String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix);
+    void setupTextures(const android::renderscript::Context *rsc, RsdShaderCache *sc);
+    void setupSampler(const android::renderscript::Context *rsc, const android::renderscript::Sampler *s, const android::renderscript::Allocation *tex);
+
+    void appendAttributes();
+    void appendTextures();
+
+    void initAttribAndUniformArray();
+
+    mutable bool mDirty;
+    android::String8 mShader;
+    android::String8 mUserShader;
+    uint32_t mShaderID;
+    uint32_t mType;
+
+    uint32_t mTextureCount;
+    uint32_t mAttribCount;
+    uint32_t mUniformCount;
+    android::String8 *mAttribNames;
+    android::String8 *mUniformNames;
+    uint32_t *mUniformArraySizes;
+
+    int32_t mTextureUniformIndexStart;
+
+    void logUniform(const android::renderscript::Element *field, const float *fd, uint32_t arraySize );
+    void setUniform(const android::renderscript::Context *rsc, const android::renderscript::Element *field, const float *fd, int32_t slot, uint32_t arraySize );
+    void initMemberVars();
+    void init();
+};
+
+#endif //ANDROID_RSD_SHADER_H
+
+
+
+
diff --git a/rsShaderCache.cpp b/driver/rsdShaderCache.cpp
similarity index 81%
rename from rsShaderCache.cpp
rename to driver/rsdShaderCache.cpp
index b958021..d11490c 100644
--- a/rsShaderCache.cpp
+++ b/driver/rsdShaderCache.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -14,28 +14,31 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
-#include "rsContext.h"
+#include <rs_hal.h>
+#include <rsContext.h>
+
+#include "rsdShader.h"
+#include "rsdShaderCache.h"
+#include "rsdGL.h"
+
 #include <GLES/gl.h>
 #include <GLES2/gl2.h>
-#else
-#include "rsContextHostStub.h"
-#include <OpenGL/gl.h>
-#endif //ANDROID_RS_BUILD_FOR_HOST
 
 using namespace android;
 using namespace android::renderscript;
 
 
-ShaderCache::ShaderCache() {
+RsdShaderCache::RsdShaderCache() {
     mEntries.setCapacity(16);
+    mVertexDirty = true;
+    mFragmentDirty = true;
 }
 
-ShaderCache::~ShaderCache() {
+RsdShaderCache::~RsdShaderCache() {
     cleanupAll();
 }
 
-void ShaderCache::updateUniformArrayData(Context *rsc, Program *prog, uint32_t linkedID,
+void RsdShaderCache::updateUniformArrayData(const Context *rsc, RsdShader *prog, uint32_t linkedID,
                                          UniformData *data, const char* logTag,
                                          UniformQueryData **uniformList, uint32_t uniListSize) {
 
@@ -57,14 +60,14 @@
     }
 }
 
-void ShaderCache::populateUniformData(Program *prog, uint32_t linkedID, UniformData *data) {
+void RsdShaderCache::populateUniformData(RsdShader *prog, uint32_t linkedID, UniformData *data) {
     for (uint32_t ct=0; ct < prog->getUniformCount(); ct++) {
        data[ct].slot = glGetUniformLocation(linkedID, prog->getUniformName(ct));
        data[ct].arraySize = prog->getUniformArraySize(ct);
     }
 }
 
-bool ShaderCache::hasArrayUniforms(ProgramVertex *vtx, ProgramFragment *frag) {
+bool RsdShaderCache::hasArrayUniforms(RsdShader *vtx, RsdShader *frag) {
     UniformData *data = mCurrent->vtxUniforms;
     for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) {
         if (data[ct].slot >= 0 && data[ct].arraySize > 1) {
@@ -80,7 +83,31 @@
     return false;
 }
 
-bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag) {
+bool RsdShaderCache::setup(const Context *rsc) {
+    if (!mVertexDirty && !mFragmentDirty) {
+        return true;
+    }
+
+    if (!link(rsc)) {
+        return false;
+    }
+
+    if (mFragmentDirty) {
+        mFragment->setup(rsc, this);
+        mFragmentDirty = false;
+    }
+    if (mVertexDirty) {
+        mVertex->setup(rsc, this);
+        mVertexDirty = false;
+    }
+
+    return true;
+}
+
+bool RsdShaderCache::link(const Context *rsc) {
+
+    RsdShader *vtx = mVertex;
+    RsdShader *frag = mFragment;
     if (!vtx->getShaderID()) {
         vtx->loadShader(rsc);
     }
@@ -92,7 +119,7 @@
     if (!vtx->getShaderID() || !frag->getShaderID()) {
         return false;
     }
-    //LOGV("ShaderCache lookup  vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
+    //LOGV("rsdShaderCache lookup  vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
     uint32_t entryCount = mEntries.size();
     for (uint32_t ct = 0; ct < entryCount; ct ++) {
         if ((mEntries[ct]->vtx == vtx->getShaderID()) &&
@@ -101,13 +128,13 @@
             //LOGV("SC using program %i", mEntries[ct]->program);
             glUseProgram(mEntries[ct]->program);
             mCurrent = mEntries[ct];
-            //LOGV("ShaderCache hit, using %i", ct);
-            rsc->checkError("ShaderCache::lookup (hit)");
+            //LOGV("RsdShaderCache hit, using %i", ct);
+            rsdGLCheckError(rsc, "RsdShaderCache::link (hit)");
             return true;
         }
     }
 
-    //LOGV("ShaderCache miss");
+    //LOGV("RsdShaderCache miss");
     //LOGE("e0 %x", glGetError());
     ProgramEntry *e = new ProgramEntry(vtx->getAttribCount(),
                                        vtx->getUniformCount(),
@@ -123,12 +150,10 @@
         //LOGE("e1 %x", glGetError());
         glAttachShader(pgm, frag->getShaderID());
 
-        if (!vtx->isUserProgram()) {
-            glBindAttribLocation(pgm, 0, "ATTRIB_position");
-            glBindAttribLocation(pgm, 1, "ATTRIB_color");
-            glBindAttribLocation(pgm, 2, "ATTRIB_normal");
-            glBindAttribLocation(pgm, 3, "ATTRIB_texture0");
-        }
+        glBindAttribLocation(pgm, 0, "ATTRIB_position");
+        glBindAttribLocation(pgm, 1, "ATTRIB_color");
+        glBindAttribLocation(pgm, 2, "ATTRIB_normal");
+        glBindAttribLocation(pgm, 3, "ATTRIB_texture0");
 
         //LOGE("e2 %x", glGetError());
         glLinkProgram(pgm);
@@ -206,11 +231,12 @@
 
     //LOGV("SC made program %i", e->program);
     glUseProgram(e->program);
-    rsc->checkError("ShaderCache::lookup (miss)");
+    rsdGLCheckError(rsc, "RsdShaderCache::link (miss)");
+
     return true;
 }
 
-int32_t ShaderCache::vtxAttribSlot(const String8 &attrName) const {
+int32_t RsdShaderCache::vtxAttribSlot(const String8 &attrName) const {
     for (uint32_t ct=0; ct < mCurrent->vtxAttrCount; ct++) {
         if (attrName == mCurrent->vtxAttrs[ct].name) {
             return mCurrent->vtxAttrs[ct].slot;
@@ -219,7 +245,7 @@
     return -1;
 }
 
-void ShaderCache::cleanupVertex(uint32_t id) {
+void RsdShaderCache::cleanupVertex(uint32_t id) {
     int32_t numEntries = (int32_t)mEntries.size();
     for (int32_t ct = 0; ct < numEntries; ct ++) {
         if (mEntries[ct]->vtx == id) {
@@ -233,7 +259,7 @@
     }
 }
 
-void ShaderCache::cleanupFragment(uint32_t id) {
+void RsdShaderCache::cleanupFragment(uint32_t id) {
     int32_t numEntries = (int32_t)mEntries.size();
     for (int32_t ct = 0; ct < numEntries; ct ++) {
         if (mEntries[ct]->frag == id) {
@@ -247,7 +273,7 @@
     }
 }
 
-void ShaderCache::cleanupAll() {
+void RsdShaderCache::cleanupAll() {
     for (uint32_t ct=0; ct < mEntries.size(); ct++) {
         glDeleteProgram(mEntries[ct]->program);
         free(mEntries[ct]);
diff --git a/rsShaderCache.h b/driver/rsdShaderCache.h
similarity index 74%
rename from rsShaderCache.h
rename to driver/rsdShaderCache.h
index 3540366..17ee3e8 100644
--- a/rsShaderCache.h
+++ b/driver/rsdShaderCache.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -14,38 +14,59 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SHADER_CACHE_H
-#define ANDROID_SHADER_CACHE_H
+#ifndef ANDROID_RSD_SHADER_CACHE_H
+#define ANDROID_RSD_SHADER_CACHE_H
 
-
-#include "rsObjectBase.h"
-#include "rsVertexArray.h"
-
-// ---------------------------------------------------------------------------
 namespace android {
 namespace renderscript {
 
+class Context;
+
+}
+}
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+class RsdShader;
+
+// ---------------------------------------------------------------------------
 
 // An element is a group of Components that occupies one cell in a structure.
-class ShaderCache {
+class RsdShaderCache {
 public:
-    ShaderCache();
-    virtual ~ShaderCache();
+    RsdShaderCache();
+    virtual ~RsdShaderCache();
 
-    bool lookup(Context *rsc, ProgramVertex *, ProgramFragment *);
+    void setActiveVertex(RsdShader *pv) {
+        mVertexDirty = true;
+        mVertex = pv;
+    }
+
+    void setActiveFragment(RsdShader *pf) {
+        mFragmentDirty = true;
+        mFragment = pf;
+    }
+
+    bool setup(const android::renderscript::Context *rsc);
 
     void cleanupVertex(uint32_t id);
     void cleanupFragment(uint32_t id);
 
     void cleanupAll();
 
-    int32_t vtxAttribSlot(const String8 &attrName) const;
+    int32_t vtxAttribSlot(const android::String8 &attrName) const;
     int32_t vtxUniformSlot(uint32_t a) const {return mCurrent->vtxUniforms[a].slot;}
     uint32_t vtxUniformSize(uint32_t a) const {return mCurrent->vtxUniforms[a].arraySize;}
     int32_t fragUniformSlot(uint32_t a) const {return mCurrent->fragUniforms[a].slot;}
     uint32_t fragUniformSize(uint32_t a) const {return mCurrent->fragUniforms[a].arraySize;}
 
 protected:
+    bool link(const android::renderscript::Context *rsc);
+    bool mFragmentDirty;
+    bool mVertexDirty;
+    RsdShader *mVertex;
+    RsdShader *mFragment;
+
     struct UniformQueryData {
         char *name;
         uint32_t nameLength;
@@ -111,21 +132,19 @@
         UniformData *vtxUniforms;
         UniformData *fragUniforms;
     };
-    Vector<ProgramEntry*> mEntries;
+    android::Vector<ProgramEntry*> mEntries;
     ProgramEntry *mCurrent;
 
-    bool hasArrayUniforms(ProgramVertex *vtx, ProgramFragment *frag);
-    void populateUniformData(Program *prog, uint32_t linkedID, UniformData *data);
-    void updateUniformArrayData(Context *rsc, Program *prog, uint32_t linkedID,
+    bool hasArrayUniforms(RsdShader *vtx, RsdShader *frag);
+    void populateUniformData(RsdShader *prog, uint32_t linkedID, UniformData *data);
+    void updateUniformArrayData(const android::renderscript::Context *rsc,
+                                RsdShader *prog, uint32_t linkedID,
                                 UniformData *data, const char* logTag,
                                 UniformQueryData **uniformList, uint32_t uniListSize);
 };
 
 
-
-}
-}
-#endif //ANDROID_SHADER_CACHE_H
+#endif //ANDROID_RSD_SHADER_CACHE_H
 
 
 
diff --git a/rsVertexArray.cpp b/driver/rsdVertexArray.cpp
similarity index 72%
rename from rsVertexArray.cpp
rename to driver/rsdVertexArray.cpp
index d9393fe..62ec107 100644
--- a/rsVertexArray.cpp
+++ b/driver/rsdVertexArray.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -14,31 +14,33 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
-#include "rsContext.h"
+#include <rs_hal.h>
+#include <rsContext.h>
+
 #include <GLES/gl.h>
 #include <GLES2/gl2.h>
-#else
-#include "rsContextHostStub.h"
-#include <OpenGL/gl.h>
-#endif
+
+#include "rsdGL.h"
+#include "rsdCore.h"
+#include "rsdVertexArray.h"
+#include "rsdShaderCache.h"
 
 using namespace android;
 using namespace android::renderscript;
 
-VertexArray::VertexArray(const Attrib *attribs, uint32_t numAttribs) {
+RsdVertexArray::RsdVertexArray(const Attrib *attribs, uint32_t numAttribs) {
     mAttribs = attribs;
     mCount = numAttribs;
 }
 
-VertexArray::~VertexArray() {
+RsdVertexArray::~RsdVertexArray() {
 }
 
-VertexArray::Attrib::Attrib() {
+RsdVertexArray::Attrib::Attrib() {
     clear();
 }
 
-void VertexArray::Attrib::clear() {
+void RsdVertexArray::Attrib::clear() {
     buffer = 0;
     offset = 0;
     type = 0;
@@ -49,7 +51,7 @@
     name.setTo("");
 }
 
-void VertexArray::Attrib::set(uint32_t type, uint32_t size, uint32_t stride,
+void RsdVertexArray::Attrib::set(uint32_t type, uint32_t size, uint32_t stride,
                               bool normalized, uint32_t offset,
                               const char *name) {
     clear();
@@ -61,7 +63,7 @@
     this->name.setTo(name);
 }
 
-void VertexArray::logAttrib(uint32_t idx, uint32_t slot) const {
+void RsdVertexArray::logAttrib(uint32_t idx, uint32_t slot) const {
     if (idx == 0) {
         LOGV("Starting vertex attribute binding");
     }
@@ -77,11 +79,15 @@
          mAttribs[idx].offset);
 }
 
-void VertexArray::setupGL2(const Context *rsc,
-                           class VertexArrayState *state,
-                           ShaderCache *sc) const {
-    rsc->checkError("VertexArray::setupGL2 start");
+void RsdVertexArray::setup(const Context *rsc) const {
+
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+    RsdVertexArrayState *state = dc->gl.vertexArrayState;
+    RsdShaderCache *sc = dc->gl.shaderCache;
+
+    rsdGLCheckError(rsc, "RsdVertexArray::setup start");
     uint32_t maxAttrs = state->mAttrsEnabledSize;
+
     for (uint32_t ct=1; ct < maxAttrs; ct++) {
         if(state->mAttrsEnabled[ct]) {
             glDisableVertexAttribArray(ct);
@@ -89,7 +95,7 @@
         }
     }
 
-    rsc->checkError("VertexArray::setupGL2 disabled");
+    rsdGLCheckError(rsc, "RsdVertexArray::setup disabled");
     for (uint32_t ct=0; ct < mCount; ct++) {
         int32_t slot = sc->vtxAttribSlot(mAttribs[ct].name);
         if (rsc->props.mLogShadersAttr) {
@@ -108,22 +114,22 @@
                               mAttribs[ct].stride,
                               mAttribs[ct].ptr + mAttribs[ct].offset);
     }
-    rsc->checkError("VertexArray::setupGL2 done");
+    rsdGLCheckError(rsc, "RsdVertexArray::setup done");
 }
 ////////////////////////////////////////////
-VertexArrayState::VertexArrayState() {
+RsdVertexArrayState::RsdVertexArrayState() {
     mAttrsEnabled = NULL;
     mAttrsEnabledSize = 0;
 }
 
-VertexArrayState::~VertexArrayState() {
+RsdVertexArrayState::~RsdVertexArrayState() {
     if (mAttrsEnabled) {
         delete[] mAttrsEnabled;
         mAttrsEnabled = NULL;
     }
 }
-void VertexArrayState::init(Context *rsc) {
-    mAttrsEnabledSize = rsc->getMaxVertexAttributes();
+void RsdVertexArrayState::init(uint32_t maxAttrs) {
+    mAttrsEnabledSize = maxAttrs;
     mAttrsEnabled = new bool[mAttrsEnabledSize];
     for (uint32_t ct = 0; ct < mAttrsEnabledSize; ct++) {
         mAttrsEnabled[ct] = false;
diff --git a/rsVertexArray.h b/driver/rsdVertexArray.h
similarity index 69%
rename from rsVertexArray.h
rename to driver/rsdVertexArray.h
index 45d9e82..3e807a3 100644
--- a/rsVertexArray.h
+++ b/driver/rsdVertexArray.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -14,20 +14,21 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_VERTEX_ARRAY_H
-#define ANDROID_VERTEX_ARRAY_H
+#ifndef ANDROID_RSD_VERTEX_ARRAY_H
+#define ANDROID_RSD_VERTEX_ARRAY_H
 
-
-#include "rsObjectBase.h"
-
-// ---------------------------------------------------------------------------
 namespace android {
 namespace renderscript {
 
-class ShaderCache;
+class Context;
+
+}
+}
+
+#include <utils/String8.h>
 
 // An element is a group of Components that occupies one cell in a structure.
-class VertexArray {
+class RsdVertexArray {
 public:
     class Attrib {
     public:
@@ -38,17 +39,17 @@
         uint32_t size;
         uint32_t stride;
         bool normalized;
-        String8 name;
+        android::String8 name;
 
         Attrib();
         void clear();
         void set(uint32_t type, uint32_t size, uint32_t stride, bool normalized, uint32_t offset, const char *name);
     };
 
-    VertexArray(const Attrib *attribs, uint32_t numAttribs);
-    virtual ~VertexArray();
+    RsdVertexArray(const Attrib *attribs, uint32_t numAttribs);
+    virtual ~RsdVertexArray();
 
-    void setupGL2(const Context *rsc, class VertexArrayState *, ShaderCache *) const;
+    void setup(const android::renderscript::Context *rsc) const;
     void logAttrib(uint32_t idx, uint32_t slot) const;
 
 protected:
@@ -61,20 +62,18 @@
 };
 
 
-class VertexArrayState {
+class RsdVertexArrayState {
 public:
-    VertexArrayState();
-    ~VertexArrayState();
-    void init(Context *);
+    RsdVertexArrayState();
+    ~RsdVertexArrayState();
+    void init(uint32_t maxAttrs);
 
     bool *mAttrsEnabled;
     uint32_t mAttrsEnabledSize;
 };
 
 
-}
-}
-#endif //ANDROID_VERTEX_ARRAY_H
+#endif //ANDROID_RSD_VERTEX_ARRAY_H
 
 
 
diff --git a/java/Android.mk b/java/Android.mk
deleted file mode 100644
index 5053e7d..0000000
--- a/java/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
diff --git a/java/Balls/Android.mk b/java/Balls/Android.mk
deleted file mode 100644
index 5b65628..0000000
--- a/java/Balls/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
-
-LOCAL_PACKAGE_NAME := Balls
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/java/Balls/AndroidManifest.xml b/java/Balls/AndroidManifest.xml
deleted file mode 100644
index 2fffc5f..0000000
--- a/java/Balls/AndroidManifest.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.balls">
-    <application 
-        android:label="Balls"
-        android:icon="@drawable/test_pattern">
-        <activity android:name="Balls"
-                  android:screenOrientation="landscape">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/java/Balls/res/drawable/flares.png b/java/Balls/res/drawable/flares.png
deleted file mode 100644
index 3a5c970..0000000
--- a/java/Balls/res/drawable/flares.png
+++ /dev/null
Binary files differ
diff --git a/java/Balls/res/drawable/test_pattern.png b/java/Balls/res/drawable/test_pattern.png
deleted file mode 100644
index e7d1455..0000000
--- a/java/Balls/res/drawable/test_pattern.png
+++ /dev/null
Binary files differ
diff --git a/java/Balls/src/com/android/balls/Balls.java b/java/Balls/src/com/android/balls/Balls.java
deleted file mode 100644
index c24e616..0000000
--- a/java/Balls/src/com/android/balls/Balls.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.balls;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Config;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-import android.app.Activity;
-import android.content.Context;
-import android.os.Bundle;
-import android.view.View;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-
-public class Balls extends Activity implements SensorEventListener {
-    //EventListener mListener = new EventListener();
-
-    private static final String LOG_TAG = "libRS_jni";
-    private static final boolean DEBUG  = false;
-    private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
-
-    private BallsView mView;
-    private SensorManager mSensorManager;
-
-    // get the current looper (from your Activity UI thread for instance
-
-
-    public void onSensorChanged(SensorEvent event) {
-        //android.util.Log.d("rs", "sensor: " + event.sensor + ", x: " + event.values[0] + ", y: " + event.values[1] + ", z: " + event.values[2]);
-        synchronized (this) {
-            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
-                if(mView != null) {
-                    mView.setAccel(event.values[0], event.values[1], event.values[2]);
-                }
-            }
-        }
-    }
-
-    public void onAccuracyChanged(Sensor sensor, int accuracy) {
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
-
-        // Create our Preview view and set it as the content of our
-        // Activity
-        mView = new BallsView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        mSensorManager.registerListener(this,
-                                        mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
-                                        SensorManager.SENSOR_DELAY_FASTEST);
-
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onResume();
-        mView.resume();
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        mView.pause();
-        Runtime.getRuntime().exit(0);
-    }
-
-    @Override
-    protected void onStop() {
-        mSensorManager.unregisterListener(this);
-        super.onStop();
-    }
-
-    static void log(String message) {
-        if (LOG_ENABLED) {
-            Log.v(LOG_TAG, message);
-        }
-    }
-
-
-}
-
diff --git a/java/Balls/src/com/android/balls/BallsRS.java b/java/Balls/src/com/android/balls/BallsRS.java
deleted file mode 100644
index 50ee921..0000000
--- a/java/Balls/src/com/android/balls/BallsRS.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.balls;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.util.Log;
-
-public class BallsRS {
-    public static final int PART_COUNT = 900;
-
-    public BallsRS() {
-    }
-
-    private Resources mRes;
-    private RenderScriptGL mRS;
-    private ScriptC_balls mScript;
-    private ScriptC_ball_physics mPhysicsScript;
-    private ProgramFragment mPFLines;
-    private ProgramFragment mPFPoints;
-    private ProgramVertex mPV;
-    private ScriptField_Point mPoints;
-    private ScriptField_VpConsts mVpConsts;
-
-    void updateProjectionMatrices() {
-        mVpConsts = new ScriptField_VpConsts(mRS, 1,
-                                             Allocation.USAGE_SCRIPT |
-                                             Allocation.USAGE_GRAPHICS_CONSTANTS);
-        ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
-        Matrix4f mvp = new Matrix4f();
-        mvp.loadOrtho(0, mRS.getWidth(), mRS.getHeight(), 0, -1, 1);
-        i.MVP = mvp;
-        mVpConsts.set(i, 0, true);
-    }
-
-    private void createProgramVertex() {
-        updateProjectionMatrices();
-
-        ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
-        String t =  "varying vec4 varColor;\n" +
-                    "void main() {\n" +
-                    "  vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
-                    "  pos.xy = ATTRIB_position;\n" +
-                    "  gl_Position = UNI_MVP * pos;\n" +
-                    "  varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
-                    "  gl_PointSize = ATTRIB_size;\n" +
-                    "}\n";
-        sb.setShader(t);
-        sb.addConstant(mVpConsts.getType());
-        sb.addInput(mPoints.getElement());
-        ProgramVertex pvs = sb.create();
-        pvs.bindConstants(mVpConsts.getAllocation(), 0);
-        mRS.bindProgramVertex(pvs);
-    }
-
-    private Allocation loadTexture(int id) {
-        final Allocation allocation =
-            Allocation.createFromBitmapResource(mRS, mRes,
-                id, Allocation.MipmapControl.MIPMAP_NONE,
-                Allocation.USAGE_GRAPHICS_TEXTURE);
-        return allocation;
-    }
-
-    ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
-        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
-        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
-        builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
-        builder.setDitherEnabled(false);
-        builder.setDepthMaskEnabled(false);
-        return builder.create();
-    }
-
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        mRS = rs;
-        mRes = res;
-
-        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
-        pfb.setPointSpriteTexCoordinateReplacement(true);
-        pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
-                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
-        pfb.setVaryingColor(true);
-        mPFPoints = pfb.create();
-
-        pfb = new ProgramFragmentFixedFunction.Builder(rs);
-        pfb.setVaryingColor(true);
-        mPFLines = pfb.create();
-
-        android.util.Log.e("rs", "Load texture");
-        mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0);
-
-        mPoints = new ScriptField_Point(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
-
-        Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
-        smb.addVertexAllocation(mPoints.getAllocation());
-        smb.addIndexSetType(Mesh.Primitive.POINT);
-        Mesh smP = smb.create();
-
-        mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics);
-
-        mScript = new ScriptC_balls(mRS, mRes, R.raw.balls);
-        mScript.set_partMesh(smP);
-        mScript.set_physics_script(mPhysicsScript);
-        mScript.bind_point(mPoints);
-        mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
-        mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
-
-        mScript.set_gPFLines(mPFLines);
-        mScript.set_gPFPoints(mPFPoints);
-        createProgramVertex();
-
-        mRS.bindProgramStore(BLEND_ADD_DEPTH_NONE(mRS));
-
-        mPhysicsScript.set_gMinPos(new Float2(5, 5));
-        mPhysicsScript.set_gMaxPos(new Float2(width - 5, height - 5));
-
-        mScript.invoke_initParts(width, height);
-
-        mRS.bindRootScript(mScript);
-    }
-
-    public void newTouchPosition(float x, float y, float pressure, int id) {
-        mPhysicsScript.invoke_touch(x, y, pressure, id);
-    }
-
-    public void setAccel(float x, float y) {
-        mPhysicsScript.set_gGravityVector(new Float2(x, y));
-    }
-
-}
diff --git a/java/Balls/src/com/android/balls/BallsView.java b/java/Balls/src/com/android/balls/BallsView.java
deleted file mode 100644
index 4442eec..0000000
--- a/java/Balls/src/com/android/balls/BallsView.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.balls;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class BallsView extends RSSurfaceView {
-
-    public BallsView(Context context) {
-        super(context);
-        //setFocusable(true);
-    }
-
-    private RenderScriptGL mRS;
-    private BallsRS mRender;
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-        if (mRS == null) {
-            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
-            mRS = createRenderScriptGL(sc);
-            mRS.setSurface(holder, w, h);
-            mRender = new BallsRS();
-            mRender.init(mRS, getResources(), w, h);
-        }
-        mRender.updateProjectionMatrices();
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        if(mRS != null) {
-            mRS = null;
-            destroyRenderScriptGL();
-        }
-    }
-
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev)
-    {
-        int act = ev.getActionMasked();
-        if (act == ev.ACTION_UP) {
-            mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
-            return false;
-        } else if (act == MotionEvent.ACTION_POINTER_UP) {
-            // only one pointer going up, we can get the index like this
-            int pointerIndex = ev.getActionIndex();
-            int pointerId = ev.getPointerId(pointerIndex);
-            mRender.newTouchPosition(0, 0, 0, pointerId);
-            return false;
-        }
-        int count = ev.getHistorySize();
-        int pcount = ev.getPointerCount();
-
-        for (int p=0; p < pcount; p++) {
-            int id = ev.getPointerId(p);
-            mRender.newTouchPosition(ev.getX(p),
-                                     ev.getY(p),
-                                     ev.getPressure(p),
-                                     id);
-
-            for (int i=0; i < count; i++) {
-                mRender.newTouchPosition(ev.getHistoricalX(p, i),
-                                         ev.getHistoricalY(p, i),
-                                         ev.getHistoricalPressure(p, i),
-                                         id);
-            }
-        }
-        return true;
-    }
-
-    void setAccel(float x, float y, float z) {
-        if (mRender == null) {
-            return;
-        }
-        mRender.setAccel(x, -y);
-    }
-
-}
-
-
diff --git a/java/Balls/src/com/android/balls/ball_physics.rs b/java/Balls/src/com/android/balls/ball_physics.rs
deleted file mode 100644
index ff38be5..0000000
--- a/java/Balls/src/com/android/balls/ball_physics.rs
+++ /dev/null
@@ -1,146 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(com.android.balls)
-
-#include "balls.rsh"
-
-float2 gGravityVector = {0.f, 9.8f};
-
-float2 gMinPos = {0.f, 0.f};
-float2 gMaxPos = {1280.f, 700.f};
-
-static float2 touchPos[10];
-static float touchPressure[10];
-
-void touch(float x, float y, float pressure, int id) {
-    if (id >= 10) {
-        return;
-    }
-
-    touchPos[id].x = x;
-    touchPos[id].y = y;
-    touchPressure[id] = pressure;
-}
-
-void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint32_t x) {
-    float2 fv = {0, 0};
-    float2 pos = ballIn->position;
-
-    int arcID = -1;
-    float arcInvStr = 100000;
-
-    const Ball_t * bPtr = rsGetElementAt(ctl->ain, 0);
-    for (uint32_t xin = 0; xin < ctl->dimX; xin++) {
-        float2 vec = bPtr[xin].position - pos;
-        float2 vec2 = vec * vec;
-        float len2 = vec2.x + vec2.y;
-
-        if (len2 < 10000) {
-            //float minDist = ballIn->size + bPtr[xin].size;
-            float forceScale = ballIn->size * bPtr[xin].size;
-            forceScale *= forceScale;
-
-            if (len2 > 16 /* (minDist*minDist)*/)  {
-                // Repulsion
-                float len = sqrt(len2);
-                fv -= (vec / (len * len * len)) * 20000.f * forceScale;
-            } else {
-                if (len2 < 1) {
-                    if (xin == x) {
-                        continue;
-                    }
-                    ballOut->delta = 0.f;
-                    ballOut->position = ballIn->position;
-                    if (xin > x) {
-                        ballOut->position.x += 1.f;
-                    } else {
-                        ballOut->position.x -= 1.f;
-                    }
-                    //ballOut->color.rgb = 1.f;
-                    //ballOut->arcID = -1;
-                    //ballOut->arcStr = 0;
-                    return;
-                }
-                // Collision
-                float2 axis = normalize(vec);
-                float e1 = dot(axis, ballIn->delta);
-                float e2 = dot(axis, bPtr[xin].delta);
-                float e = (e1 - e2) * 0.45f;
-                if (e1 > 0) {
-                    fv -= axis * e;
-                } else {
-                    fv += axis * e;
-                }
-            }
-        }
-    }
-
-    fv /= ballIn->size * ballIn->size * ballIn->size;
-    fv -= gGravityVector * 4.f;
-    fv *= ctl->dt;
-
-    for (int i=0; i < 10; i++) {
-        if (touchPressure[i] > 0.1f) {
-            float2 vec = touchPos[i] - ballIn->position;
-            float2 vec2 = vec * vec;
-            float len2 = max(2.f, vec2.x + vec2.y);
-            fv -= (vec / len2) * touchPressure[i] * 300.f;
-        }
-    }
-
-    ballOut->delta = (ballIn->delta * (1.f - 0.004f)) + fv;
-    ballOut->position = ballIn->position + (ballOut->delta * ctl->dt);
-
-    const float wallForce = 400.f;
-    if (ballOut->position.x > (gMaxPos.x - 20.f)) {
-        float d = gMaxPos.x - ballOut->position.x;
-        if (d < 0.f) {
-            if (ballOut->delta.x > 0) {
-                ballOut->delta.x *= -0.7;
-            }
-            ballOut->position.x = gMaxPos.x;
-        } else {
-            ballOut->delta.x -= min(wallForce / (d * d), 10.f);
-        }
-    }
-
-    if (ballOut->position.x < (gMinPos.x + 20.f)) {
-        float d = ballOut->position.x - gMinPos.x;
-        if (d < 0.f) {
-            if (ballOut->delta.x < 0) {
-                ballOut->delta.x *= -0.7;
-            }
-            ballOut->position.x = gMinPos.x + 1.f;
-        } else {
-            ballOut->delta.x += min(wallForce / (d * d), 10.f);
-        }
-    }
-
-    if (ballOut->position.y > (gMaxPos.y - 20.f)) {
-        float d = gMaxPos.y - ballOut->position.y;
-        if (d < 0.f) {
-            if (ballOut->delta.y > 0) {
-                ballOut->delta.y *= -0.7;
-            }
-            ballOut->position.y = gMaxPos.y;
-        } else {
-            ballOut->delta.y -= min(wallForce / (d * d), 10.f);
-        }
-    }
-
-    if (ballOut->position.y < (gMinPos.y + 20.f)) {
-        float d = ballOut->position.y - gMinPos.y;
-        if (d < 0.f) {
-            if (ballOut->delta.y < 0) {
-                ballOut->delta.y *= -0.7;
-            }
-            ballOut->position.y = gMinPos.y + 1.f;
-        } else {
-            ballOut->delta.y += min(wallForce / (d * d * d), 10.f);
-        }
-    }
-
-    ballOut->size = ballIn->size;
-
-    //rsDebug("physics pos out", ballOut->position);
-}
-
diff --git a/java/Balls/src/com/android/balls/balls.rs b/java/Balls/src/com/android/balls/balls.rs
deleted file mode 100644
index fed9963..0000000
--- a/java/Balls/src/com/android/balls/balls.rs
+++ /dev/null
@@ -1,85 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(com.android.balls)
-#include "rs_graphics.rsh"
-
-#include "balls.rsh"
-
-#pragma stateVertex(parent)
-#pragma stateStore(parent)
-
-rs_program_fragment gPFPoints;
-rs_program_fragment gPFLines;
-rs_mesh partMesh;
-
-typedef struct __attribute__((packed, aligned(4))) Point {
-    float2 position;
-    float size;
-} Point_t;
-Point_t *point;
-
-typedef struct VpConsts {
-    rs_matrix4x4 MVP;
-} VpConsts_t;
-VpConsts_t *vpConstants;
-
-rs_script physics_script;
-
-Ball_t *balls1;
-Ball_t *balls2;
-
-static int frame = 0;
-
-void initParts(int w, int h)
-{
-    uint32_t dimX = rsAllocationGetDimX(rsGetAllocation(balls1));
-
-    for (uint32_t ct=0; ct < dimX; ct++) {
-        balls1[ct].position.x = rsRand(0.f, (float)w);
-        balls1[ct].position.y = rsRand(0.f, (float)h);
-        balls1[ct].delta.x = 0.f;
-        balls1[ct].delta.y = 0.f;
-        balls1[ct].size = 1.f;
-
-        float r = rsRand(100.f);
-        if (r > 90.f) {
-            balls1[ct].size += pow(10.f, rsRand(0.f, 2.f)) * 0.07;
-        }
-    }
-}
-
-
-
-int root() {
-    rsgClearColor(0.f, 0.f, 0.f, 1.f);
-
-    BallControl_t bc = {0};
-    Ball_t *bout;
-
-    if (frame & 1) {
-        rsSetObject(&bc.ain, rsGetAllocation(balls2));
-        rsSetObject(&bc.aout, rsGetAllocation(balls1));
-        bout = balls2;
-    } else {
-        rsSetObject(&bc.ain, rsGetAllocation(balls1));
-        rsSetObject(&bc.aout, rsGetAllocation(balls2));
-        bout = balls1;
-    }
-
-    bc.dimX = rsAllocationGetDimX(bc.ain);
-    bc.dt = 1.f / 30.f;
-
-    rsForEach(physics_script, bc.ain, bc.aout, &bc);
-
-    for (uint32_t ct=0; ct < bc.dimX; ct++) {
-        point[ct].position = bout[ct].position;
-        point[ct].size = 6.f /*+ bout[ct].color.g * 6.f*/ * bout[ct].size;
-    }
-
-    frame++;
-    rsgBindProgramFragment(gPFPoints);
-    rsgDrawMesh(partMesh);
-    rsClearObject(&bc.ain);
-    rsClearObject(&bc.aout);
-    return 1;
-}
-
diff --git a/java/Balls/src/com/android/balls/balls.rsh b/java/Balls/src/com/android/balls/balls.rsh
deleted file mode 100644
index fc886f9..0000000
--- a/java/Balls/src/com/android/balls/balls.rsh
+++ /dev/null
@@ -1,18 +0,0 @@
-
-typedef struct __attribute__((packed, aligned(4))) Ball {
-    float2 delta;
-    float2 position;
-    //float3 color;
-    float size;
-    //int arcID;
-    //float arcStr;
-} Ball_t;
-Ball_t *balls;
-
-
-typedef struct BallControl {
-    uint32_t dimX;
-    rs_allocation ain;
-    rs_allocation aout;
-    float dt;
-} BallControl_t;
diff --git a/java/Fountain/Android.mk b/java/Fountain/Android.mk
deleted file mode 100644
index 71944b2..0000000
--- a/java/Fountain/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
-
-LOCAL_PACKAGE_NAME := Fountain
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/java/Fountain/AndroidManifest.xml b/java/Fountain/AndroidManifest.xml
deleted file mode 100644
index 951c451..0000000
--- a/java/Fountain/AndroidManifest.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.fountain">
-    <application 
-        android:label="Fountain"
-        android:icon="@drawable/test_pattern">
-        <activity android:name="Fountain">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/java/Fountain/res/drawable/test_pattern.png b/java/Fountain/res/drawable/test_pattern.png
deleted file mode 100644
index e7d1455..0000000
--- a/java/Fountain/res/drawable/test_pattern.png
+++ /dev/null
Binary files differ
diff --git a/java/Fountain/src/com/android/fountain/Fountain.java b/java/Fountain/src/com/android/fountain/Fountain.java
deleted file mode 100644
index 116c478..0000000
--- a/java/Fountain/src/com/android/fountain/Fountain.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fountain;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Config;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-public class Fountain extends Activity {
-    //EventListener mListener = new EventListener();
-
-    private static final String LOG_TAG = "libRS_jni";
-    private static final boolean DEBUG  = false;
-    private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
-
-    private FountainView mView;
-
-    // get the current looper (from your Activity UI thread for instance
-
-
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        // Create our Preview view and set it as the content of our
-        // Activity
-        mView = new FountainView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        Log.e("rs", "onResume");
-
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onResume();
-        mView.resume();
-    }
-
-    @Override
-    protected void onPause() {
-        Log.e("rs", "onPause");
-
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onPause();
-        mView.pause();
-
-
-
-        //Runtime.getRuntime().exit(0);
-    }
-
-
-    static void log(String message) {
-        if (LOG_ENABLED) {
-            Log.v(LOG_TAG, message);
-        }
-    }
-
-
-}
-
diff --git a/java/Fountain/src/com/android/fountain/FountainRS.java b/java/Fountain/src/com/android/fountain/FountainRS.java
deleted file mode 100644
index be2f9ca..0000000
--- a/java/Fountain/src/com/android/fountain/FountainRS.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fountain;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.util.Log;
-
-
-public class FountainRS {
-    public static final int PART_COUNT = 50000;
-
-    public FountainRS() {
-    }
-
-    private Resources mRes;
-    private RenderScriptGL mRS;
-    private ScriptC_fountain mScript;
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        mRS = rs;
-        mRes = res;
-
-        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
-        pfb.setVaryingColor(true);
-        rs.bindProgramFragment(pfb.create());
-
-        ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);//
- //                                                        Allocation.USAGE_GRAPHICS_VERTEX);
-
-        Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
-        smb.addVertexAllocation(points.getAllocation());
-        smb.addIndexSetType(Mesh.Primitive.POINT);
-        Mesh sm = smb.create();
-
-        mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
-        mScript.set_partMesh(sm);
-        mScript.bind_point(points);
-        mRS.bindRootScript(mScript);
-    }
-
-    boolean holdingColor[] = new boolean[10];
-    public void newTouchPosition(float x, float y, float pressure, int id) {
-        if (id >= holdingColor.length) {
-            return;
-        }
-        int rate = (int)(pressure * pressure * 500.f);
-        if (rate > 500) {
-            rate = 500;
-        }
-        if (rate > 0) {
-            mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]);
-            holdingColor[id] = true;
-        } else {
-            holdingColor[id] = false;
-        }
-
-    }
-}
diff --git a/java/Fountain/src/com/android/fountain/FountainView.java b/java/Fountain/src/com/android/fountain/FountainView.java
deleted file mode 100644
index 69b181d..0000000
--- a/java/Fountain/src/com/android/fountain/FountainView.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.fountain;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class FountainView extends RSSurfaceView {
-
-    public FountainView(Context context) {
-        super(context);
-        //setFocusable(true);
-    }
-
-    private RenderScriptGL mRS;
-    private FountainRS mRender;
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-        if (mRS == null) {
-            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
-            mRS = createRenderScriptGL(sc);
-            mRS.setSurface(holder, w, h);
-            mRender = new FountainRS();
-            mRender.init(mRS, getResources(), w, h);
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        if (mRS != null) {
-            mRS = null;
-            destroyRenderScriptGL();
-        }
-    }
-
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev)
-    {
-        int act = ev.getActionMasked();
-        if (act == ev.ACTION_UP) {
-            mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
-            return false;
-        } else if (act == MotionEvent.ACTION_POINTER_UP) {
-            // only one pointer going up, we can get the index like this
-            int pointerIndex = ev.getActionIndex();
-            int pointerId = ev.getPointerId(pointerIndex);
-            mRender.newTouchPosition(0, 0, 0, pointerId);
-        }
-        int count = ev.getHistorySize();
-        int pcount = ev.getPointerCount();
-
-        for (int p=0; p < pcount; p++) {
-            int id = ev.getPointerId(p);
-            mRender.newTouchPosition(ev.getX(p),
-                                     ev.getY(p),
-                                     ev.getPressure(p),
-                                     id);
-
-            for (int i=0; i < count; i++) {
-                mRender.newTouchPosition(ev.getHistoricalX(p, i),
-                                         ev.getHistoricalY(p, i),
-                                         ev.getHistoricalPressure(p, i),
-                                         id);
-            }
-        }
-        return true;
-    }
-}
-
-
diff --git a/java/Fountain/src/com/android/fountain/fountain.rs b/java/Fountain/src/com/android/fountain/fountain.rs
deleted file mode 100644
index b8f57a3..0000000
--- a/java/Fountain/src/com/android/fountain/fountain.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-// Fountain test script
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.fountain)
-
-#pragma stateFragment(parent)
-
-#include "rs_graphics.rsh"
-
-static int newPart = 0;
-rs_mesh partMesh;
-
-typedef struct __attribute__((packed, aligned(4))) Point {
-    float2 delta;
-    float2 position;
-    uchar4 color;
-} Point_t;
-Point_t *point;
-
-int root() {
-    float dt = min(rsGetDt(), 0.1f);
-    rsgClearColor(0.f, 0.f, 0.f, 1.f);
-    const float height = rsgGetHeight();
-    const int size = rsAllocationGetDimX(rsGetAllocation(point));
-    float dy2 = dt * (10.f);
-    Point_t * p = point;
-    for (int ct=0; ct < size; ct++) {
-        p->delta.y += dy2;
-        p->position += p->delta;
-        if ((p->position.y > height) && (p->delta.y > 0)) {
-            p->delta.y *= -0.3f;
-        }
-        p++;
-    }
-
-    rsgDrawMesh(partMesh);
-    return 1;
-}
-
-static float4 partColor[10];
-void addParticles(int rate, float x, float y, int index, bool newColor)
-{
-    if (newColor) {
-        partColor[index].x = rsRand(0.5f, 1.0f);
-        partColor[index].y = rsRand(1.0f);
-        partColor[index].z = rsRand(1.0f);
-    }
-    float rMax = ((float)rate) * 0.02f;
-    int size = rsAllocationGetDimX(rsGetAllocation(point));
-    uchar4 c = rsPackColorTo8888(partColor[index]);
-
-    Point_t * np = &point[newPart];
-    float2 p = {x, y};
-    while (rate--) {
-        float angle = rsRand(3.14f * 2.f);
-        float len = rsRand(rMax);
-        np->delta.x = len * sin(angle);
-        np->delta.y = len * cos(angle);
-        np->position = p;
-        np->color = c;
-        newPart++;
-        np++;
-        if (newPart >= size) {
-            newPart = 0;
-            np = &point[newPart];
-        }
-    }
-}
-
diff --git a/java/ImageProcessing/Android.mk b/java/ImageProcessing/Android.mk
deleted file mode 100644
index 7fa30d0..0000000
--- a/java/ImageProcessing/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# 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.
-#
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-                   $(call all-renderscript-files-under, src)
-#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
-
-LOCAL_PACKAGE_NAME := ImageProcessing
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/java/ImageProcessing/AndroidManifest.xml b/java/ImageProcessing/AndroidManifest.xml
deleted file mode 100644
index d6a2db4..0000000
--- a/java/ImageProcessing/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.rs.image">
-
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-    <application android:label="Image Processing">
-        <activity android:name="ImageProcessingActivity"
-                  android:screenOrientation="portrait">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/java/ImageProcessing/res/drawable-hdpi/data.jpg b/java/ImageProcessing/res/drawable-hdpi/data.jpg
deleted file mode 100644
index 81a87b1..0000000
--- a/java/ImageProcessing/res/drawable-hdpi/data.jpg
+++ /dev/null
Binary files differ
diff --git a/java/ImageProcessing/res/drawable/data.jpg b/java/ImageProcessing/res/drawable/data.jpg
deleted file mode 100644
index 81a87b1..0000000
--- a/java/ImageProcessing/res/drawable/data.jpg
+++ /dev/null
Binary files differ
diff --git a/java/ImageProcessing/res/layout/main.xml b/java/ImageProcessing/res/layout/main.xml
deleted file mode 100644
index c6ec729..0000000
--- a/java/ImageProcessing/res/layout/main.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?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.
--->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <SurfaceView
-        android:id="@+id/surface"
-        android:layout_width="1dip"
-        android:layout_height="1dip" />
-
-    <ImageView
-        android:id="@+id/display"
-        android:layout_width="320dip"
-        android:layout_height="266dip" />
-
-    <Button
-        android:layout_marginBottom="170dip"
-        android:layout_width="wrap_content"
-        android:layout_height="40dip"
-        android:text="@string/benchmark"
-        android:onClick="benchmark"
-        android:layout_gravity="bottom"/>
-
-    <TextView
-        android:id="@+id/benchmarkText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:layout_marginLeft="100dip"
-        android:layout_marginBottom="175dip"
-        android:layout_gravity="bottom"
-        android:text="@string/saturation"/>
-
-     <SeekBar
-        android:id="@+id/inSaturation"
-        android:layout_marginBottom="140dip"
-        android:layout_marginLeft="10dip"
-        android:layout_marginRight="10dip"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom" />
-
-    <TextView
-        android:id="@+id/inSaturationText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:layout_marginLeft="50dip"
-        android:layout_marginBottom="142dip"
-        android:textColor="#000"
-        android:layout_gravity="bottom"
-        android:text="@string/saturation"/>
-
-    <SeekBar
-        android:id="@+id/inGamma"
-        android:layout_marginBottom="110dip"
-        android:layout_marginLeft="10dip"
-        android:layout_marginRight="10dip"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom" />
-
-    <TextView
-        android:id="@+id/inGammaText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:layout_marginLeft="50dip"
-        android:layout_marginBottom="112dip"
-        android:textColor="#000"
-        android:layout_gravity="bottom"
-        android:text="@string/gamma"/>
-
-    <SeekBar
-        android:id="@+id/outWhite"
-        android:layout_marginBottom="80dip"
-        android:layout_marginLeft="170dip"
-        android:layout_marginRight="10dip"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom" />
-
-    <TextView
-        android:id="@+id/outWhiteText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:layout_marginLeft="220dip"
-        android:layout_marginBottom="82dip"
-        android:textColor="#000"
-        android:layout_gravity="bottom"
-        android:text="@string/out_white"/>
-
-    <SeekBar
-        android:id="@+id/inWhite"
-        android:layout_marginBottom="80dip"
-        android:layout_marginLeft="10dip"
-        android:layout_marginRight="170dip"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom" />
-
-    <TextView
-        android:id="@+id/inWhiteText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:layout_marginLeft="50dip"
-        android:layout_marginBottom="82dip"
-        android:textColor="#000"
-        android:layout_gravity="bottom"
-        android:text="@string/in_white"/>
-
-    <SeekBar
-        android:id="@+id/outBlack"
-        android:layout_marginBottom="50dip"
-        android:layout_marginLeft="170dip"
-        android:layout_marginRight="10dip"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom" />
-
-    <TextView
-        android:id="@+id/outBlackText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:layout_marginLeft="220dip"
-        android:layout_marginBottom="52dip"
-        android:textColor="#000"
-        android:layout_gravity="bottom"
-        android:text="@string/out_black"/>
-
-    <SeekBar
-        android:id="@+id/inBlack"
-        android:layout_marginBottom="50dip"
-        android:layout_marginLeft="10dip"
-        android:layout_marginRight="170dip"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom" />
-
-    <TextView
-        android:id="@+id/inBlackText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:layout_marginLeft="50dip"
-        android:layout_marginBottom="52dip"
-        android:textColor="#000"
-        android:layout_gravity="bottom"
-        android:text="@string/in_black"/>
-
-    <SeekBar
-        android:id="@+id/radius"
-        android:layout_marginBottom="10dip"
-        android:layout_marginLeft="10dip"
-        android:layout_marginRight="10dip"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom" />
-
-     <TextView
-        android:id="@+id/blurText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:layout_marginLeft="50dip"
-        android:layout_marginBottom="12dip"
-        android:textColor="#000"
-        android:layout_gravity="bottom"
-        android:text="@string/blur_description"/>
-
-</merge>
\ No newline at end of file
diff --git a/java/ImageProcessing/res/values/strings.xml b/java/ImageProcessing/res/values/strings.xml
deleted file mode 100644
index cc5cc4d..0000000
--- a/java/ImageProcessing/res/values/strings.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2008 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- General -->
-    <skip />
-    <!--slider label -->
-    <string name="blur_description">Blur Radius</string>
-    <string name="in_white">In White</string>
-    <string name="out_white">Out White</string>
-    <string name="in_black">In Black</string>
-    <string name="out_black">Out Black</string>
-    <string name="gamma">Gamma</string>
-    <string name="saturation">Saturation</string>
-    <string name="benchmark">Benchmark</string>
-
-</resources>
diff --git a/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
deleted file mode 100644
index 5de09f7..0000000
--- a/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.rs.image;
-
-import android.app.Activity;
-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;
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.Script;
-import android.view.SurfaceView;
-import android.view.SurfaceHolder;
-import android.widget.ImageView;
-import android.widget.SeekBar;
-import android.widget.TextView;
-import android.view.View;
-import java.lang.Math;
-
-public class ImageProcessingActivity extends Activity
-                                       implements SurfaceHolder.Callback,
-                                       SeekBar.OnSeekBarChangeListener {
-    private Bitmap mBitmapIn;
-    private Bitmap mBitmapOut;
-    private Bitmap mBitmapScratch;
-    private ScriptC_threshold mScript;
-    private ScriptC_vertical_blur mScriptVBlur;
-    private ScriptC_horizontal_blur mScriptHBlur;
-    private int mRadius = 0;
-    private SeekBar mRadiusSeekBar;
-
-    private float mInBlack = 0.0f;
-    private SeekBar mInBlackSeekBar;
-    private float mOutBlack = 0.0f;
-    private SeekBar mOutBlackSeekBar;
-    private float mInWhite = 255.0f;
-    private SeekBar mInWhiteSeekBar;
-    private float mOutWhite = 255.0f;
-    private SeekBar mOutWhiteSeekBar;
-    private float mGamma = 1.0f;
-    private SeekBar mGammaSeekBar;
-
-    private float mSaturation = 1.0f;
-    private SeekBar mSaturationSeekBar;
-
-    private TextView mBenchmarkResult;
-
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private RenderScript mRS;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private Type mPixelType;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private Allocation mInPixelsAllocation;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private Allocation mOutPixelsAllocation;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private Allocation mScratchPixelsAllocation1;
-    private Allocation mScratchPixelsAllocation2;
-
-    private SurfaceView mSurfaceView;
-    private ImageView mDisplayView;
-
-    class FilterCallback extends RenderScript.RSMessageHandler {
-        private Runnable mAction = new Runnable() {
-            public void run() {
-                mDisplayView.invalidate();
-            }
-        };
-
-        @Override
-        public void run() {
-            mSurfaceView.removeCallbacks(mAction);
-            mSurfaceView.post(mAction);
-        }
-    }
-
-    int in[];
-    int interm[];
-    int out[];
-    int MAX_RADIUS = 25;
-    // Store our coefficients here
-    float gaussian[];
-
-    private long javaFilter() {
-        final int width = mBitmapIn.getWidth();
-        final int height = mBitmapIn.getHeight();
-        final int count = width * height;
-
-        if (in == null) {
-            in = new int[count];
-            interm = new int[count];
-            out = new int[count];
-            gaussian = new float[MAX_RADIUS * 2 + 1];
-            mBitmapIn.getPixels(in, 0, width, 0, 0, width, height);
-        }
-
-        long t = java.lang.System.currentTimeMillis();
-
-        int w, h, r;
-
-        float fRadius = (float)mRadius;
-        int radius = (int)mRadius;
-
-        // 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 * fRadius + 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 / (float)(Math.sqrt( 2.0f * pi ) * sigma);
-        float coeff2 = - 1.0f / (2.0f * sigma * sigma);
-        float normalizeFactor = 0.0f;
-        float floatR = 0.0f;
-        for (r = -radius; r <= radius; r ++) {
-            floatR = (float)r;
-            gaussian[r + radius] = coeff1 * (float)Math.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 (r = -radius; r <= radius; r ++) {
-            floatR = (float)r;
-            gaussian[r + radius] *= normalizeFactor;
-        }
-
-        float blurredPixelR = 0.0f;
-        float blurredPixelG = 0.0f;
-        float blurredPixelB = 0.0f;
-        float blurredPixelA = 0.0f;
-
-        for (h = 0; h < height; h ++) {
-            for (w = 0; w < width; w ++) {
-
-                blurredPixelR = 0.0f;
-                blurredPixelG = 0.0f;
-                blurredPixelB = 0.0f;
-                blurredPixelA = 0.0f;
-
-                for (r = -radius; r <= radius; r ++) {
-                    // Stepping left and right away from the pixel
-                    int validW = w + r;
-                    // Clamp to zero and width max() isn't exposed for ints yet
-                    if (validW < 0) {
-                        validW = 0;
-                    }
-                    if (validW > width - 1) {
-                        validW = width - 1;
-                    }
-
-                    int input = in[h*width + validW];
-
-                    int R = ((input >> 24) & 0xff);
-                    int G = ((input >> 16) & 0xff);
-                    int B = ((input >> 8) & 0xff);
-                    int A = (input & 0xff);
-
-                    float weight = gaussian[r + radius];
-
-                    blurredPixelR += (float)(R)*weight;
-                    blurredPixelG += (float)(G)*weight;
-                    blurredPixelB += (float)(B)*weight;
-                    blurredPixelA += (float)(A)*weight;
-                }
-
-                int R = (int)blurredPixelR;
-                int G = (int)blurredPixelG;
-                int B = (int)blurredPixelB;
-                int A = (int)blurredPixelA;
-
-                interm[h*width + w] = (R << 24) | (G << 16) | (B << 8) | (A);
-            }
-        }
-
-        for (h = 0; h < height; h ++) {
-            for (w = 0; w < width; w ++) {
-
-                blurredPixelR = 0.0f;
-                blurredPixelG = 0.0f;
-                blurredPixelB = 0.0f;
-                blurredPixelA = 0.0f;
-                for (r = -radius; r <= radius; r ++) {
-                    int validH = h + r;
-                    // Clamp to zero and width
-                    if (validH < 0) {
-                        validH = 0;
-                    }
-                    if (validH > height - 1) {
-                        validH = height - 1;
-                    }
-
-                    int input = interm[validH*width + w];
-
-                    int R = ((input >> 24) & 0xff);
-                    int G = ((input >> 16) & 0xff);
-                    int B = ((input >> 8) & 0xff);
-                    int A = (input & 0xff);
-
-                    float weight = gaussian[r + radius];
-
-                    blurredPixelR += (float)(R)*weight;
-                    blurredPixelG += (float)(G)*weight;
-                    blurredPixelB += (float)(B)*weight;
-                    blurredPixelA += (float)(A)*weight;
-                }
-
-                int R = (int)blurredPixelR;
-                int G = (int)blurredPixelG;
-                int B = (int)blurredPixelB;
-                int A = (int)blurredPixelA;
-
-                out[h*width + w] = (R << 24) | (G << 16) | (B << 8) | (A);
-            }
-        }
-
-        t = java.lang.System.currentTimeMillis() - t;
-        android.util.Log.v("Img", "Java frame time ms " + t);
-        mBitmapOut.setPixels(out, 0, width, 0, 0, width, height);
-        return t;
-    }
-
-    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-        if (fromUser) {
-
-            if (seekBar == mRadiusSeekBar) {
-                float fRadius = progress / 100.0f;
-                fRadius *= (float)(MAX_RADIUS);
-                mRadius = (int)fRadius;
-
-                mScript.set_radius(mRadius);
-            } else if (seekBar == mInBlackSeekBar) {
-                mInBlack = (float)progress;
-                mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
-            } else if (seekBar == mOutBlackSeekBar) {
-                mOutBlack = (float)progress;
-                mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
-            } else if (seekBar == mInWhiteSeekBar) {
-                mInWhite = (float)progress + 127.0f;
-                mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
-            } else if (seekBar == mOutWhiteSeekBar) {
-                mOutWhite = (float)progress + 127.0f;
-                mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
-            } else if (seekBar == mGammaSeekBar) {
-                mGamma = (float)progress/100.0f;
-                mGamma = Math.max(mGamma, 0.1f);
-                mGamma = 1.0f / mGamma;
-                mScriptVBlur.invoke_setGamma(mGamma);
-            } else if (seekBar == mSaturationSeekBar) {
-                mSaturation = (float)progress / 50.0f;
-                mScriptVBlur.invoke_setSaturation(mSaturation);
-            }
-
-            long t = java.lang.System.currentTimeMillis();
-            if (true) {
-                mScript.invoke_filter();
-                mOutPixelsAllocation.copyTo(mBitmapOut);
-            } else {
-                javaFilter();
-                mDisplayView.invalidate();
-            }
-
-            t = java.lang.System.currentTimeMillis() - t;
-            android.util.Log.v("Img", "Renderscript frame time core ms " + t);
-        }
-    }
-
-    public void onStartTrackingTouch(SeekBar seekBar) {
-    }
-
-    public void onStopTrackingTouch(SeekBar seekBar) {
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.main);
-
-        mBitmapIn = loadBitmap(R.drawable.data);
-        mBitmapOut = loadBitmap(R.drawable.data);
-        mBitmapScratch = loadBitmap(R.drawable.data);
-
-        mSurfaceView = (SurfaceView) findViewById(R.id.surface);
-        mSurfaceView.getHolder().addCallback(this);
-
-        mDisplayView = (ImageView) findViewById(R.id.display);
-        mDisplayView.setImageBitmap(mBitmapOut);
-
-        mRadiusSeekBar = (SeekBar) findViewById(R.id.radius);
-        mRadiusSeekBar.setOnSeekBarChangeListener(this);
-
-        mInBlackSeekBar = (SeekBar)findViewById(R.id.inBlack);
-        mInBlackSeekBar.setOnSeekBarChangeListener(this);
-        mInBlackSeekBar.setMax(128);
-        mInBlackSeekBar.setProgress(0);
-        mOutBlackSeekBar = (SeekBar)findViewById(R.id.outBlack);
-        mOutBlackSeekBar.setOnSeekBarChangeListener(this);
-        mOutBlackSeekBar.setMax(128);
-        mOutBlackSeekBar.setProgress(0);
-
-        mInWhiteSeekBar = (SeekBar)findViewById(R.id.inWhite);
-        mInWhiteSeekBar.setOnSeekBarChangeListener(this);
-        mInWhiteSeekBar.setMax(128);
-        mInWhiteSeekBar.setProgress(128);
-        mOutWhiteSeekBar = (SeekBar)findViewById(R.id.outWhite);
-        mOutWhiteSeekBar.setOnSeekBarChangeListener(this);
-        mOutWhiteSeekBar.setMax(128);
-        mOutWhiteSeekBar.setProgress(128);
-
-        mGammaSeekBar = (SeekBar)findViewById(R.id.inGamma);
-        mGammaSeekBar.setOnSeekBarChangeListener(this);
-        mGammaSeekBar.setMax(150);
-        mGammaSeekBar.setProgress(100);
-
-        mSaturationSeekBar = (SeekBar)findViewById(R.id.inSaturation);
-        mSaturationSeekBar.setOnSeekBarChangeListener(this);
-        mSaturationSeekBar.setProgress(50);
-
-        mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
-        mBenchmarkResult.setText("Benchmark not yet run");
-    }
-
-    public void surfaceCreated(SurfaceHolder holder) {
-        createScript();
-        mScript.invoke_filter();
-        mOutPixelsAllocation.copyTo(mBitmapOut);
-    }
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-    }
-
-    public void surfaceDestroyed(SurfaceHolder holder) {
-    }
-
-    private void createScript() {
-        mRS = RenderScript.create(this);
-        mRS.setMessageHandler(new FilterCallback());
-
-        mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
-                                                          Allocation.MipmapControl.MIPMAP_NONE,
-                                                          Allocation.USAGE_SCRIPT);
-        mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut,
-                                                           Allocation.MipmapControl.MIPMAP_NONE,
-                                                           Allocation.USAGE_SCRIPT);
-
-        Type.Builder tb = new Type.Builder(mRS, Element.F32_4(mRS));
-        tb.setX(mBitmapIn.getWidth());
-        tb.setY(mBitmapIn.getHeight());
-        mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create());
-        mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create());
-
-        mScriptVBlur = new ScriptC_vertical_blur(mRS, getResources(), R.raw.vertical_blur);
-        mScriptHBlur = new ScriptC_horizontal_blur(mRS, getResources(), R.raw.horizontal_blur);
-
-        mScript = new ScriptC_threshold(mRS, getResources(), R.raw.threshold);
-        mScript.set_width(mBitmapIn.getWidth());
-        mScript.set_height(mBitmapIn.getHeight());
-        mScript.set_radius(mRadius);
-
-        mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
-        mScriptVBlur.invoke_setGamma(mGamma);
-        mScriptVBlur.invoke_setSaturation(mSaturation);
-
-        mScript.bind_InPixel(mInPixelsAllocation);
-        mScript.bind_OutPixel(mOutPixelsAllocation);
-        mScript.bind_ScratchPixel1(mScratchPixelsAllocation1);
-        mScript.bind_ScratchPixel2(mScratchPixelsAllocation2);
-
-        mScript.set_vBlurScript(mScriptVBlur);
-        mScript.set_hBlurScript(mScriptHBlur);
-    }
-
-    private Bitmap loadBitmap(int resource) {
-        final BitmapFactory.Options options = new BitmapFactory.Options();
-        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
-        return copyBitmap(BitmapFactory.decodeResource(getResources(), resource, options));
-    }
-
-    private static Bitmap copyBitmap(Bitmap source) {
-        Bitmap b = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig());
-        Canvas c = new Canvas(b);
-        c.drawBitmap(source, 0, 0, null);
-        source.recycle();
-        return b;
-    }
-
-    // button hook
-    public void benchmark(View v) {
-        android.util.Log.v("Img", "Benchmarking");
-        int oldRadius = mRadius;
-        mRadius = MAX_RADIUS;
-        mScript.set_radius(mRadius);
-
-        long t = java.lang.System.currentTimeMillis();
-
-        mScript.invoke_filter();
-        mOutPixelsAllocation.copyTo(mBitmapOut);
-
-        t = java.lang.System.currentTimeMillis() - t;
-        android.util.Log.v("Img", "Renderscript frame time core ms " + t);
-
-        //long javaTime = javaFilter();
-        //mBenchmarkResult.setText("RS: " + t + " ms  Java: " + javaTime + " ms");
-        mBenchmarkResult.setText("RS: " + t + " ms");
-
-        mRadius = oldRadius;
-        mScript.set_radius(mRadius);
-
-        mScript.invoke_filter();
-        mOutPixelsAllocation.copyTo(mBitmapOut);
-    }
-}
diff --git a/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs b/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs
deleted file mode 100644
index 652ffd7..0000000
--- a/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma version(1)
-
-#include "ip.rsh"
-
-void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) {
-    float4 *output = (float4 *)v_out;
-    const FilterStruct *fs = (const FilterStruct *)usrData;
-    const float4 *input = (const float4 *)rsGetElementAt(fs->ain, 0, y);
-
-    float3 blurredPixel = 0;
-    const float *gPtr = fs->gaussian;
-    if ((x > fs->radius) && (x < (fs->width - fs->radius))) {
-        const float4 *i = input + (x - fs->radius);
-        for (int r = -fs->radius; r <= fs->radius; r ++) {
-            blurredPixel += i->xyz * gPtr[0];
-            gPtr++;
-            i++;
-        }
-    } else {
-        for (int r = -fs->radius; r <= fs->radius; r ++) {
-            // Stepping left and right away from the pixel
-            int validW = rsClamp(x + r, (uint)0, (uint)(fs->width - 1));
-            blurredPixel += input[validW].xyz * gPtr[0];
-            gPtr++;
-        }
-    }
-
-    output->xyz = blurredPixel;
-}
-
diff --git a/java/ImageProcessing/src/com/android/rs/image/ip.rsh b/java/ImageProcessing/src/com/android/rs/image/ip.rsh
deleted file mode 100644
index 1d7a719..0000000
--- a/java/ImageProcessing/src/com/android/rs/image/ip.rsh
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma rs java_package_name(com.android.rs.image)
-
-#define MAX_RADIUS 25
-
-typedef struct FilterStruct_s {
-    rs_allocation ain;
-
-    float *gaussian; //[MAX_RADIUS * 2 + 1];
-    int height;
-    int width;
-    int radius;
-
-} FilterStruct;
-
-
diff --git a/java/ImageProcessing/src/com/android/rs/image/threshold.rs b/java/ImageProcessing/src/com/android/rs/image/threshold.rs
deleted file mode 100644
index f2f9a36..0000000
--- a/java/ImageProcessing/src/com/android/rs/image/threshold.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-#pragma version(1)
-
-#include "ip.rsh"
-
-int height;
-int width;
-int radius;
-
-uchar4 * InPixel;
-uchar4 * OutPixel;
-float4 * ScratchPixel1;
-float4 * ScratchPixel2;
-
-rs_script vBlurScript;
-rs_script hBlurScript;
-
-const int CMD_FINISHED = 1;
-
-// Store our coefficients here
-static float gaussian[MAX_RADIUS * 2 + 1];
-
-
-static void computeGaussianWeights() {
-    // 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;
-    int r;
-    for (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 (r = -radius; r <= radius; r ++) {
-        floatR = (float)r;
-        gaussian[r + radius] *= normalizeFactor;
-    }
-}
-
-
-static void copyInput() {
-    rs_allocation ain;
-    rsSetObject(&ain,rsGetAllocation(InPixel));
-    uint32_t dimx = rsAllocationGetDimX(ain);
-    uint32_t dimy = rsAllocationGetDimY(ain);
-    for (uint32_t y = 0; y < dimy; y++) {
-        for (uint32_t x = 0; x < dimx; x++) {
-            ScratchPixel1[x + y * dimx] = convert_float4(InPixel[x + y * dimx]);
-        }
-    }
-}
-
-void filter() {
-    copyInput();
-    computeGaussianWeights();
-
-    FilterStruct fs;
-    fs.gaussian = gaussian;
-    fs.width = width;
-    fs.height = height;
-    fs.radius = radius;
-
-    fs.ain = rsGetAllocation(ScratchPixel1);
-    rsForEach(hBlurScript, fs.ain, rsGetAllocation(ScratchPixel2), &fs);
-
-    fs.ain = rsGetAllocation(ScratchPixel2);
-    rsForEach(vBlurScript, fs.ain, rsGetAllocation(OutPixel), &fs);
-    rsSendToClientBlocking(CMD_FINISHED);
-}
-
diff --git a/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs b/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs
deleted file mode 100644
index bd4ae4e..0000000
--- a/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-#pragma version(1)
-
-#include "ip.rsh"
-
-static float inBlack;
-static float outBlack;
-static float inWhite;
-static float outWhite;
-static float3 gamma;
-static float saturation;
-
-static float inWMinInB;
-static float outWMinOutB;
-static float overInWMinInB;
-static rs_matrix3x3 colorMat;
-
-void setLevels(float iBlk, float oBlk, float iWht, float oWht) {
-    inBlack = iBlk;
-    outBlack = oBlk;
-    inWhite = iWht;
-    outWhite = oWht;
-
-    inWMinInB = inWhite - inBlack;
-    outWMinOutB = outWhite - outBlack;
-    overInWMinInB = 1.f / inWMinInB;
-}
-
-void setSaturation(float sat) {
-    saturation = sat;
-
-    // Saturation
-    // Linear weights
-    //float rWeight = 0.3086f;
-    //float gWeight = 0.6094f;
-    //float bWeight = 0.0820f;
-
-    // Gamma 2.2 weights (we haven't converted our image to linear space yet for perf reasons)
-    float rWeight = 0.299f;
-    float gWeight = 0.587f;
-    float bWeight = 0.114f;
-
-    float oneMinusS = 1.0f - saturation;
-    rsMatrixSet(&colorMat, 0, 0, oneMinusS * rWeight + saturation);
-    rsMatrixSet(&colorMat, 0, 1, oneMinusS * rWeight);
-    rsMatrixSet(&colorMat, 0, 2, oneMinusS * rWeight);
-    rsMatrixSet(&colorMat, 1, 0, oneMinusS * gWeight);
-    rsMatrixSet(&colorMat, 1, 1, oneMinusS * gWeight + saturation);
-    rsMatrixSet(&colorMat, 1, 2, oneMinusS * gWeight);
-    rsMatrixSet(&colorMat, 2, 0, oneMinusS * bWeight);
-    rsMatrixSet(&colorMat, 2, 1, oneMinusS * bWeight);
-    rsMatrixSet(&colorMat, 2, 2, oneMinusS * bWeight + saturation);
-}
-
-void setGamma(float g) {
-    gamma = (float3)g;
-}
-
-//sliao
-extern uchar3 __attribute__((overloadable)) convert2uchar3(float3 xyz);
-
-void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) {
-    uchar4 *output = (uchar4 *)v_out;
-    const FilterStruct *fs = (const FilterStruct *)usrData;
-    const float4 *input = (const float4 *)rsGetElementAt(fs->ain, x, 0);
-
-    float3 blurredPixel = 0;
-    const float *gPtr = fs->gaussian;
-    if ((y > fs->radius) && (y < (fs->height - fs->radius))) {
-        const float4 *i = input + ((y - fs->radius) * fs->width);
-        for (int r = -fs->radius; r <= fs->radius; r ++) {
-            blurredPixel += i->xyz * gPtr[0];
-            gPtr++;
-            i += fs->width;
-        }
-    } else {
-        for (int r = -fs->radius; r <= fs->radius; r ++) {
-            int validH = rsClamp(y + r, (uint)0, (uint)(fs->height - 1));
-            const float4 *i = input + validH * fs->width;
-            blurredPixel += i->xyz * gPtr[0];
-            gPtr++;
-        }
-    }
-
-    float3 temp = rsMatrixMultiply(&colorMat, blurredPixel);
-    temp = (clamp(temp, 0.f, 255.f) - inBlack) * overInWMinInB;
-    if (gamma.x != 1.0f)
-        temp = pow(temp, (float3)gamma);
-    temp = clamp(temp * outWMinOutB + outBlack, 0.f, 255.f);
-
-    output->xyz = convert_uchar3(temp);
-    //output->w = input->w;
-}
-
diff --git a/java/ModelViewer/Android.mk b/java/ModelViewer/Android.mk
deleted file mode 100644
index efe77d7..0000000
--- a/java/ModelViewer/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
-
-LOCAL_PACKAGE_NAME := ModelViewer
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/java/ModelViewer/AndroidManifest.xml b/java/ModelViewer/AndroidManifest.xml
deleted file mode 100644
index 959fe53..0000000
--- a/java/ModelViewer/AndroidManifest.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.modelviewer">
-    <application android:label="ModelViewer">
-        <activity android:name="SimpleModel"
-                  android:label="SimpleModel"
-                  android:screenOrientation="portrait"
-                  android:theme="@android:style/Theme.Black.NoTitleBar">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-        <activity android:name="SceneGraph"
-                  android:label="SceneGraph"
-                  android:theme="@android:style/Theme.Black.NoTitleBar">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/java/ModelViewer/res/drawable/robot.png b/java/ModelViewer/res/drawable/robot.png
deleted file mode 100644
index f7353fd..0000000
--- a/java/ModelViewer/res/drawable/robot.png
+++ /dev/null
Binary files differ
diff --git a/java/ModelViewer/res/raw/robot.a3d b/java/ModelViewer/res/raw/robot.a3d
deleted file mode 100644
index f48895c..0000000
--- a/java/ModelViewer/res/raw/robot.a3d
+++ /dev/null
Binary files differ
diff --git a/java/ModelViewer/src/com/android/modelviewer/SceneGraph.java b/java/ModelViewer/src/com/android/modelviewer/SceneGraph.java
deleted file mode 100644
index b8717a7..0000000
--- a/java/ModelViewer/src/com/android/modelviewer/SceneGraph.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.modelviewer;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Config;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-public class SceneGraph extends Activity {
-
-    private SceneGraphView mView;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        // Create our Preview view and set it as the content of our
-        // Activity
-        mView = new SceneGraphView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onResume();
-        mView.resume();
-    }
-
-    @Override
-    protected void onPause() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onPause();
-        mView.pause();
-    }
-
-}
-
diff --git a/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java b/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
deleted file mode 100644
index f91f31e..0000000
--- a/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.modelviewer;
-
-import java.io.Writer;
-import java.util.Map;
-import java.util.Vector;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.renderscript.Element.Builder;
-import android.renderscript.Font.Style;
-import android.renderscript.ProgramStore.DepthFunc;
-import android.util.Log;
-
-
-public class SceneGraphRS {
-
-    private final int STATE_LAST_FOCUS = 1;
-
-    int mWidth;
-    int mHeight;
-    int mRotation;
-
-    public SceneGraphRS() {
-    }
-
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        mRS = rs;
-        mRes = res;
-        mWidth = width;
-        mHeight = height;
-        mRotation = 0;
-        initRS();
-    }
-
-    private Resources mRes;
-    private RenderScriptGL mRS;
-    private Sampler mSampler;
-    private ProgramStore mPSBackground;
-    private ProgramFragment mPFBackground;
-    private ProgramVertex mPVBackground;
-    private ProgramVertexFixedFunction.Constants mPVA;
-
-    private Allocation mGridImage;
-    private Allocation mAllocPV;
-
-    private Mesh mMesh;
-
-    private Font mItalic;
-    private Allocation mTextAlloc;
-
-    private ScriptC_scenegraph mScript;
-    private ScriptC_transform mTransformScript;
-
-    int mLastX;
-    int mLastY;
-
-    public void touchEvent(int x, int y) {
-        int dx = mLastX - x;
-        if (Math.abs(dx) > 50 || Math.abs(dx) < 3) {
-            dx = 0;
-        }
-
-        mRotation -= dx;
-        if (mRotation > 360) {
-            mRotation -= 360;
-        }
-        if (mRotation < 0) {
-            mRotation += 360;
-        }
-
-        mScript.set_gRotate(-(float)mRotation);
-
-        mLastX = x;
-        mLastY = y;
-    }
-
-    private void initPFS() {
-        ProgramStore.Builder b = new ProgramStore.Builder(mRS);
-
-        b.setDepthFunc(ProgramStore.DepthFunc.LESS);
-        b.setDitherEnabled(false);
-        b.setDepthMaskEnabled(true);
-        mPSBackground = b.create();
-
-        mScript.set_gPFSBackground(mPSBackground);
-    }
-
-    private void initPF() {
-        Sampler.Builder bs = new Sampler.Builder(mRS);
-        bs.setMinification(Sampler.Value.LINEAR);
-        bs.setMagnification(Sampler.Value.LINEAR);
-        bs.setWrapS(Sampler.Value.CLAMP);
-        bs.setWrapT(Sampler.Value.CLAMP);
-        mSampler = bs.create();
-
-        ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
-        b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
-                     ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
-        mPFBackground = b.create();
-        mPFBackground.bindSampler(mSampler, 0);
-
-        mScript.set_gPFBackground(mPFBackground);
-    }
-
-    private void initPV() {
-        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
-        mPVBackground = pvb.create();
-
-        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
-        ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVA);
-
-        mScript.set_gPVBackground(mPVBackground);
-    }
-
-    private void loadImage() {
-        mGridImage = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot,
-                                                         Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
-                                                         Allocation.USAGE_GRAPHICS_TEXTURE);
-        mScript.set_gTGrid(mGridImage);
-    }
-
-    private void initTextAllocation() {
-        String allocString = "Displaying file: R.raw.robot";
-        mTextAlloc = Allocation.createFromString(mRS, allocString, Allocation.USAGE_SCRIPT);
-        mScript.set_gTextAlloc(mTextAlloc);
-    }
-
-    SgTransform mRootTransform;
-    SgTransform mGroup1;
-
-    SgTransform mRobot1;
-    SgTransform mRobot2;
-
-    void initTransformHierarchy() {
-        mRootTransform = new SgTransform(mRS);
-
-        mGroup1 = new SgTransform(mRS);
-        mRootTransform.addChild(mGroup1);
-
-        mRobot1 = new SgTransform(mRS);
-        mRobot2 = new SgTransform(mRS);
-
-        mGroup1.addChild(mRobot1);
-        mGroup1.addChild(mRobot2);
-
-        mGroup1.setTransform(0, new Float4(0.0f, 0.0f, -15.0f, 0.0f), TransformType.TRANSLATE);
-        mGroup1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 15.0f), TransformType.ROTATE);
-
-        mRobot1.setTransform(0, new Float4(-3.0f, -0.5f, 0.0f, 0.0f), TransformType.TRANSLATE);
-        mRobot1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 20.0f), TransformType.ROTATE);
-        mRobot1.setTransform(2, new Float4(0.2f, 0.2f, 0.2f, 0.0f), TransformType.SCALE);
-
-        mRobot2.setTransform(0, new Float4(3.0f, 0.0f, 0.0f, 0.0f), TransformType.TRANSLATE);
-        mRobot2.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, -20.0f), TransformType.ROTATE);
-        mRobot2.setTransform(2, new Float4(0.3f, 0.3f, 0.3f, 0.0f), TransformType.SCALE);
-    }
-
-    private void initRS() {
-
-        mScript = new ScriptC_scenegraph(mRS, mRes, R.raw.scenegraph);
-        mTransformScript = new ScriptC_transform(mRS, mRes, R.raw.transform);
-        mTransformScript.set_transformScript(mTransformScript);
-
-        mScript.set_gTransformRS(mTransformScript);
-
-        initPFS();
-        initPF();
-        initPV();
-
-        loadImage();
-
-        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
-        FileA3D.IndexEntry entry = model.getIndexEntry(0);
-        if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
-            Log.e("rs", "could not load model");
-        } else {
-            mMesh = (Mesh)entry.getObject();
-            mScript.set_gTestMesh(mMesh);
-        }
-
-        mItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
-        mScript.set_gItalic(mItalic);
-
-        initTextAllocation();
-
-        initTransformHierarchy();
-
-        mScript.bind_gRootNode(mRootTransform.getField());
-
-        mScript.bind_gGroup(mGroup1.mParent.mChildField);
-        mScript.bind_gRobot1(mRobot1.mParent.mChildField);
-        mScript.set_gRobot1Index(mRobot1.mIndexInParentGroup);
-        mScript.bind_gRobot2(mRobot2.mParent.mChildField);
-        mScript.set_gRobot2Index(mRobot2.mIndexInParentGroup);
-
-        mRS.bindRootScript(mScript);
-    }
-}
-
-
-
diff --git a/java/ModelViewer/src/com/android/modelviewer/SceneGraphView.java b/java/ModelViewer/src/com/android/modelviewer/SceneGraphView.java
deleted file mode 100644
index 0b6a3b8..0000000
--- a/java/ModelViewer/src/com/android/modelviewer/SceneGraphView.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.modelviewer;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class SceneGraphView extends RSSurfaceView {
-
-    public SceneGraphView(Context context) {
-        super(context);
-        //setFocusable(true);
-    }
-
-    private RenderScriptGL mRS;
-    private SceneGraphRS mRender;
-
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-        if (mRS == null) {
-            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
-            sc.setDepth(16, 24);
-            mRS = createRenderScriptGL(sc);
-            mRS.setSurface(holder, w, h);
-            mRender = new SceneGraphRS();
-            mRender.init(mRS, getResources(), w, h);
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        if (mRS != null) {
-            mRS = null;
-            destroyRenderScriptGL();
-        }
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event)
-    {
-        // break point at here
-        // this method doesn't work when 'extends View' include 'extends ScrollView'.
-        return super.onKeyDown(keyCode, event);
-    }
-
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev)
-    {
-        boolean ret = true;
-        int act = ev.getAction();
-        if (act == ev.ACTION_UP) {
-            ret = false;
-        }
-
-        mRender.touchEvent((int)ev.getX(), (int)ev.getY());
-        return ret;
-    }
-}
-
-
diff --git a/java/ModelViewer/src/com/android/modelviewer/SgTransform.java b/java/ModelViewer/src/com/android/modelviewer/SgTransform.java
deleted file mode 100644
index f5484e2..0000000
--- a/java/ModelViewer/src/com/android/modelviewer/SgTransform.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.modelviewer;
-
-import java.io.Writer;
-import java.util.Map;
-import java.util.Vector;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.renderscript.Element.Builder;
-import android.renderscript.ProgramStore.DepthFunc;
-import android.util.Log;
-
-enum TransformType {
-
-    NONE(0),
-    TRANSLATE(1),
-    ROTATE(2),
-    SCALE(3);
-
-    int mID;
-    TransformType(int id) {
-        mID = id;
-    }
-}
-
-public class SgTransform {
-
-
-    ScriptField_SgTransform mTransformField;
-    ScriptField_SgTransform mChildField;
-    public ScriptField_SgTransform.Item mTransformData;
-
-    RenderScript mRS;
-
-    Vector mChildren;
-    SgTransform mParent;
-    int mIndexInParentGroup;
-
-    public void setParent(SgTransform parent, int parentIndex) {
-        mParent = parent;
-        mIndexInParentGroup = parentIndex;
-    }
-
-    public void addChild(SgTransform child) {
-        mChildren.add(child);
-        child.setParent(this, mChildren.size() - 1);
-    }
-
-    public void setTransform(int index, Float4 value, TransformType type) {
-        mTransformData.transforms[index] = value;
-        mTransformData.transformTypes[index] = type.mID;
-    }
-
-    void initData() {
-        int numElements = mTransformData.transforms.length;
-        mTransformData.transformTypes = new int[numElements];
-        for (int i = 0; i < numElements; i ++) {
-            mTransformData.transforms[i] = new Float4(0, 0, 0, 0);
-            mTransformData.transformTypes[i] = TransformType.NONE.mID;
-        }
-
-        mTransformData.isDirty = 1;
-        mTransformData.children = null;
-    }
-
-    public SgTransform(RenderScript rs) {
-        mRS = rs;
-        mTransformData = new ScriptField_SgTransform.Item();
-        mChildren = new Vector();
-        initData();
-    }
-
-    public ScriptField_SgTransform.Item getData() {
-        if (mChildren.size() != 0) {
-            mChildField = new ScriptField_SgTransform(mRS, mChildren.size());
-            mTransformData.children = mChildField.getAllocation();
-
-            for (int i = 0; i < mChildren.size(); i ++) {
-                SgTransform child = (SgTransform)mChildren.get(i);
-                mChildField.set(child.getData(), i, false);
-            }
-            mChildField.copyAll();
-        }
-
-        return mTransformData;
-    }
-
-    public ScriptField_SgTransform getField() {
-        mTransformField = new ScriptField_SgTransform(mRS, 1);
-        mTransformField.set(getData(), 0, true);
-        return mTransformField;
-    }
-}
-
-
-
diff --git a/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java b/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java
deleted file mode 100644
index 9910970..0000000
--- a/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.modelviewer;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Config;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-public class SimpleModel extends Activity {
-
-    private SimpleModelView mView;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        // Create our Preview view and set it as the content of our
-        // Activity
-        mView = new SimpleModelView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onResume();
-        mView.resume();
-    }
-
-    @Override
-    protected void onPause() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onPause();
-        mView.pause();
-    }
-
-}
-
diff --git a/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java b/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
deleted file mode 100644
index b18a327..0000000
--- a/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.modelviewer;
-
-import java.io.Writer;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.renderscript.ProgramStore.DepthFunc;
-import android.util.Log;
-
-
-public class SimpleModelRS {
-
-    private final int STATE_LAST_FOCUS = 1;
-
-    int mWidth;
-    int mHeight;
-    int mRotation;
-
-    public SimpleModelRS() {
-    }
-
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        mRS = rs;
-        mRes = res;
-        mWidth = width;
-        mHeight = height;
-        mRotation = 0;
-        initRS();
-    }
-
-    private Resources mRes;
-    private RenderScriptGL mRS;
-    private Sampler mSampler;
-    private ProgramStore mPSBackground;
-    private ProgramFragment mPFBackground;
-    private ProgramVertex mPVBackground;
-    private ProgramVertexFixedFunction.Constants mPVA;
-
-    private Allocation mGridImage;
-    private Allocation mAllocPV;
-
-    private Mesh mMesh;
-
-    private Font mItalic;
-    private Allocation mTextAlloc;
-
-    private ScriptC_simplemodel mScript;
-
-    int mLastX;
-    int mLastY;
-
-    public void touchEvent(int x, int y) {
-        int dx = mLastX - x;
-        if (Math.abs(dx) > 50 || Math.abs(dx) < 3) {
-            dx = 0;
-        }
-
-        mRotation -= dx;
-        if (mRotation > 360) {
-            mRotation -= 360;
-        }
-        if (mRotation < 0) {
-            mRotation += 360;
-        }
-
-        mScript.set_gRotate((float)mRotation);
-
-        mLastX = x;
-        mLastY = y;
-    }
-
-    private void initPFS() {
-        ProgramStore.Builder b = new ProgramStore.Builder(mRS);
-
-        b.setDepthFunc(ProgramStore.DepthFunc.LESS);
-        b.setDitherEnabled(false);
-        b.setDepthMaskEnabled(true);
-        mPSBackground = b.create();
-
-        mScript.set_gPFSBackground(mPSBackground);
-    }
-
-    private void initPF() {
-        Sampler.Builder bs = new Sampler.Builder(mRS);
-        bs.setMinification(Sampler.Value.LINEAR);
-        bs.setMagnification(Sampler.Value.LINEAR);
-        bs.setWrapS(Sampler.Value.CLAMP);
-        bs.setWrapT(Sampler.Value.CLAMP);
-        mSampler = bs.create();
-
-        ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
-        b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
-                     ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
-        mPFBackground = b.create();
-        mPFBackground.bindSampler(mSampler, 0);
-
-        mScript.set_gPFBackground(mPFBackground);
-    }
-
-    private void initPV() {
-        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
-        mPVBackground = pvb.create();
-
-        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
-        ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVA);
-
-        mScript.set_gPVBackground(mPVBackground);
-    }
-
-    private void loadImage() {
-        mGridImage = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot,
-                                                         Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
-                                                         Allocation.USAGE_GRAPHICS_TEXTURE);
-        mScript.set_gTGrid(mGridImage);
-    }
-
-    private void initTextAllocation() {
-        String allocString = "Displaying file: R.raw.robot";
-        mTextAlloc = Allocation.createFromString(mRS, allocString, Allocation.USAGE_SCRIPT);
-        mScript.set_gTextAlloc(mTextAlloc);
-    }
-
-    private void initRS() {
-
-        mScript = new ScriptC_simplemodel(mRS, mRes, R.raw.simplemodel);
-
-        initPFS();
-        initPF();
-        initPV();
-
-        loadImage();
-
-        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
-        FileA3D.IndexEntry entry = model.getIndexEntry(0);
-        if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
-            Log.e("rs", "could not load model");
-        } else {
-            mMesh = (Mesh)entry.getObject();
-            mScript.set_gTestMesh(mMesh);
-        }
-
-        mItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
-        mScript.set_gItalic(mItalic);
-
-        initTextAllocation();
-
-        mRS.bindRootScript(mScript);
-    }
-}
-
-
-
diff --git a/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java b/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java
deleted file mode 100644
index 5c5956d..0000000
--- a/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.modelviewer;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class SimpleModelView extends RSSurfaceView {
-
-    public SimpleModelView(Context context) {
-        super(context);
-        //setFocusable(true);
-    }
-
-    private RenderScriptGL mRS;
-    private SimpleModelRS mRender;
-
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-        if (mRS == null) {
-            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
-            sc.setDepth(16, 24);
-            mRS = createRenderScriptGL(sc);
-            mRS.setSurface(holder, w, h);
-            mRender = new SimpleModelRS();
-            mRender.init(mRS, getResources(), w, h);
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        if (mRS != null) {
-            mRS = null;
-            destroyRenderScriptGL();
-        }
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event)
-    {
-        // break point at here
-        // this method doesn't work when 'extends View' include 'extends ScrollView'.
-        return super.onKeyDown(keyCode, event);
-    }
-
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev)
-    {
-        boolean ret = true;
-        int act = ev.getAction();
-        if (act == ev.ACTION_UP) {
-            ret = false;
-        }
-
-        mRender.touchEvent((int)ev.getX(), (int)ev.getY());
-        return ret;
-    }
-}
-
-
diff --git a/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs b/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs
deleted file mode 100644
index 3679068..0000000
--- a/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.modelviewer)
-
-#include "rs_graphics.rsh"
-#include "transform_def.rsh"
-
-rs_program_vertex gPVBackground;
-rs_program_fragment gPFBackground;
-
-rs_allocation gTGrid;
-rs_mesh gTestMesh;
-
-rs_program_store gPFSBackground;
-
-float gRotate;
-
-rs_font gItalic;
-rs_allocation gTextAlloc;
-
-rs_script gTransformRS;
-
-SgTransform *gGroup;
-SgTransform *gRobot1;
-int gRobot1Index;
-SgTransform *gRobot2;
-int gRobot2Index;
-
-SgTransform *gRootNode;
-
-void init() {
-    gRotate = 0.0f;
-}
-
-int root(int launchID) {
-
-    gGroup->transforms[1].w += 0.5f;
-    gGroup->isDirty = 1;
-
-    SgTransform *robot1Ptr = gRobot1 + gRobot1Index;
-
-    robot1Ptr->transforms[1].w -= 1.5f;
-    robot1Ptr->isDirty = 1;
-
-    SgTransform *robot2Ptr = gRobot2 + gRobot2Index;
-    robot2Ptr->transforms[1].w += 2.5f;
-    robot2Ptr->isDirty = 1;
-
-    rsForEach(gTransformRS, gRootNode->children, gRootNode->children, 0);
-
-    rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgClearDepth(1.0f);
-
-    rsgBindProgramVertex(gPVBackground);
-    rs_matrix4x4 proj;
-    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
-    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
-    rsgProgramVertexLoadProjectionMatrix(&proj);
-
-    rsgBindProgramFragment(gPFBackground);
-    rsgBindProgramStore(gPFSBackground);
-    rsgBindTexture(gPFBackground, 0, gTGrid);
-
-    rsgProgramVertexLoadModelMatrix(&robot1Ptr->globalMat);
-    rsgDrawMesh(gTestMesh);
-
-    rsgProgramVertexLoadModelMatrix(&robot2Ptr->globalMat);
-    rsgDrawMesh(gTestMesh);
-
-    //color(0.3f, 0.3f, 0.3f, 1.0f);
-    rsgDrawText("Renderscript transform test", 30, 695);
-
-    rsgBindFont(gItalic);
-    rsgDrawText(gTextAlloc, 30, 730);
-
-    return 10;
-}
diff --git a/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs b/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs
deleted file mode 100644
index 419de62..0000000
--- a/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.modelviewer)
-
-#include "rs_graphics.rsh"
-
-rs_program_vertex gPVBackground;
-rs_program_fragment gPFBackground;
-
-rs_allocation gTGrid;
-rs_mesh gTestMesh;
-
-rs_program_store gPFSBackground;
-
-float gRotate;
-
-rs_font gItalic;
-rs_allocation gTextAlloc;
-
-void init() {
-    gRotate = 0.0f;
-}
-
-int root(int launchID) {
-
-    rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgClearDepth(1.0f);
-
-    rsgBindProgramVertex(gPVBackground);
-    rs_matrix4x4 proj;
-    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
-    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
-    rsgProgramVertexLoadProjectionMatrix(&proj);
-
-    rsgBindProgramFragment(gPFBackground);
-    rsgBindProgramStore(gPFSBackground);
-    rsgBindTexture(gPFBackground, 0, gTGrid);
-
-    rs_matrix4x4 matrix;
-    rsMatrixLoadIdentity(&matrix);
-    // Position our model on the screen
-    rsMatrixTranslate(&matrix, 0.0f, -0.3f, -10.0f);
-    rsMatrixScale(&matrix, 0.2f, 0.2f, 0.2f);
-    rsMatrixRotate(&matrix, 25.0f, 1.0f, 0.0f, 0.0f);
-    rsMatrixRotate(&matrix, gRotate, 0.0f, 1.0f, 0.0f);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    rsgDrawMesh(gTestMesh);
-
-    rsgFontColor(0.3f, 0.3f, 0.3f, 1.0f);
-    rsgDrawText("Renderscript model test", 30, 695);
-
-    rsgBindFont(gItalic);
-    rsgDrawText(gTextAlloc, 30, 730);
-
-    return 10;
-}
diff --git a/java/ModelViewer/src/com/android/modelviewer/transform.rs b/java/ModelViewer/src/com/android/modelviewer/transform.rs
deleted file mode 100644
index f328025..0000000
--- a/java/ModelViewer/src/com/android/modelviewer/transform.rs
+++ /dev/null
@@ -1,96 +0,0 @@
-// 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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.modelviewer)
-
-#include "transform_def.rsh"
-
-rs_script transformScript;
-
-typedef struct {
-    int changed;
-    rs_matrix4x4 *mat;
-} ParentData;
-
-static void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) {
-    rs_matrix4x4 temp;
-
-    switch (type) {
-    case TRANSFORM_TRANSLATE:
-        rsMatrixLoadTranslate(&temp, data.x, data.y, data.z);
-        break;
-    case TRANSFORM_ROTATE:
-        rsMatrixLoadRotate(&temp, data.w, data.x, data.y, data.z);
-        break;
-    case TRANSFORM_SCALE:
-        rsMatrixLoadScale(&temp, data.x, data.y, data.z);
-        break;
-    }
-    rsMatrixMultiply(mat, &temp);
-}
-
-void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) {
-
-    SgTransform *data = (SgTransform *)v_out;
-    const ParentData *parent = (const ParentData *)usrData;
-
-    //rsDebug("Transform data", (int)data);
-    //rsDebug("Entering parent", (int)parent);
-
-    rs_matrix4x4 *localMat = &data->localMat;
-    rs_matrix4x4 *globalMat = &data->globalMat;
-
-    ParentData toChild;
-    toChild.changed = 0;
-    toChild.mat = globalMat;
-
-    //rsDebug("Transform is dirty", data->isDirty);
-
-    // Refresh matrices if dirty
-    if (data->isDirty) {
-        data->isDirty = 0;
-        toChild.changed = 1;
-
-        // Reset our local matrix
-        rsMatrixLoadIdentity(localMat);
-
-        for (int i = 0; i < 16; i ++) {
-            if (data->transformTypes[i] == TRANSFORM_NONE) {
-                break;
-            }
-            //rsDebug("Transform adding transformation", transformTypes[i]);
-            appendTransformation(data->transformTypes[i], data->transforms[i], localMat);
-        }
-    }
-
-    //rsDebug("Transform checking parent", (int)0);
-
-    if (parent) {
-        if (parent->changed) {
-            toChild.changed = 1;
-
-            rsMatrixLoad(globalMat, parent->mat);
-            rsMatrixMultiply(globalMat, localMat);
-        }
-    } else {
-        rsMatrixLoad(globalMat, localMat);
-    }
-
-    //rsDebug("Transform calling self with child ", (int)data->children.p);
-    if (data->children.p) {
-        rsForEach(transformScript, data->children, data->children, (void*)&toChild);
-    }
-}
diff --git a/java/ModelViewer/src/com/android/modelviewer/transform_def.rsh b/java/ModelViewer/src/com/android/modelviewer/transform_def.rsh
deleted file mode 100644
index 24a36c1..0000000
--- a/java/ModelViewer/src/com/android/modelviewer/transform_def.rsh
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.modelviewer)
-
-#define TRANSFORM_NONE 0
-#define TRANSFORM_TRANSLATE 1
-#define TRANSFORM_ROTATE 2
-#define TRANSFORM_SCALE 3
-
-typedef struct __attribute__((packed, aligned(4))) SgTransform {
-    rs_matrix4x4 globalMat;
-    rs_matrix4x4 localMat;
-
-    float4 transforms[16];
-    int transformTypes[16];
-
-    int isDirty;
-
-    rs_allocation children;
-
-} SgTransform;
diff --git a/java/Samples/Android.mk b/java/Samples/Android.mk
deleted file mode 100644
index 65ae734..0000000
--- a/java/Samples/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
-
-LOCAL_PACKAGE_NAME := Samples
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/java/Samples/AndroidManifest.xml b/java/Samples/AndroidManifest.xml
deleted file mode 100644
index 9646a77..0000000
--- a/java/Samples/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.samples">
-    <application android:label="Samples"
-    android:icon="@drawable/test_pattern">
-        <activity android:name="RsList"
-                  android:label="RsList"
-                  android:theme="@android:style/Theme.Black.NoTitleBar">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-        
-        <activity android:name="RsRenderStates"
-                  android:label="RsStates"
-                  android:theme="@android:style/Theme.Black.NoTitleBar">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name="RsBench"
-                  android:label="RsBenchmark"
-                  android:theme="@android:style/Theme.Black.NoTitleBar">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/java/Samples/res/drawable/checker.png b/java/Samples/res/drawable/checker.png
deleted file mode 100644
index b631e1e..0000000
--- a/java/Samples/res/drawable/checker.png
+++ /dev/null
Binary files differ
diff --git a/java/Samples/res/drawable/cubemap_test.png b/java/Samples/res/drawable/cubemap_test.png
deleted file mode 100644
index baf35d0..0000000
--- a/java/Samples/res/drawable/cubemap_test.png
+++ /dev/null
Binary files differ
diff --git a/java/Samples/res/drawable/data.png b/java/Samples/res/drawable/data.png
deleted file mode 100644
index 8e34714..0000000
--- a/java/Samples/res/drawable/data.png
+++ /dev/null
Binary files differ
diff --git a/java/Samples/res/drawable/leaf.png b/java/Samples/res/drawable/leaf.png
deleted file mode 100644
index 3cd3775..0000000
--- a/java/Samples/res/drawable/leaf.png
+++ /dev/null
Binary files differ
diff --git a/java/Samples/res/drawable/test_pattern.png b/java/Samples/res/drawable/test_pattern.png
deleted file mode 100644
index e7d1455..0000000
--- a/java/Samples/res/drawable/test_pattern.png
+++ /dev/null
Binary files differ
diff --git a/java/Samples/res/drawable/torusmap.png b/java/Samples/res/drawable/torusmap.png
deleted file mode 100644
index 1e08f3b..0000000
--- a/java/Samples/res/drawable/torusmap.png
+++ /dev/null
Binary files differ
diff --git a/java/Samples/res/raw/multitexf.glsl b/java/Samples/res/raw/multitexf.glsl
deleted file mode 100644
index e492a47..0000000
--- a/java/Samples/res/raw/multitexf.glsl
+++ /dev/null
@@ -1,13 +0,0 @@
-varying vec2 varTex0;
-
-void main() {
-   vec2 t0 = varTex0.xy;
-   lowp vec4 col0 = texture2D(UNI_Tex0, t0).rgba;
-   lowp vec4 col1 = texture2D(UNI_Tex1, t0*4.0).rgba;
-   lowp vec4 col2 = texture2D(UNI_Tex2, t0).rgba;
-   col0.xyz = col0.xyz*col1.xyz*1.5;
-   col0.xyz = mix(col0.xyz, col2.xyz, col2.w);
-   col0.w = 0.5;
-   gl_FragColor = col0;
-}
-
diff --git a/java/Samples/res/raw/shader2f.glsl b/java/Samples/res/raw/shader2f.glsl
deleted file mode 100644
index 5fc05f1..0000000
--- a/java/Samples/res/raw/shader2f.glsl
+++ /dev/null
@@ -1,29 +0,0 @@
-varying vec3 varWorldPos;
-varying vec3 varWorldNormal;
-varying vec2 varTex0;
-
-void main() {
-
-   vec3 V = normalize(-varWorldPos.xyz);
-   vec3 worldNorm = normalize(varWorldNormal);
-
-   vec3 light0Vec = normalize(UNI_light0_Posision.xyz - varWorldPos);
-   vec3 light0R = -reflect(light0Vec, worldNorm);
-   float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light0_Diffuse;
-   float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
-   float light0_Specular = pow(light0Spec, UNI_light0_CosinePower) * UNI_light0_Specular;
-
-   vec3 light1Vec = normalize(UNI_light1_Posision.xyz - varWorldPos);
-   vec3 light1R = reflect(light1Vec, worldNorm);
-   float light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light1_Diffuse;
-   float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
-   float light1_Specular = pow(light1Spec, UNI_light1_CosinePower) * UNI_light1_Specular;
-
-   vec2 t0 = varTex0.xy;
-   lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
-   col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor.xyz + light1_Diffuse * UNI_light1_DiffuseColor.xyz);
-   col.xyz += light0_Specular * UNI_light0_SpecularColor.xyz;
-   col.xyz += light1_Specular * UNI_light1_SpecularColor.xyz;
-   gl_FragColor = col;
-}
-
diff --git a/java/Samples/res/raw/shader2movev.glsl b/java/Samples/res/raw/shader2movev.glsl
deleted file mode 100644
index a2c807e..0000000
--- a/java/Samples/res/raw/shader2movev.glsl
+++ /dev/null
@@ -1,21 +0,0 @@
-varying vec3 varWorldPos;
-varying vec3 varWorldNormal;
-varying vec2 varTex0;
-
-// This is where actual shader code begins
-void main() {
-   vec4 objPos = ATTRIB_position;
-   vec3 oldPos = objPos.xyz;
-   objPos.xyz += 0.1*sin(objPos.xyz*2.0 + UNI_time);
-   objPos.xyz += 0.05*sin(objPos.xyz*4.0 + UNI_time*0.5);
-   objPos.xyz += 0.02*sin(objPos.xyz*7.0 + UNI_time*0.75);
-   vec4 worldPos = UNI_model * objPos;
-   gl_Position = UNI_proj * worldPos;
-
-   mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
-   vec3 worldNorm = model3 * (ATTRIB_normal + oldPos - objPos.xyz);
-
-   varWorldPos = worldPos.xyz;
-   varWorldNormal = worldNorm;
-   varTex0 = ATTRIB_texture0;
-}
diff --git a/java/Samples/res/raw/shader2v.glsl b/java/Samples/res/raw/shader2v.glsl
deleted file mode 100644
index e6885a3..0000000
--- a/java/Samples/res/raw/shader2v.glsl
+++ /dev/null
@@ -1,17 +0,0 @@
-varying vec3 varWorldPos;
-varying vec3 varWorldNormal;
-varying vec2 varTex0;
-
-// This is where actual shader code begins
-void main() {
-   vec4 objPos = ATTRIB_position;
-   vec4 worldPos = UNI_model * objPos;
-   gl_Position = UNI_proj * worldPos;
-
-   mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
-   vec3 worldNorm = model3 * ATTRIB_normal;
-
-   varWorldPos = worldPos.xyz;
-   varWorldNormal = worldNorm;
-   varTex0 = ATTRIB_texture0;
-}
diff --git a/java/Samples/res/raw/shaderarrayf.glsl b/java/Samples/res/raw/shaderarrayf.glsl
deleted file mode 100644
index 238ecad..0000000
--- a/java/Samples/res/raw/shaderarrayf.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-
-varying lowp float light0_Diffuse;
-varying lowp float light0_Specular;
-varying lowp float light1_Diffuse;
-varying lowp float light1_Specular;
-varying vec2 varTex0;
-
-void main() {
-   vec2 t0 = varTex0.xy;
-   lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
-   col.xyz = col.xyz * (light0_Diffuse * UNI_light_DiffuseColor[0].xyz + light1_Diffuse * UNI_light_DiffuseColor[1].xyz);
-   col.xyz += light0_Specular * UNI_light_SpecularColor[0].xyz;
-   col.xyz += light1_Specular * UNI_light_SpecularColor[1].xyz;
-   gl_FragColor = col;
-}
-
diff --git a/java/Samples/res/raw/shaderarrayv.glsl b/java/Samples/res/raw/shaderarrayv.glsl
deleted file mode 100644
index 7a1310a..0000000
--- a/java/Samples/res/raw/shaderarrayv.glsl
+++ /dev/null
@@ -1,32 +0,0 @@
-varying float light0_Diffuse;
-varying float light0_Specular;
-varying float light1_Diffuse;
-varying float light1_Specular;
-varying vec2 varTex0;
-
-// This is where actual shader code begins
-void main() {
-   vec4 worldPos = UNI_model[0] * ATTRIB_position;
-   worldPos = UNI_model[1] * worldPos;
-   gl_Position = UNI_proj * worldPos;
-
-   mat4 model0 = UNI_model[0];
-   mat3 model3 = mat3(model0[0].xyz, model0[1].xyz, model0[2].xyz);
-   vec3 worldNorm = model3 * ATTRIB_normal;
-   vec3 V = normalize(-worldPos.xyz);
-
-   vec3 light0Vec = normalize(UNI_light_Posision[0].xyz - worldPos.xyz);
-   vec3 light0R = -reflect(light0Vec, worldNorm);
-   light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light_Diffuse[0];
-   float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
-   light0_Specular = pow(light0Spec, UNI_light_CosinePower[0]) * UNI_light_Specular[0];
-
-   vec3 light1Vec = normalize(UNI_light_Posision[1].xyz - worldPos.xyz);
-   vec3 light1R = reflect(light1Vec, worldNorm);
-   light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light_Diffuse[1];
-   float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
-   light1_Specular = pow(light1Spec, UNI_light_CosinePower[1]) * UNI_light_Specular[1];
-
-   gl_PointSize = 1.0;
-   varTex0 = ATTRIB_texture0;
-}
diff --git a/java/Samples/res/raw/shadercubef.glsl b/java/Samples/res/raw/shadercubef.glsl
deleted file mode 100644
index 15696a4..0000000
--- a/java/Samples/res/raw/shadercubef.glsl
+++ /dev/null
@@ -1,8 +0,0 @@
-
-varying vec3 worldNormal;
-
-void main() {
-   lowp vec4 col = textureCube(UNI_Tex0, worldNormal);
-   gl_FragColor = col;
-}
-
diff --git a/java/Samples/res/raw/shadercubev.glsl b/java/Samples/res/raw/shadercubev.glsl
deleted file mode 100644
index 70f5cd6..0000000
--- a/java/Samples/res/raw/shadercubev.glsl
+++ /dev/null
@@ -1,10 +0,0 @@
-varying vec3 worldNormal;
-
-// This is where actual shader code begins
-void main() {
-   vec4 worldPos = UNI_model * ATTRIB_position;
-   gl_Position = UNI_proj * worldPos;
-
-   mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
-   worldNormal = model3 * ATTRIB_normal;
-}
diff --git a/java/Samples/res/raw/shaderf.glsl b/java/Samples/res/raw/shaderf.glsl
deleted file mode 100644
index d56e203..0000000
--- a/java/Samples/res/raw/shaderf.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-
-varying lowp float light0_Diffuse;
-varying lowp float light0_Specular;
-varying lowp float light1_Diffuse;
-varying lowp float light1_Specular;
-varying vec2 varTex0;
-
-void main() {
-   vec2 t0 = varTex0.xy;
-   lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
-   col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor.xyz + light1_Diffuse * UNI_light1_DiffuseColor.xyz);
-   col.xyz += light0_Specular * UNI_light0_SpecularColor.xyz;
-   col.xyz += light1_Specular * UNI_light1_SpecularColor.xyz;
-   gl_FragColor = col;
-}
-
diff --git a/java/Samples/res/raw/shaderv.glsl b/java/Samples/res/raw/shaderv.glsl
deleted file mode 100644
index f7d01de..0000000
--- a/java/Samples/res/raw/shaderv.glsl
+++ /dev/null
@@ -1,30 +0,0 @@
-varying float light0_Diffuse;
-varying float light0_Specular;
-varying float light1_Diffuse;
-varying float light1_Specular;
-varying vec2 varTex0;
-
-// This is where actual shader code begins
-void main() {
-   vec4 worldPos = UNI_model * ATTRIB_position;
-   gl_Position = UNI_proj * worldPos;
-
-   mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
-   vec3 worldNorm = model3 * ATTRIB_normal;
-   vec3 V = normalize(-worldPos.xyz);
-
-   vec3 light0Vec = normalize(UNI_light0_Posision.xyz - worldPos.xyz);
-   vec3 light0R = -reflect(light0Vec, worldNorm);
-   light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light0_Diffuse;
-   float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
-   light0_Specular = pow(light0Spec, UNI_light0_CosinePower) * UNI_light0_Specular;
-
-   vec3 light1Vec = normalize(UNI_light1_Posision.xyz - worldPos.xyz);
-   vec3 light1R = reflect(light1Vec, worldNorm);
-   light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light1_Diffuse;
-   float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
-   light1_Specular = pow(light1Spec, UNI_light1_CosinePower) * UNI_light1_Specular;
-
-   gl_PointSize = 1.0;
-   varTex0 = ATTRIB_texture0;
-}
diff --git a/java/Samples/res/raw/torus.a3d b/java/Samples/res/raw/torus.a3d
deleted file mode 100644
index 0322b01..0000000
--- a/java/Samples/res/raw/torus.a3d
+++ /dev/null
Binary files differ
diff --git a/java/Samples/src/com/android/samples/RsBench.java b/java/Samples/src/com/android/samples/RsBench.java
deleted file mode 100644
index a29dddc..0000000
--- a/java/Samples/src/com/android/samples/RsBench.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.samples;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Config;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-public class RsBench extends Activity {
-
-    private RsBenchView mView;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        // Create our Preview view and set it as the content of our
-        // Activity
-        mView = new RsBenchView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity loses focus
-        super.onResume();
-        mView.resume();
-    }
-
-    @Override
-    protected void onPause() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity loses focus
-        super.onPause();
-        mView.pause();
-    }
-
-}
-
diff --git a/java/Samples/src/com/android/samples/RsBenchRS.java b/java/Samples/src/com/android/samples/RsBenchRS.java
deleted file mode 100644
index 1afcee3..0000000
--- a/java/Samples/src/com/android/samples/RsBenchRS.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.samples;
-
-import java.io.Writer;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.renderscript.*;
-import android.renderscript.Allocation.MipmapControl;
-import android.renderscript.Program.TextureType;
-import android.renderscript.ProgramStore.DepthFunc;
-import android.renderscript.ProgramStore.BlendSrcFunc;
-import android.renderscript.ProgramStore.BlendDstFunc;
-import android.renderscript.Sampler.Value;
-import android.util.Log;
-
-
-public class RsBenchRS {
-
-    int mWidth;
-    int mHeight;
-
-    public RsBenchRS() {
-    }
-
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        mRS = rs;
-        mRes = res;
-        mWidth = width;
-        mHeight = height;
-        mOptionsARGB.inScaled = false;
-        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
-        mMode = 0;
-        mMaxModes = 0;
-        initRS();
-    }
-
-    private Resources mRes;
-    private RenderScriptGL mRS;
-
-    private Sampler mLinearClamp;
-    private Sampler mLinearWrap;
-    private Sampler mMipLinearWrap;
-    private Sampler mNearestClamp;
-    private Sampler mMipLinearAniso8;
-    private Sampler mMipLinearAniso15;
-
-    private ProgramStore mProgStoreBlendNoneDepth;
-    private ProgramStore mProgStoreBlendNone;
-    private ProgramStore mProgStoreBlendAlpha;
-    private ProgramStore mProgStoreBlendAdd;
-
-    private ProgramFragment mProgFragmentTexture;
-    private ProgramFragment mProgFragmentColor;
-
-    private ProgramVertex mProgVertex;
-    private ProgramVertexFixedFunction.Constants mPVA;
-
-    // Custom shaders
-    private ProgramVertex mProgVertexCustom;
-    private ProgramFragment mProgFragmentCustom;
-    private ProgramFragment mProgFragmentMultitex;
-    private ProgramVertex mProgVertexPixelLight;
-    private ProgramVertex mProgVertexPixelLightMove;
-    private ProgramFragment mProgFragmentPixelLight;
-    private ScriptField_VertexShaderConstants_s mVSConst;
-    private ScriptField_FragentShaderConstants_s mFSConst;
-    private ScriptField_VertexShaderConstants3_s mVSConstPixel;
-    private ScriptField_FragentShaderConstants3_s mFSConstPixel;
-
-    private ProgramVertex mProgVertexCube;
-    private ProgramFragment mProgFragmentCube;
-
-    private ProgramRaster mCullBack;
-    private ProgramRaster mCullFront;
-    private ProgramRaster mCullNone;
-
-    private Allocation mTexTorus;
-    private Allocation mTexOpaque;
-    private Allocation mTexTransparent;
-    private Allocation mTexChecker;
-    private Allocation mTexCube;
-
-    private Mesh m10by10Mesh;
-    private Mesh m100by100Mesh;
-    private Mesh mWbyHMesh;
-    private Mesh mTorus;
-
-    Font mFontSans;
-    Font mFontSerif;
-    Font mFontSerifBold;
-    Font mFontSerifItalic;
-    Font mFontSerifBoldItalic;
-    Font mFontMono;
-    private Allocation mTextAlloc;
-
-    private ScriptC_rsbench mScript;
-
-    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
-
-    int mMode;
-    int mMaxModes;
-
-    public void onActionDown(int x, int y) {
-        mMode ++;
-        mMode = mMode % mMaxModes;
-        mScript.set_gDisplayMode(mMode);
-    }
-
-    ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
-        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
-        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
-        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
-        builder.setDitherEnabled(false);
-        builder.setDepthMaskEnabled(false);
-        return builder.create();
-    }
-
-    private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) {
-
-        Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
-                                           2, Mesh.TriangleMeshBuilder.TEXTURE_0);
-
-        for (int y = 0; y <= hResolution; y++) {
-            final float normalizedY = (float)y / hResolution;
-            final float yOffset = (normalizedY - 0.5f) * height;
-            for (int x = 0; x <= wResolution; x++) {
-                float normalizedX = (float)x / wResolution;
-                float xOffset = (normalizedX - 0.5f) * width;
-                tmb.setTexture((float)x % 2, (float)y % 2);
-                tmb.addVertex(xOffset, yOffset);
-             }
-        }
-
-        for (int y = 0; y < hResolution; y++) {
-            final int curY = y * (wResolution + 1);
-            final int belowY = (y + 1) * (wResolution + 1);
-            for (int x = 0; x < wResolution; x++) {
-                int curV = curY + x;
-                int belowV = belowY + x;
-                tmb.addTriangle(curV, belowV, curV + 1);
-                tmb.addTriangle(belowV, belowV + 1, curV + 1);
-            }
-        }
-
-        return tmb.create(true);
-    }
-
-    private void initProgramStore() {
-        // Use stock the stock program store object
-        mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS);
-        mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(mRS);
-
-        // Create a custom program store
-        ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
-        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
-        builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
-                             ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-        builder.setDitherEnabled(false);
-        builder.setDepthMaskEnabled(false);
-        mProgStoreBlendAlpha = builder.create();
-
-        mProgStoreBlendAdd = BLEND_ADD_DEPTH_NONE(mRS);
-
-        mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth);
-        mScript.set_gProgStoreBlendNone(mProgStoreBlendNone);
-        mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha);
-        mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd);
-    }
-
-    private void initProgramFragment() {
-
-        ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
-        texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
-                              ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
-        mProgFragmentTexture = texBuilder.create();
-        mProgFragmentTexture.bindSampler(mLinearClamp, 0);
-
-        ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
-        colBuilder.setVaryingColor(false);
-        mProgFragmentColor = colBuilder.create();
-
-        mScript.set_gProgFragmentColor(mProgFragmentColor);
-        mScript.set_gProgFragmentTexture(mProgFragmentTexture);
-    }
-
-    private void initProgramVertex() {
-        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
-        mProgVertex = pvb.create();
-
-        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
-        ((ProgramVertexFixedFunction)mProgVertex).bindConstants(mPVA);
-        Matrix4f proj = new Matrix4f();
-        proj.loadOrthoWindow(mWidth, mHeight);
-        mPVA.setProjection(proj);
-
-        mScript.set_gProgVertex(mProgVertex);
-    }
-
-    private void initCustomShaders() {
-        mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1);
-        mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1);
-        mScript.bind_gVSConstants(mVSConst);
-        mScript.bind_gFSConstants(mFSConst);
-
-        mVSConstPixel = new ScriptField_VertexShaderConstants3_s(mRS, 1);
-        mFSConstPixel = new ScriptField_FragentShaderConstants3_s(mRS, 1);
-        mScript.bind_gVSConstPixel(mVSConstPixel);
-        mScript.bind_gFSConstPixel(mFSConstPixel);
-
-        // Initialize the shader builder
-        ProgramVertex.Builder pvbCustom = new ProgramVertex.Builder(mRS);
-        // Specify the resource that contains the shader string
-        pvbCustom.setShader(mRes, R.raw.shaderv);
-        // Use a script field to specify the input layout
-        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
-        // Define the constant input layout
-        pvbCustom.addConstant(mVSConst.getAllocation().getType());
-        mProgVertexCustom = pvbCustom.create();
-        // Bind the source of constant data
-        mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0);
-
-        ProgramFragment.Builder pfbCustom = new ProgramFragment.Builder(mRS);
-        // Specify the resource that contains the shader string
-        pfbCustom.setShader(mRes, R.raw.shaderf);
-        // Tell the builder how many textures we have
-        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
-        // Define the constant input layout
-        pfbCustom.addConstant(mFSConst.getAllocation().getType());
-        mProgFragmentCustom = pfbCustom.create();
-        // Bind the source of constant data
-        mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0);
-
-        // Cubemap test shaders
-        pvbCustom = new ProgramVertex.Builder(mRS);
-        pvbCustom.setShader(mRes, R.raw.shadercubev);
-        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
-        pvbCustom.addConstant(mVSConst.getAllocation().getType());
-        mProgVertexCube = pvbCustom.create();
-        mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0);
-
-        pfbCustom = new ProgramFragment.Builder(mRS);
-        pfbCustom.setShader(mRes, R.raw.shadercubef);
-        pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE);
-        mProgFragmentCube = pfbCustom.create();
-
-        pvbCustom = new ProgramVertex.Builder(mRS);
-        pvbCustom.setShader(mRes, R.raw.shader2v);
-        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
-        pvbCustom.addConstant(mVSConstPixel.getAllocation().getType());
-        mProgVertexPixelLight = pvbCustom.create();
-        mProgVertexPixelLight.bindConstants(mVSConstPixel.getAllocation(), 0);
-
-        pvbCustom = new ProgramVertex.Builder(mRS);
-        pvbCustom.setShader(mRes, R.raw.shader2movev);
-        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
-        pvbCustom.addConstant(mVSConstPixel.getAllocation().getType());
-        mProgVertexPixelLightMove = pvbCustom.create();
-        mProgVertexPixelLightMove.bindConstants(mVSConstPixel.getAllocation(), 0);
-
-        pfbCustom = new ProgramFragment.Builder(mRS);
-        pfbCustom.setShader(mRes, R.raw.shader2f);
-        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
-        pfbCustom.addConstant(mFSConstPixel.getAllocation().getType());
-        mProgFragmentPixelLight = pfbCustom.create();
-        mProgFragmentPixelLight.bindConstants(mFSConstPixel.getAllocation(), 0);
-
-        pfbCustom = new ProgramFragment.Builder(mRS);
-        pfbCustom.setShader(mRes, R.raw.multitexf);
-        for (int texCount = 0; texCount < 3; texCount ++) {
-            pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
-        }
-        mProgFragmentMultitex = pfbCustom.create();
-
-        mScript.set_gProgVertexCustom(mProgVertexCustom);
-        mScript.set_gProgFragmentCustom(mProgFragmentCustom);
-        mScript.set_gProgVertexCube(mProgVertexCube);
-        mScript.set_gProgFragmentCube(mProgFragmentCube);
-        mScript.set_gProgVertexPixelLight(mProgVertexPixelLight);
-        mScript.set_gProgVertexPixelLightMove(mProgVertexPixelLightMove);
-        mScript.set_gProgFragmentPixelLight(mProgFragmentPixelLight);
-        mScript.set_gProgFragmentMultitex(mProgFragmentMultitex);
-    }
-
-    private Allocation loadTextureRGB(int id) {
-        return Allocation.createFromBitmapResource(mRS, mRes, id,
-                Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
-                Allocation.USAGE_GRAPHICS_TEXTURE);
-    }
-
-    private Allocation loadTextureARGB(int id) {
-        Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB);
-        return Allocation.createFromBitmap(mRS, b,
-                Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
-                Allocation.USAGE_GRAPHICS_TEXTURE);
-    }
-
-    private void loadImages() {
-        mTexTorus = loadTextureRGB(R.drawable.torusmap);
-        mTexOpaque = loadTextureRGB(R.drawable.data);
-        mTexTransparent = loadTextureARGB(R.drawable.leaf);
-        mTexChecker = loadTextureRGB(R.drawable.checker);
-        Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.cubemap_test);
-        mTexCube = Allocation.createCubemapFromBitmap(mRS, b);
-
-        mScript.set_gTexTorus(mTexTorus);
-        mScript.set_gTexOpaque(mTexOpaque);
-        mScript.set_gTexTransparent(mTexTransparent);
-        mScript.set_gTexChecker(mTexChecker);
-        mScript.set_gTexCube(mTexCube);
-    }
-
-    private void initFonts() {
-        // Sans font by family name
-        mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
-        mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8);
-        // Create fonts by family and style
-        mFontSerifBold = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
-        mFontSerifItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
-        mFontSerifBoldItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
-        mFontMono = Font.create(mRS, mRes, "mono", Font.Style.NORMAL, 8);
-
-        mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
-
-        mScript.set_gFontSans(mFontSans);
-        mScript.set_gFontSerif(mFontSerif);
-        mScript.set_gFontSerifBold(mFontSerifBold);
-        mScript.set_gFontSerifItalic(mFontSerifItalic);
-        mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic);
-        mScript.set_gFontMono(mFontMono);
-        mScript.set_gTextAlloc(mTextAlloc);
-    }
-
-    private void initMesh() {
-        m10by10Mesh = getMbyNMesh(mWidth, mHeight, 10, 10);
-        mScript.set_g10by10Mesh(m10by10Mesh);
-        m100by100Mesh = getMbyNMesh(mWidth, mHeight, 100, 100);
-        mScript.set_g100by100Mesh(m100by100Mesh);
-        mWbyHMesh= getMbyNMesh(mWidth, mHeight, mWidth/4, mHeight/4);
-        mScript.set_gWbyHMesh(mWbyHMesh);
-
-        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
-        FileA3D.IndexEntry entry = model.getIndexEntry(0);
-        if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
-            Log.e("rs", "could not load model");
-        } else {
-            mTorus = (Mesh)entry.getObject();
-            mScript.set_gTorusMesh(mTorus);
-        }
-    }
-
-    private void initSamplers() {
-        Sampler.Builder bs = new Sampler.Builder(mRS);
-        bs.setMinification(Sampler.Value.LINEAR);
-        bs.setMagnification(Sampler.Value.LINEAR);
-        bs.setWrapS(Sampler.Value.WRAP);
-        bs.setWrapT(Sampler.Value.WRAP);
-        mLinearWrap = bs.create();
-
-        mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
-        mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
-        mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
-
-        bs = new Sampler.Builder(mRS);
-        bs.setMinification(Sampler.Value.LINEAR_MIP_LINEAR);
-        bs.setMagnification(Sampler.Value.LINEAR);
-        bs.setWrapS(Sampler.Value.WRAP);
-        bs.setWrapT(Sampler.Value.WRAP);
-        bs.setAnisotropy(8.0f);
-        mMipLinearAniso8 = bs.create();
-        bs.setAnisotropy(15.0f);
-        mMipLinearAniso15 = bs.create();
-
-        mScript.set_gLinearClamp(mLinearClamp);
-        mScript.set_gLinearWrap(mLinearWrap);
-        mScript.set_gMipLinearWrap(mMipLinearWrap);
-        mScript.set_gMipLinearAniso8(mMipLinearAniso8);
-        mScript.set_gMipLinearAniso15(mMipLinearAniso15);
-        mScript.set_gNearestClamp(mNearestClamp);
-    }
-
-    private void initProgramRaster() {
-        mCullBack = ProgramRaster.CULL_BACK(mRS);
-        mCullFront = ProgramRaster.CULL_FRONT(mRS);
-        mCullNone = ProgramRaster.CULL_NONE(mRS);
-
-        mScript.set_gCullBack(mCullBack);
-        mScript.set_gCullFront(mCullFront);
-        mScript.set_gCullNone(mCullNone);
-    }
-
-    private void initRS() {
-
-        mScript = new ScriptC_rsbench(mRS, mRes, R.raw.rsbench);
-
-        mMaxModes = mScript.get_gMaxModes();
-
-        initSamplers();
-        initProgramStore();
-        initProgramFragment();
-        initProgramVertex();
-        initFonts();
-        loadImages();
-        initMesh();
-        initProgramRaster();
-        initCustomShaders();
-
-        mRS.bindRootScript(mScript);
-    }
-}
-
-
-
diff --git a/java/Samples/src/com/android/samples/RsBenchView.java b/java/Samples/src/com/android/samples/RsBenchView.java
deleted file mode 100644
index 0a56668..0000000
--- a/java/Samples/src/com/android/samples/RsBenchView.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.samples;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class RsBenchView extends RSSurfaceView {
-
-    public RsBenchView(Context context) {
-        super(context);
-    }
-
-    private RenderScriptGL mRS;
-    private RsBenchRS mRender;
-
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-        if (mRS == null) {
-            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
-            sc.setDepth(16, 24);
-            mRS = createRenderScriptGL(sc);
-            mRS.setSurface(holder, w, h);
-            mRender = new RsBenchRS();
-            mRender.init(mRS, getResources(), w, h);
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        if (mRS != null) {
-            mRS = null;
-            destroyRenderScriptGL();
-        }
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        return super.onKeyDown(keyCode, event);
-    }
-
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        boolean ret = false;
-        int act = ev.getAction();
-        if (act == ev.ACTION_DOWN) {
-            mRender.onActionDown((int)ev.getX(), (int)ev.getY());
-            ret = true;
-        }
-
-        return ret;
-    }
-}
-
-
diff --git a/java/Samples/src/com/android/samples/RsList.java b/java/Samples/src/com/android/samples/RsList.java
deleted file mode 100644
index d47be42..0000000
--- a/java/Samples/src/com/android/samples/RsList.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.samples;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Config;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-public class RsList extends Activity {
-
-    private RsListView mView;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        // Create our Preview view and set it as the content of our
-        // Activity
-        mView = new RsListView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity loses focus
-        super.onResume();
-        mView.resume();
-    }
-
-    @Override
-    protected void onPause() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity loses focus
-        super.onPause();
-        mView.pause();
-    }
-
-}
-
diff --git a/java/Samples/src/com/android/samples/RsListRS.java b/java/Samples/src/com/android/samples/RsListRS.java
deleted file mode 100644
index 8e2d51f..0000000
--- a/java/Samples/src/com/android/samples/RsListRS.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.samples;
-
-import java.io.Writer;
-import java.util.Vector;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.renderscript.ProgramStore.DepthFunc;
-import android.util.Log;
-
-
-public class RsListRS {
-
-    private final int STATE_LAST_FOCUS = 1;
-
-    private static final String[] DATA_LIST = {
-    "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
-    "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
-    "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
-    "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
-    "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
-    "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil",
-    "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria",
-    "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
-    "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
-    "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
-    "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
-    "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
-    "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
-    "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
-    "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
-    "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
-    "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
-    "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
-    "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
-    "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
-    "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
-    "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
-    "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
-    "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
-    "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
-    "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
-    "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
-    "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
-    "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
-    "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
-    "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
-    "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
-    "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
-    "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
-    "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
-    "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
-    "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
-    "Ukraine", "United Arab Emirates", "United Kingdom",
-    "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
-    "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
-    "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
-    };
-
-    int mWidth;
-    int mHeight;
-
-    public RsListRS() {
-    }
-
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        mRS = rs;
-        mRes = res;
-        mWidth = width;
-        mHeight = height;
-        initRS();
-    }
-
-    private Resources mRes;
-    private RenderScriptGL mRS;
-    private Font mItalic;
-
-    ScriptField_ListAllocs_s mListAllocs;
-
-    private ScriptC_rslist mScript;
-
-    int mLastX;
-    int mLastY;
-
-    public void onActionDown(int x, int y) {
-        mScript.set_gDY(0.0f);
-
-        mLastX = x;
-        mLastY = y;
-    }
-
-    public void onActionMove(int x, int y) {
-        int dx = mLastX - x;
-        int dy = mLastY - y;
-
-        if (Math.abs(dy) <= 2) {
-            dy = 0;
-        }
-
-        mScript.set_gDY(dy);
-
-        mLastX = x;
-        mLastY = y;
-    }
-
-    private void initRS() {
-
-        mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist);
-
-        mListAllocs = new ScriptField_ListAllocs_s(mRS, DATA_LIST.length);
-        for (int i = 0; i < DATA_LIST.length; i ++) {
-            ScriptField_ListAllocs_s.Item listElem = new ScriptField_ListAllocs_s.Item();
-            listElem.text = Allocation.createFromString(mRS, DATA_LIST[i], Allocation.USAGE_SCRIPT);
-            mListAllocs.set(listElem, i, false);
-        }
-
-        mListAllocs.copyAll();
-
-        mScript.bind_gList(mListAllocs);
-
-        mItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
-        mScript.set_gItalic(mItalic);
-
-        mRS.bindRootScript(mScript);
-    }
-}
-
-
-
diff --git a/java/Samples/src/com/android/samples/RsListView.java b/java/Samples/src/com/android/samples/RsListView.java
deleted file mode 100644
index 00b1723..0000000
--- a/java/Samples/src/com/android/samples/RsListView.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.samples;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class RsListView extends RSSurfaceView {
-
-    public RsListView(Context context) {
-        super(context);
-        //setFocusable(true);
-    }
-
-    private RenderScriptGL mRS;
-    private RsListRS mRender;
-
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-        if (mRS == null) {
-            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
-            sc.setDepth(16, 24);
-            mRS = createRenderScriptGL(sc);
-            mRS.setSurface(holder, w, h);
-            mRender = new RsListRS();
-            mRender.init(mRS, getResources(), w, h);
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        if (mRS != null) {
-            mRS = null;
-            destroyRenderScriptGL();
-        }
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event)
-    {
-        // break point at here
-        // this method doesn't work when 'extends View' include 'extends ScrollView'.
-        return super.onKeyDown(keyCode, event);
-    }
-
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev)
-    {
-        boolean ret = false;
-        int act = ev.getAction();
-        if (act == ev.ACTION_DOWN) {
-            mRender.onActionDown((int)ev.getX(), (int)ev.getY());
-            ret = true;
-        } else if (act == ev.ACTION_MOVE) {
-            mRender.onActionMove((int)ev.getX(), (int)ev.getY());
-            ret = true;
-        }
-
-        return ret;
-    }
-}
-
-
diff --git a/java/Samples/src/com/android/samples/RsRenderStates.java b/java/Samples/src/com/android/samples/RsRenderStates.java
deleted file mode 100644
index 33c1719..0000000
--- a/java/Samples/src/com/android/samples/RsRenderStates.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.samples;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Config;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-public class RsRenderStates extends Activity {
-
-    private RsRenderStatesView mView;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        // Create our Preview view and set it as the content of our
-        // Activity
-        mView = new RsRenderStatesView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onResume();
-        mView.resume();
-    }
-
-    @Override
-    protected void onPause() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity looses focus
-        super.onPause();
-        mView.pause();
-    }
-
-}
-
diff --git a/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/java/Samples/src/com/android/samples/RsRenderStatesRS.java
deleted file mode 100644
index 87840a7..0000000
--- a/java/Samples/src/com/android/samples/RsRenderStatesRS.java
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.samples;
-
-import java.io.Writer;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.renderscript.*;
-import android.renderscript.Font.Style;
-import android.renderscript.Program.TextureType;
-import android.renderscript.ProgramStore.DepthFunc;
-import android.renderscript.ProgramStore.BlendSrcFunc;
-import android.renderscript.ProgramStore.BlendDstFunc;
-import android.renderscript.Sampler.Value;
-import android.util.Log;
-
-
-public class RsRenderStatesRS {
-
-    int mWidth;
-    int mHeight;
-
-    public RsRenderStatesRS() {
-    }
-
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        mRS = rs;
-        mRes = res;
-        mWidth = width;
-        mHeight = height;
-        mOptionsARGB.inScaled = false;
-        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
-        mMode = 0;
-        mMaxModes = 0;
-        initRS();
-    }
-
-    private Resources mRes;
-    private RenderScriptGL mRS;
-
-    private Sampler mLinearClamp;
-    private Sampler mLinearWrap;
-    private Sampler mMipLinearWrap;
-    private Sampler mNearestClamp;
-    private Sampler mMipLinearAniso8;
-    private Sampler mMipLinearAniso15;
-
-    private ProgramStore mProgStoreBlendNoneDepth;
-    private ProgramStore mProgStoreBlendNone;
-    private ProgramStore mProgStoreBlendAlpha;
-    private ProgramStore mProgStoreBlendAdd;
-
-    private ProgramFragment mProgFragmentTexture;
-    private ProgramFragment mProgFragmentColor;
-
-    private ProgramVertex mProgVertex;
-    private ProgramVertexFixedFunction.Constants mPVA;
-
-    // Custom shaders
-    private ProgramVertex mProgVertexCustom;
-    private ProgramFragment mProgFragmentCustom;
-    private ProgramFragment mProgFragmentMultitex;
-    private ScriptField_VertexShaderConstants_s mVSConst;
-    private ScriptField_VertexShaderConstants2_s mVSConst2;
-    private ScriptField_FragentShaderConstants_s mFSConst;
-    private ScriptField_FragentShaderConstants2_s mFSConst2;
-
-    private ProgramVertex mProgVertexCustom2;
-    private ProgramFragment mProgFragmentCustom2;
-
-    private ProgramVertex mProgVertexCube;
-    private ProgramFragment mProgFragmentCube;
-
-    private ProgramRaster mCullBack;
-    private ProgramRaster mCullFront;
-    private ProgramRaster mCullNone;
-
-    private Allocation mTexTorus;
-    private Allocation mTexOpaque;
-    private Allocation mTexTransparent;
-    private Allocation mTexChecker;
-    private Allocation mTexCube;
-
-    private Mesh mMbyNMesh;
-    private Mesh mTorus;
-
-    Font mFontSans;
-    Font mFontSerif;
-    Font mFontSerifBold;
-    Font mFontSerifItalic;
-    Font mFontSerifBoldItalic;
-    Font mFontMono;
-    private Allocation mTextAlloc;
-
-    private ScriptC_rsrenderstates mScript;
-
-    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
-
-    int mMode;
-    int mMaxModes;
-
-    public void onActionDown(int x, int y) {
-        mMode ++;
-        mMode = mMode % mMaxModes;
-        mScript.set_gDisplayMode(mMode);
-    }
-
-    ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
-        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
-        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
-        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
-        builder.setDitherEnabled(false);
-        builder.setDepthMaskEnabled(false);
-        return builder.create();
-    }
-
-    private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) {
-
-        Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
-                                           2, Mesh.TriangleMeshBuilder.TEXTURE_0);
-
-        for (int y = 0; y <= hResolution; y++) {
-            final float normalizedY = (float)y / hResolution;
-            final float yOffset = (normalizedY - 0.5f) * height;
-            for (int x = 0; x <= wResolution; x++) {
-                float normalizedX = (float)x / wResolution;
-                float xOffset = (normalizedX - 0.5f) * width;
-                tmb.setTexture(normalizedX, normalizedY);
-                tmb.addVertex(xOffset, yOffset);
-             }
-        }
-
-        for (int y = 0; y < hResolution; y++) {
-            final int curY = y * (wResolution + 1);
-            final int belowY = (y + 1) * (wResolution + 1);
-            for (int x = 0; x < wResolution; x++) {
-                int curV = curY + x;
-                int belowV = belowY + x;
-                tmb.addTriangle(curV, belowV, curV + 1);
-                tmb.addTriangle(belowV, belowV + 1, curV + 1);
-            }
-        }
-
-        return tmb.create(true);
-    }
-
-    private void initProgramStore() {
-        // Use stock the stock program store object
-        mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS);
-        mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(mRS);
-
-        // Create a custom program store
-        ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
-        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
-        builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
-                             ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-        builder.setDitherEnabled(false);
-        builder.setDepthMaskEnabled(false);
-        mProgStoreBlendAlpha = builder.create();
-
-        mProgStoreBlendAdd = BLEND_ADD_DEPTH_NONE(mRS);
-
-        mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth);
-        mScript.set_gProgStoreBlendNone(mProgStoreBlendNone);
-        mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha);
-        mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd);
-    }
-
-    private void initProgramFragment() {
-
-        ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
-        texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
-                              ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
-        mProgFragmentTexture = texBuilder.create();
-        mProgFragmentTexture.bindSampler(mLinearClamp, 0);
-
-        ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
-        colBuilder.setVaryingColor(false);
-        mProgFragmentColor = colBuilder.create();
-
-        mScript.set_gProgFragmentColor(mProgFragmentColor);
-        mScript.set_gProgFragmentTexture(mProgFragmentTexture);
-    }
-
-    private void initProgramVertex() {
-        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
-        mProgVertex = pvb.create();
-
-        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
-        ((ProgramVertexFixedFunction)mProgVertex).bindConstants(mPVA);
-        Matrix4f proj = new Matrix4f();
-        proj.loadOrthoWindow(mWidth, mHeight);
-        mPVA.setProjection(proj);
-
-        mScript.set_gProgVertex(mProgVertex);
-    }
-
-    private void initCustomShaders() {
-        mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1);
-        mVSConst2 = new ScriptField_VertexShaderConstants2_s(mRS, 1);
-        mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1);
-        mFSConst2 = new ScriptField_FragentShaderConstants2_s(mRS, 1);
-
-        mScript.bind_gVSConstants(mVSConst);
-        mScript.bind_gVSConstants2(mVSConst2);
-        mScript.bind_gFSConstants(mFSConst);
-        mScript.bind_gFSConstants2(mFSConst2);
-
-        // Initialize the shader builder
-        ProgramVertex.Builder pvbCustom = new ProgramVertex.Builder(mRS);
-        // Specify the resource that contains the shader string
-        pvbCustom.setShader(mRes, R.raw.shaderv);
-        // Use a script field to spcify the input layout
-        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
-        // Define the constant input layout
-        pvbCustom.addConstant(mVSConst.getAllocation().getType());
-        mProgVertexCustom = pvbCustom.create();
-        // Bind the source of constant data
-        mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0);
-
-        ProgramFragment.Builder pfbCustom = new ProgramFragment.Builder(mRS);
-        // Specify the resource that contains the shader string
-        pfbCustom.setShader(mRes, R.raw.shaderf);
-        //Tell the builder how many textures we have
-        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
-        // Define the constant input layout
-        pfbCustom.addConstant(mFSConst.getAllocation().getType());
-        mProgFragmentCustom = pfbCustom.create();
-        // Bind the source of constant data
-        mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0);
-
-        pvbCustom = new ProgramVertex.Builder(mRS);
-        pvbCustom.setShader(mRes, R.raw.shaderarrayv);
-        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
-        pvbCustom.addConstant(mVSConst2.getAllocation().getType());
-        mProgVertexCustom2 = pvbCustom.create();
-        mProgVertexCustom2.bindConstants(mVSConst2.getAllocation(), 0);
-
-        pfbCustom = new ProgramFragment.Builder(mRS);
-        pfbCustom.setShader(mRes, R.raw.shaderarrayf);
-        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
-        pfbCustom.addConstant(mFSConst2.getAllocation().getType());
-        mProgFragmentCustom2 = pfbCustom.create();
-        mProgFragmentCustom2.bindConstants(mFSConst2.getAllocation(), 0);
-
-        // Cubemap test shaders
-        pvbCustom = new ProgramVertex.Builder(mRS);
-        pvbCustom.setShader(mRes, R.raw.shadercubev);
-        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
-        pvbCustom.addConstant(mVSConst.getAllocation().getType());
-        mProgVertexCube = pvbCustom.create();
-        mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0);
-
-        pfbCustom = new ProgramFragment.Builder(mRS);
-        pfbCustom.setShader(mRes, R.raw.shadercubef);
-        pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE);
-        mProgFragmentCube = pfbCustom.create();
-
-        pfbCustom = new ProgramFragment.Builder(mRS);
-        pfbCustom.setShader(mRes, R.raw.multitexf);
-        for (int texCount = 0; texCount < 3; texCount ++) {
-            pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
-        }
-        mProgFragmentMultitex = pfbCustom.create();
-
-        mScript.set_gProgVertexCustom(mProgVertexCustom);
-        mScript.set_gProgFragmentCustom(mProgFragmentCustom);
-        mScript.set_gProgVertexCustom2(mProgVertexCustom2);
-        mScript.set_gProgFragmentCustom2(mProgFragmentCustom2);
-        mScript.set_gProgVertexCube(mProgVertexCube);
-        mScript.set_gProgFragmentCube(mProgFragmentCube);
-        mScript.set_gProgFragmentMultitex(mProgFragmentMultitex);
-    }
-
-    private Allocation loadTextureRGB(int id) {
-        return Allocation.createFromBitmapResource(mRS, mRes, id,
-                                                   Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
-                                                   Allocation.USAGE_GRAPHICS_TEXTURE);
-    }
-
-    private Allocation loadTextureARGB(int id) {
-        Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB);
-        return Allocation.createFromBitmap(mRS, b,
-                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
-                                           Allocation.USAGE_GRAPHICS_TEXTURE);
-    }
-
-    private void loadImages() {
-        mTexTorus = loadTextureRGB(R.drawable.torusmap);
-        mTexOpaque = loadTextureRGB(R.drawable.data);
-        mTexTransparent = loadTextureARGB(R.drawable.leaf);
-        mTexChecker = loadTextureRGB(R.drawable.checker);
-        Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.cubemap_test);
-        mTexCube = Allocation.createCubemapFromBitmap(mRS, b);
-
-        mScript.set_gTexTorus(mTexTorus);
-        mScript.set_gTexOpaque(mTexOpaque);
-        mScript.set_gTexTransparent(mTexTransparent);
-        mScript.set_gTexChecker(mTexChecker);
-        mScript.set_gTexCube(mTexCube);
-    }
-
-    private void initFonts() {
-        // Sans font by family name
-        mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
-        mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8);
-        // Create fonts by family and style
-        mFontSerifBold = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
-        mFontSerifItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
-        mFontSerifBoldItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
-        mFontMono = Font.create(mRS, mRes, "mono", Font.Style.NORMAL, 8);
-
-        mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
-
-        mScript.set_gFontSans(mFontSans);
-        mScript.set_gFontSerif(mFontSerif);
-        mScript.set_gFontSerifBold(mFontSerifBold);
-        mScript.set_gFontSerifItalic(mFontSerifItalic);
-        mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic);
-        mScript.set_gFontMono(mFontMono);
-        mScript.set_gTextAlloc(mTextAlloc);
-    }
-
-    private void initMesh() {
-        mMbyNMesh = getMbyNMesh(256, 256, 10, 10);
-        mScript.set_gMbyNMesh(mMbyNMesh);
-
-        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
-        FileA3D.IndexEntry entry = model.getIndexEntry(0);
-        if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
-            Log.e("rs", "could not load model");
-        } else {
-            mTorus = (Mesh)entry.getObject();
-            mScript.set_gTorusMesh(mTorus);
-        }
-    }
-
-    private void initSamplers() {
-        Sampler.Builder bs = new Sampler.Builder(mRS);
-        bs.setMinification(Sampler.Value.LINEAR);
-        bs.setMagnification(Sampler.Value.LINEAR);
-        bs.setWrapS(Sampler.Value.WRAP);
-        bs.setWrapT(Sampler.Value.WRAP);
-        mLinearWrap = bs.create();
-
-        mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
-        mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
-        mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
-
-        bs = new Sampler.Builder(mRS);
-        bs.setMinification(Sampler.Value.LINEAR_MIP_LINEAR);
-        bs.setMagnification(Sampler.Value.LINEAR);
-        bs.setWrapS(Sampler.Value.WRAP);
-        bs.setWrapT(Sampler.Value.WRAP);
-        bs.setAnisotropy(8.0f);
-        mMipLinearAniso8 = bs.create();
-        bs.setAnisotropy(15.0f);
-        mMipLinearAniso15 = bs.create();
-
-        mScript.set_gLinearClamp(mLinearClamp);
-        mScript.set_gLinearWrap(mLinearWrap);
-        mScript.set_gMipLinearWrap(mMipLinearWrap);
-        mScript.set_gMipLinearAniso8(mMipLinearAniso8);
-        mScript.set_gMipLinearAniso15(mMipLinearAniso15);
-        mScript.set_gNearestClamp(mNearestClamp);
-    }
-
-    private void initProgramRaster() {
-        mCullBack = ProgramRaster.CULL_BACK(mRS);
-        mCullFront = ProgramRaster.CULL_FRONT(mRS);
-        mCullNone = ProgramRaster.CULL_NONE(mRS);
-
-        mScript.set_gCullBack(mCullBack);
-        mScript.set_gCullFront(mCullFront);
-        mScript.set_gCullNone(mCullNone);
-    }
-
-    private void initRS() {
-
-        mScript = new ScriptC_rsrenderstates(mRS, mRes, R.raw.rsrenderstates);
-
-        mMaxModes = mScript.get_gMaxModes();
-
-        initSamplers();
-        initProgramStore();
-        initProgramFragment();
-        initProgramVertex();
-        initFonts();
-        loadImages();
-        initMesh();
-        initProgramRaster();
-        initCustomShaders();
-
-        mRS.bindRootScript(mScript);
-    }
-}
-
-
-
diff --git a/java/Samples/src/com/android/samples/RsRenderStatesView.java b/java/Samples/src/com/android/samples/RsRenderStatesView.java
deleted file mode 100644
index 235d29b..0000000
--- a/java/Samples/src/com/android/samples/RsRenderStatesView.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.samples;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class RsRenderStatesView extends RSSurfaceView {
-
-    public RsRenderStatesView(Context context) {
-        super(context);
-        //setFocusable(true);
-    }
-
-    private RenderScriptGL mRS;
-    private RsRenderStatesRS mRender;
-
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-        if (mRS == null) {
-            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
-            sc.setDepth(16, 24);
-            mRS = createRenderScriptGL(sc);
-            mRS.setSurface(holder, w, h);
-            mRender = new RsRenderStatesRS();
-            mRender.init(mRS, getResources(), w, h);
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        if (mRS != null) {
-            mRS = null;
-            destroyRenderScriptGL();
-        }
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event)
-    {
-        // break point at here
-        // this method doesn't work when 'extends View' include 'extends ScrollView'.
-        return super.onKeyDown(keyCode, event);
-    }
-
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev)
-    {
-        boolean ret = false;
-        int act = ev.getAction();
-        if (act == ev.ACTION_DOWN) {
-            mRender.onActionDown((int)ev.getX(), (int)ev.getY());
-            ret = true;
-        }
-
-        return ret;
-    }
-}
-
-
diff --git a/java/Samples/src/com/android/samples/rsbench.rs b/java/Samples/src/com/android/samples/rsbench.rs
deleted file mode 100644
index 905f34b..0000000
--- a/java/Samples/src/com/android/samples/rsbench.rs
+++ /dev/null
@@ -1,789 +0,0 @@
-// 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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.samples)
-
-#include "rs_graphics.rsh"
-#include "shader_def.rsh"
-
-const int gMaxModes = 26;
-
-rs_program_vertex gProgVertex;
-rs_program_fragment gProgFragmentColor;
-rs_program_fragment gProgFragmentTexture;
-
-rs_program_store gProgStoreBlendNoneDepth;
-rs_program_store gProgStoreBlendNone;
-rs_program_store gProgStoreBlendAlpha;
-rs_program_store gProgStoreBlendAdd;
-
-rs_allocation gTexOpaque;
-rs_allocation gTexTorus;
-rs_allocation gTexTransparent;
-rs_allocation gTexChecker;
-rs_allocation gTexCube;
-
-rs_mesh g10by10Mesh;
-rs_mesh g100by100Mesh;
-rs_mesh gWbyHMesh;
-rs_mesh gTorusMesh;
-
-rs_font gFontSans;
-rs_font gFontSerif;
-rs_font gFontSerifBold;
-rs_font gFontSerifItalic;
-rs_font gFontSerifBoldItalic;
-rs_font gFontMono;
-rs_allocation gTextAlloc;
-
-int gDisplayMode;
-
-rs_sampler gLinearClamp;
-rs_sampler gLinearWrap;
-rs_sampler gMipLinearWrap;
-rs_sampler gMipLinearAniso8;
-rs_sampler gMipLinearAniso15;
-rs_sampler gNearestClamp;
-
-rs_program_raster gCullBack;
-rs_program_raster gCullFront;
-rs_program_raster gCullNone;
-
-// Custom vertex shader compunents
-VertexShaderConstants *gVSConstants;
-FragentShaderConstants *gFSConstants;
-VertexShaderConstants3 *gVSConstPixel;
-FragentShaderConstants3 *gFSConstPixel;
-// Export these out to easily set the inputs to shader
-VertexShaderInputs *gVSInputs;
-// Custom shaders we use for lighting
-rs_program_vertex gProgVertexCustom;
-rs_program_fragment gProgFragmentCustom;
-rs_program_vertex gProgVertexPixelLight;
-rs_program_vertex gProgVertexPixelLightMove;
-rs_program_fragment gProgFragmentPixelLight;
-rs_program_vertex gProgVertexCube;
-rs_program_fragment gProgFragmentCube;
-rs_program_fragment gProgFragmentMultitex;
-
-float gDt = 0;
-
-void init() {
-}
-
-static const char *sampleText = "This is a sample of small text for performace";
-// Offsets for multiple layer of text
-static int textOffsets[] = { 0,  0, -5, -5, 5,  5, -8, -8, 8,  8};
-static float textColors[] = {1.0f, 1.0f, 1.0f, 1.0f,
-                             0.5f, 0.7f, 0.5f, 1.0f,
-                             0.7f, 0.5f, 0.5f, 1.0f,
-                             0.5f, 0.5f, 0.7f, 1.0f,
-                             0.5f, 0.6f, 0.7f, 1.0f,
-};
-
-static void displayFontSamples(int fillNum) {
-
-    rs_font fonts[5];
-    rsSetObject(&fonts[0], gFontSans);
-    rsSetObject(&fonts[1], gFontSerif);
-    rsSetObject(&fonts[2], gFontSerifBold);
-    rsSetObject(&fonts[3], gFontSerifBoldItalic);
-    rsSetObject(&fonts[4], gFontSans);
-
-    uint width = rsgGetWidth();
-    uint height = rsgGetHeight();
-    int left = 0, right = 0, top = 0, bottom = 0;
-    rsgMeasureText(sampleText, &left, &right, &top, &bottom);
-
-    int textHeight = top - bottom;
-    int textWidth = right - left;
-    int numVerticalLines = height / textHeight;
-    int yPos = top;
-
-    int xOffset = 0, yOffset = 0;
-    for(int fillI = 0; fillI < fillNum; fillI ++) {
-        rsgBindFont(fonts[fillI]);
-        xOffset = textOffsets[fillI * 2];
-        yOffset = textOffsets[fillI * 2 + 1];
-        float *colPtr = textColors + fillI * 4;
-        rsgFontColor(colPtr[0], colPtr[1], colPtr[2], colPtr[3]);
-        for (int h = 0; h < 4; h ++) {
-            yPos = top + yOffset;
-            for (int v = 0; v < numVerticalLines; v ++) {
-                rsgDrawText(sampleText, xOffset + textWidth * h, yPos);
-                yPos += textHeight;
-            }
-        }
-    }
-
-    for (int i = 0; i < 5; i ++) {
-        rsClearObject(&fonts[i]);
-    }
-}
-
-static void bindProgramVertexOrtho() {
-    // Default vertex sahder
-    rsgBindProgramVertex(gProgVertex);
-    // Setup the projection matrix
-    rs_matrix4x4 proj;
-    rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500);
-    rsgProgramVertexLoadProjectionMatrix(&proj);
-}
-
-static void displaySingletexFill(bool blend, int quadCount) {
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadIdentity(&matrix);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    // Fragment shader with texture
-    if (!blend) {
-        rsgBindProgramStore(gProgStoreBlendNone);
-    } else {
-        rsgBindProgramStore(gProgStoreBlendAlpha);
-    }
-    rsgBindProgramFragment(gProgFragmentTexture);
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
-    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
-
-    for (int i = 0; i < quadCount; i ++) {
-        float startX = 10 * i, startY = 10 * i;
-        float width = rsgGetWidth() - startX, height = rsgGetHeight() - startY;
-        rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                             startX, startY + height, 0, 0, 1,
-                             startX + width, startY + height, 0, 1, 1,
-                             startX + width, startY, 0, 1, 0);
-    }
-}
-
-static void displayBlendingSamples() {
-    int i;
-
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadIdentity(&matrix);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    rsgBindProgramFragment(gProgFragmentColor);
-
-    rsgBindProgramStore(gProgStoreBlendNone);
-    for (i = 0; i < 3; i ++) {
-        float iPlusOne = (float)(i + 1);
-        rsgProgramFragmentConstantColor(gProgFragmentColor,
-                                        0.1f*iPlusOne, 0.2f*iPlusOne, 0.3f*iPlusOne, 1);
-        float yPos = 150 * (float)i;
-        rsgDrawRect(0, yPos, 200, yPos + 200, 0);
-    }
-
-    rsgBindProgramStore(gProgStoreBlendAlpha);
-    for (i = 0; i < 3; i ++) {
-        float iPlusOne = (float)(i + 1);
-        rsgProgramFragmentConstantColor(gProgFragmentColor,
-                                        0.2f*iPlusOne, 0.3f*iPlusOne, 0.1f*iPlusOne, 0.5);
-        float yPos = 150 * (float)i;
-        rsgDrawRect(150, yPos, 350, yPos + 200, 0);
-    }
-
-    rsgBindProgramStore(gProgStoreBlendAdd);
-    for (i = 0; i < 3; i ++) {
-        float iPlusOne = (float)(i + 1);
-        rsgProgramFragmentConstantColor(gProgFragmentColor,
-                                        0.3f*iPlusOne, 0.1f*iPlusOne, 0.2f*iPlusOne, 0.5);
-        float yPos = 150 * (float)i;
-        rsgDrawRect(300, yPos, 500, yPos + 200, 0);
-    }
-
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("No Blending", 10, 50);
-    rsgDrawText("Alpha Blending", 160, 150);
-    rsgDrawText("Additive Blending", 320, 250);
-
-}
-
-static void displayMeshSamples(int meshNum) {
-
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadTranslate(&matrix, rsgGetWidth()/2, rsgGetHeight()/2, 0);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNone);
-    rsgBindProgramFragment(gProgFragmentTexture);
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
-    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
-
-    if (meshNum == 0) {
-        rsgDrawMesh(g10by10Mesh);
-    } else if (meshNum == 1) {
-        rsgDrawMesh(g100by100Mesh);
-    } else if (meshNum == 2) {
-        rsgDrawMesh(gWbyHMesh);
-    }
-}
-
-static void displayTextureSamplers() {
-
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadIdentity(&matrix);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNone);
-    rsgBindProgramFragment(gProgFragmentTexture);
-    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
-
-    // Linear clamp
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
-    float startX = 0, startY = 0;
-    float width = 300, height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.1,
-                         startX + width, startY + height, 0, 1.1, 1.1,
-                         startX + width, startY, 0, 1.1, 0);
-
-    // Linear Wrap
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearWrap);
-    startX = 0; startY = 300;
-    width = 300; height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.1,
-                         startX + width, startY + height, 0, 1.1, 1.1,
-                         startX + width, startY, 0, 1.1, 0);
-
-    // Nearest
-    rsgBindSampler(gProgFragmentTexture, 0, gNearestClamp);
-    startX = 300; startY = 0;
-    width = 300; height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.1,
-                         startX + width, startY + height, 0, 1.1, 1.1,
-                         startX + width, startY, 0, 1.1, 0);
-
-    rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
-    startX = 300; startY = 300;
-    width = 300; height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.5,
-                         startX + width, startY + height, 0, 1.5, 1.5,
-                         startX + width, startY, 0, 1.5, 0);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("Filtering: linear clamp", 10, 290);
-    rsgDrawText("Filtering: linear wrap", 10, 590);
-    rsgDrawText("Filtering: nearest clamp", 310, 290);
-    rsgDrawText("Filtering: miplinear wrap", 310, 590);
-}
-
-static float gTorusRotation = 0;
-static void updateModelMatrix(rs_matrix4x4 *matrix, void *buffer) {
-    if (buffer == 0) {
-        rsgProgramVertexLoadModelMatrix(matrix);
-    } else {
-        rsAllocationMarkDirty(rsGetAllocation(buffer));
-    }
-}
-
-static void drawToruses(int numMeshes, rs_matrix4x4 *matrix, void *buffer) {
-
-    if (numMeshes == 1) {
-        rsMatrixLoadTranslate(matrix, 0.0f, 0.0f, -7.5f);
-        rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
-        updateModelMatrix(matrix, buffer);
-        rsgDrawMesh(gTorusMesh);
-        return;
-    }
-
-    if (numMeshes == 2) {
-        rsMatrixLoadTranslate(matrix, -1.6f, 0.0f, -7.5f);
-        rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
-        updateModelMatrix(matrix, buffer);
-        rsgDrawMesh(gTorusMesh);
-
-        rsMatrixLoadTranslate(matrix, 1.6f, 0.0f, -7.5f);
-        rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
-        updateModelMatrix(matrix, buffer);
-        rsgDrawMesh(gTorusMesh);
-        return;
-    }
-
-    float startX = -5.0f;
-    float startY = -1.5f;
-    float startZ = -15.0f;
-    float dist = 3.2f;
-
-    for (int h = 0; h < 4; h ++) {
-        for (int v = 0; v < 2; v ++) {
-            // Position our model on the screen
-            rsMatrixLoadTranslate(matrix, startX + dist * h, startY + dist * v, startZ);
-            rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
-            updateModelMatrix(matrix, buffer);
-            rsgDrawMesh(gTorusMesh);
-        }
-    }
-}
-
-
-// Quick hack to get some geometry numbers
-static void displaySimpleGeoSamples(bool useTexture, int numMeshes) {
-    rsgBindProgramVertex(gProgVertex);
-    rsgBindProgramRaster(gCullBack);
-    // Setup the projection matrix with 30 degree field of view
-    rs_matrix4x4 proj;
-    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
-    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
-    rsgProgramVertexLoadProjectionMatrix(&proj);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNoneDepth);
-    if (useTexture) {
-        rsgBindProgramFragment(gProgFragmentTexture);
-    } else {
-        rsgBindProgramFragment(gProgFragmentColor);
-        rsgProgramFragmentConstantColor(gProgFragmentColor, 0.1, 0.7, 0.1, 1);
-    }
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
-    rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
-
-    // Apply a rotation to our mesh
-    gTorusRotation += 50.0f * gDt;
-    if (gTorusRotation > 360.0f) {
-        gTorusRotation -= 360.0f;
-    }
-
-    rs_matrix4x4 matrix;
-    drawToruses(numMeshes, &matrix, 0);
-}
-
-float gLight0Rotation = 0;
-float gLight1Rotation = 0;
-
-static void setupCustomShaderLights() {
-    float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f};
-    float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f};
-    float4 light0DiffCol = {0.9f, 0.7f, 0.7f, 1.0f};
-    float4 light0SpecCol = {0.9f, 0.6f, 0.6f, 1.0f};
-    float4 light1DiffCol = {0.5f, 0.5f, 0.9f, 1.0f};
-    float4 light1SpecCol = {0.5f, 0.5f, 0.9f, 1.0f};
-
-    gLight0Rotation += 50.0f * gDt;
-    if (gLight0Rotation > 360.0f) {
-        gLight0Rotation -= 360.0f;
-    }
-    gLight1Rotation -= 50.0f * gDt;
-    if (gLight1Rotation > 360.0f) {
-        gLight1Rotation -= 360.0f;
-    }
-
-    rs_matrix4x4 l0Mat;
-    rsMatrixLoadRotate(&l0Mat, gLight0Rotation, 1.0f, 0.0f, 0.0f);
-    light0Pos = rsMatrixMultiply(&l0Mat, light0Pos);
-    rs_matrix4x4 l1Mat;
-    rsMatrixLoadRotate(&l1Mat, gLight1Rotation, 0.0f, 0.0f, 1.0f);
-    light1Pos = rsMatrixMultiply(&l1Mat, light1Pos);
-
-    // Set light 0 properties
-    gVSConstants->light0_Posision = light0Pos;
-    gVSConstants->light0_Diffuse = 1.0f;
-    gVSConstants->light0_Specular = 0.5f;
-    gVSConstants->light0_CosinePower = 10.0f;
-    // Set light 1 properties
-    gVSConstants->light1_Posision = light1Pos;
-    gVSConstants->light1_Diffuse = 1.0f;
-    gVSConstants->light1_Specular = 0.7f;
-    gVSConstants->light1_CosinePower = 25.0f;
-    rsAllocationMarkDirty(rsGetAllocation(gVSConstants));
-
-    // Update fragment shader constants
-    // Set light 0 colors
-    gFSConstants->light0_DiffuseColor = light0DiffCol;
-    gFSConstants->light0_SpecularColor = light0SpecCol;
-    // Set light 1 colors
-    gFSConstants->light1_DiffuseColor = light1DiffCol;
-    gFSConstants->light1_SpecularColor = light1SpecCol;
-    rsAllocationMarkDirty(rsGetAllocation(gFSConstants));
-
-    // Set light 0 properties for per pixel lighting
-    gFSConstPixel->light0_Posision = light0Pos;
-    gFSConstPixel->light0_Diffuse = 1.0f;
-    gFSConstPixel->light0_Specular = 0.5f;
-    gFSConstPixel->light0_CosinePower = 10.0f;
-    gFSConstPixel->light0_DiffuseColor = light0DiffCol;
-    gFSConstPixel->light0_SpecularColor = light0SpecCol;
-    // Set light 1 properties
-    gFSConstPixel->light1_Posision = light1Pos;
-    gFSConstPixel->light1_Diffuse = 1.0f;
-    gFSConstPixel->light1_Specular = 0.7f;
-    gFSConstPixel->light1_CosinePower = 25.0f;
-    gFSConstPixel->light1_DiffuseColor = light1DiffCol;
-    gFSConstPixel->light1_SpecularColor = light1SpecCol;
-    rsAllocationMarkDirty(rsGetAllocation(gFSConstPixel));
-}
-
-static void displayCustomShaderSamples(int numMeshes) {
-
-    // Update vertex shader constants
-    // Load model matrix
-    // Apply a rotation to our mesh
-    gTorusRotation += 50.0f * gDt;
-    if (gTorusRotation > 360.0f) {
-        gTorusRotation -= 360.0f;
-    }
-
-    // Setup the projection matrix
-    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
-    rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
-    setupCustomShaderLights();
-
-    rsgBindProgramVertex(gProgVertexCustom);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNoneDepth);
-    rsgBindProgramFragment(gProgFragmentCustom);
-    rsgBindSampler(gProgFragmentCustom, 0, gLinearClamp);
-    rsgBindTexture(gProgFragmentCustom, 0, gTexTorus);
-
-    // Use back face culling
-    rsgBindProgramRaster(gCullBack);
-
-    drawToruses(numMeshes, &gVSConstants->model, gVSConstants);
-}
-
-static void displayPixelLightSamples(int numMeshes, bool heavyVertex) {
-
-    // Update vertex shader constants
-    // Load model matrix
-    // Apply a rotation to our mesh
-    gTorusRotation += 30.0f * gDt;
-    if (gTorusRotation > 360.0f) {
-        gTorusRotation -= 360.0f;
-    }
-
-    gVSConstPixel->time = rsUptimeMillis()*0.005;
-
-    // Setup the projection matrix
-    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
-    rsMatrixLoadPerspective(&gVSConstPixel->proj, 30.0f, aspect, 0.1f, 100.0f);
-    setupCustomShaderLights();
-
-    if (heavyVertex) {
-        rsgBindProgramVertex(gProgVertexPixelLightMove);
-    } else {
-        rsgBindProgramVertex(gProgVertexPixelLight);
-    }
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNoneDepth);
-    rsgBindProgramFragment(gProgFragmentPixelLight);
-    rsgBindSampler(gProgFragmentPixelLight, 0, gLinearClamp);
-    rsgBindTexture(gProgFragmentPixelLight, 0, gTexTorus);
-
-    // Use back face culling
-    rsgBindProgramRaster(gCullBack);
-
-    drawToruses(numMeshes, &gVSConstPixel->model, gVSConstPixel);
-}
-
-static void displayMultitextureSample(bool blend, int quadCount) {
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadIdentity(&matrix);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    // Fragment shader with texture
-    if (!blend) {
-        rsgBindProgramStore(gProgStoreBlendNone);
-    } else {
-        rsgBindProgramStore(gProgStoreBlendAlpha);
-    }
-    rsgBindProgramFragment(gProgFragmentMultitex);
-    rsgBindSampler(gProgFragmentMultitex, 0, gLinearClamp);
-    rsgBindSampler(gProgFragmentMultitex, 1, gLinearWrap);
-    rsgBindSampler(gProgFragmentMultitex, 2, gLinearClamp);
-    rsgBindTexture(gProgFragmentMultitex, 0, gTexChecker);
-    rsgBindTexture(gProgFragmentMultitex, 1, gTexTorus);
-    rsgBindTexture(gProgFragmentMultitex, 2, gTexTransparent);
-
-    for (int i = 0; i < quadCount; i ++) {
-        float startX = 10 * i, startY = 10 * i;
-        float width = rsgGetWidth() - startX, height = rsgGetHeight() - startY;
-        rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                             startX, startY + height, 0, 0, 1,
-                             startX + width, startY + height, 0, 1, 1,
-                             startX + width, startY, 0, 1, 0);
-    }
-}
-
-static float gAnisoTime = 0.0f;
-static uint anisoMode = 0;
-static void displayAnisoSample() {
-
-    gAnisoTime += gDt;
-
-    rsgBindProgramVertex(gProgVertex);
-    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
-    rs_matrix4x4 proj;
-    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
-    rsgProgramVertexLoadProjectionMatrix(&proj);
-
-    rs_matrix4x4 matrix;
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNone);
-    rsgBindProgramFragment(gProgFragmentTexture);
-    rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, -10.0f);
-    rsMatrixRotate(&matrix, -80, 1.0f, 0.0f, 0.0f);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    rsgBindProgramRaster(gCullNone);
-
-    rsgBindTexture(gProgFragmentTexture, 0, gTexChecker);
-
-    if (gAnisoTime >= 5.0f) {
-        gAnisoTime = 0.0f;
-        anisoMode ++;
-        anisoMode = anisoMode % 3;
-    }
-
-    if (anisoMode == 0) {
-        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso8);
-    } else if (anisoMode == 1) {
-        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso15);
-    } else {
-        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
-    }
-
-    float startX = -15;
-    float startY = -15;
-    float width = 30;
-    float height = 30;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 10,
-                         startX + width, startY + height, 0, 10, 10,
-                         startX + width, startY, 0, 10, 0);
-
-    rsgBindProgramRaster(gCullBack);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    if (anisoMode == 0) {
-        rsgDrawText("Anisotropic filtering 8", 10, 40);
-    } else if (anisoMode == 1) {
-        rsgDrawText("Anisotropic filtering 15", 10, 40);
-    } else {
-        rsgDrawText("Miplinear filtering", 10, 40);
-    }
-}
-
-static bool checkInit() {
-
-    static int countdown = 5;
-
-    if (countdown == 0) {
-        gDt = 0;
-        countdown --;
-    }
-    // Perform all the uploads so we only measure rendered time
-    if(countdown > 1) {
-        displayFontSamples(5);
-        displaySingletexFill(true, 3);
-        displayBlendingSamples();
-        displayMeshSamples(0);
-        displayMeshSamples(1);
-        displayMeshSamples(2);
-        displayTextureSamplers();
-        displayMultitextureSample(true, 5);
-        displayAnisoSample();
-        displayPixelLightSamples(1, false);
-        displayPixelLightSamples(1, true);
-        countdown --;
-        rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
-
-        // Now use text metrics to center the text
-        uint width = rsgGetWidth();
-        uint height = rsgGetHeight();
-        int left = 0, right = 0, top = 0, bottom = 0;
-
-        rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
-        rsgBindFont(gFontSerifBoldItalic);
-
-        const char* text = "Initializing";
-        rsgMeasureText(text, &left, &right, &top, &bottom);
-        int centeredPosX = width / 2 - (right - left) / 2;
-        int centeredPosY = height / 2 - (top - bottom) / 2;
-        rsgDrawText(text, centeredPosX, centeredPosY);
-
-        return false;
-    }
-
-    return true;
-}
-
-static int frameCount = 0;
-static int totalFramesRendered = 0;
-static int benchMode = 0;
-
-#define testTime 5.0f
-static float curTestTime = testTime;
-
-static const char *testNames[] = {
-    "Finished text fill 1",
-    "Finished text fill 2",
-    "Finished text fill 3",
-    "Finished text fill 4",
-    "Finished text fill 5",
-    "Finished 25.6k geo flat color",
-    "Finished 51.2k geo flat color",
-    "Finished 204.8k geo raster load flat color",
-    "Finished 25.6k geo texture",
-    "Finished 51.2k geo texture",
-    "Finished 204.8k geo raster load texture",
-    "Finished full screen mesh 10 by 10",
-    "Finished full screen mesh 100 by 100",
-    "Finished full screen mesh W / 4 by H / 4",
-    "Finished 25.6k geo heavy vertex",
-    "Finished 51.2k geo heavy vertex",
-    "Finished 204.8k geo raster load heavy vertex",
-    "Finished singletexture 5x fill",
-    "Finished 3tex multitexture 5x fill",
-    "Finished blend singletexture 5x fill",
-    "Finished blend 3tex multitexture 5x fill",
-    "Finished 25.6k geo heavy fragment",
-    "Finished 51.2k geo heavy fragment",
-    "Finished 204.8k geo raster load heavy fragment",
-    "Finished 25.6k geo heavy fragment, heavy vertex",
-    "Finished 51.2k geo heavy fragment, heavy vertex",
-    "Finished 204.8k geo raster load heavy fragment, heavy vertex",
-};
-
-int root(int launchID) {
-
-    gDt = rsGetDt();
-
-    rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
-    rsgClearDepth(1.0f);
-
-    if(!checkInit()) {
-        return 1;
-    }
-
-    curTestTime -= gDt;
-    if(curTestTime < 0.0f) {
-        float fps = (float)(frameCount) / (testTime - curTestTime);
-        rsDebug(testNames[benchMode], fps);
-        benchMode ++;
-        curTestTime = testTime;
-        totalFramesRendered += frameCount;
-        frameCount = 0;
-        gTorusRotation = 0;
-
-        if (benchMode > gMaxModes) {
-            benchMode = 0;
-        }
-    }
-
-    switch (benchMode) {
-    case 0:
-        displayFontSamples(1);
-        break;
-    case 1:
-        displayFontSamples(2);
-        break;
-    case 2:
-        displayFontSamples(3);
-        break;
-    case 3:
-        displayFontSamples(4);
-        break;
-    case 4:
-        displayFontSamples(5);
-        break;
-    case 5:
-        displaySimpleGeoSamples(false, 1);
-        break;
-    case 6:
-        displaySimpleGeoSamples(false, 2);
-        break;
-    case 7:
-        displaySimpleGeoSamples(false, 8);
-        break;
-    case 8:
-        displaySimpleGeoSamples(true, 1);
-        break;
-    case 9:
-        displaySimpleGeoSamples(true, 2);
-        break;
-    case 10:
-        displaySimpleGeoSamples(true, 8);
-        break;
-    case 11:
-        displayMeshSamples(0);
-        break;
-    case 12:
-        displayMeshSamples(1);
-        break;
-    case 13:
-        displayMeshSamples(2);
-        break;
-    case 14:
-        displayCustomShaderSamples(1);
-        break;
-    case 15:
-        displayCustomShaderSamples(2);
-        break;
-    case 16:
-        displayCustomShaderSamples(8);
-        break;
-    case 17:
-        displaySingletexFill(false, 5);
-        break;
-    case 18:
-        displayMultitextureSample(false, 5);
-        break;
-    case 19:
-        displaySingletexFill(true, 5);
-        break;
-    case 20:
-        displayMultitextureSample(true, 5);
-        break;
-    case 21:
-        displayPixelLightSamples(1, false);
-        break;
-    case 22:
-        displayPixelLightSamples(2, false);
-        break;
-    case 23:
-        displayPixelLightSamples(8, false);
-        break;
-    case 24:
-        displayPixelLightSamples(1, true);
-        break;
-    case 25:
-        displayPixelLightSamples(2, true);
-        break;
-    case 26:
-        displayPixelLightSamples(8, true);
-        break;
-
-    }
-
-    frameCount ++;
-
-    return 1;
-}
diff --git a/java/Samples/src/com/android/samples/rslist.rs b/java/Samples/src/com/android/samples/rslist.rs
deleted file mode 100644
index b79f4fc..0000000
--- a/java/Samples/src/com/android/samples/rslist.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.samples)
-
-#include "rs_graphics.rsh"
-
-float gDY;
-
-rs_font gItalic;
-
-typedef struct ListAllocs_s {
-    rs_allocation text;
-} ListAllocs;
-
-ListAllocs *gList;
-
-void init() {
-    gDY = 0.0f;
-}
-
-int textPos = 0;
-
-int root(int launchID) {
-
-    rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-    rsgClearDepth(1.0f);
-
-    textPos -= (int)gDY*2;
-    gDY *= 0.95;
-
-    rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f);
-    rsgBindFont(gItalic);
-
-    rs_allocation listAlloc;
-    rsSetObject(&listAlloc, rsGetAllocation(gList));
-    int allocSize = rsAllocationGetDimX(listAlloc);
-
-    int width = rsgGetWidth();
-    int height = rsgGetHeight();
-
-    int itemHeight = 80;
-    int currentYPos = itemHeight + textPos;
-
-    for (int i = 0; i < allocSize; i ++) {
-        if (currentYPos - itemHeight > height) {
-            break;
-        }
-
-        if (currentYPos > 0) {
-            rsgDrawRect(0, currentYPos - 1, width, currentYPos, 0);
-            rsgDrawText(gList[i].text, 30, currentYPos - 32);
-        }
-        currentYPos += itemHeight;
-    }
-
-    return 10;
-}
diff --git a/java/Samples/src/com/android/samples/rsrenderstates.rs b/java/Samples/src/com/android/samples/rsrenderstates.rs
deleted file mode 100644
index 42be4d8..0000000
--- a/java/Samples/src/com/android/samples/rsrenderstates.rs
+++ /dev/null
@@ -1,680 +0,0 @@
-// 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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.samples)
-
-#include "rs_graphics.rsh"
-#include "shader_def.rsh"
-
-const int gMaxModes = 11;
-
-rs_program_vertex gProgVertex;
-rs_program_fragment gProgFragmentColor;
-rs_program_fragment gProgFragmentTexture;
-
-rs_program_store gProgStoreBlendNoneDepth;
-rs_program_store gProgStoreBlendNone;
-rs_program_store gProgStoreBlendAlpha;
-rs_program_store gProgStoreBlendAdd;
-
-rs_allocation gTexOpaque;
-rs_allocation gTexTorus;
-rs_allocation gTexTransparent;
-rs_allocation gTexChecker;
-rs_allocation gTexCube;
-
-rs_mesh gMbyNMesh;
-rs_mesh gTorusMesh;
-
-rs_font gFontSans;
-rs_font gFontSerif;
-rs_font gFontSerifBold;
-rs_font gFontSerifItalic;
-rs_font gFontSerifBoldItalic;
-rs_font gFontMono;
-rs_allocation gTextAlloc;
-
-int gDisplayMode;
-
-rs_sampler gLinearClamp;
-rs_sampler gLinearWrap;
-rs_sampler gMipLinearWrap;
-rs_sampler gMipLinearAniso8;
-rs_sampler gMipLinearAniso15;
-rs_sampler gNearestClamp;
-
-rs_program_raster gCullBack;
-rs_program_raster gCullFront;
-rs_program_raster gCullNone;
-
-// Custom vertex shader compunents
-VertexShaderConstants *gVSConstants;
-VertexShaderConstants2 *gVSConstants2;
-FragentShaderConstants *gFSConstants;
-FragentShaderConstants2 *gFSConstants2;
-// Export these out to easily set the inputs to shader
-VertexShaderInputs *gVSInputs;
-// Custom shaders we use for lighting
-rs_program_vertex gProgVertexCustom;
-rs_program_fragment gProgFragmentCustom;
-rs_program_vertex gProgVertexCustom2;
-rs_program_fragment gProgFragmentCustom2;
-rs_program_vertex gProgVertexCube;
-rs_program_fragment gProgFragmentCube;
-rs_program_fragment gProgFragmentMultitex;
-
-float gDt = 0;
-
-void init() {
-}
-
-static void displayFontSamples() {
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    int yPos = 100;
-    rsgBindFont(gFontSans);
-    rsgDrawText("Sans font sample", 30, yPos);
-    yPos += 30;
-    rsgFontColor(0.5f, 0.9f, 0.5f, 1.0f);
-    rsgBindFont(gFontSerif);
-    rsgDrawText("Serif font sample", 30, yPos);
-    yPos += 30;
-    rsgFontColor(0.7f, 0.7f, 0.7f, 1.0f);
-    rsgBindFont(gFontSerifBold);
-    rsgDrawText("Serif Bold font sample", 30, yPos);
-    yPos += 30;
-    rsgFontColor(0.5f, 0.5f, 0.9f, 1.0f);
-    rsgBindFont(gFontSerifItalic);
-    rsgDrawText("Serif Italic font sample", 30, yPos);
-    yPos += 30;
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontSerifBoldItalic);
-    rsgDrawText("Serif Bold Italic font sample", 30, yPos);
-    yPos += 30;
-    rsgBindFont(gFontMono);
-    rsgDrawText("Monospace font sample", 30, yPos);
-    yPos += 50;
-
-    // Now use text metrics to center the text
-    uint width = rsgGetWidth();
-    uint height = rsgGetHeight();
-    int left = 0, right = 0, top = 0, bottom = 0;
-
-    rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
-    rsgBindFont(gFontSerifBoldItalic);
-
-    rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom);
-    int centeredPos = width / 2 - (right - left) / 2;
-    rsgDrawText(gTextAlloc, centeredPos, yPos);
-    yPos += 30;
-
-    const char* text = "Centered Text Sample";
-    rsgMeasureText(text, &left, &right, &top, &bottom);
-    centeredPos = width / 2 - (right - left) / 2;
-    rsgDrawText(text, centeredPos, yPos);
-    yPos += 30;
-
-    rsgBindFont(gFontSans);
-    text = "More Centered Text Samples";
-    rsgMeasureText(text, &left, &right, &top, &bottom);
-    centeredPos = width / 2 - (right - left) / 2;
-    rsgDrawText(text, centeredPos, yPos);
-    yPos += 30;
-
-    // Now draw bottom and top right aligned text
-    text = "Top-right aligned text";
-    rsgMeasureText(text, &left, &right, &top, &bottom);
-    rsgDrawText(text, width - right, top);
-
-    text = "Top-left";
-    rsgMeasureText(text, &left, &right, &top, &bottom);
-    rsgDrawText(text, -left, top);
-
-    text = "Bottom-right aligned text";
-    rsgMeasureText(text, &left, &right, &top, &bottom);
-    rsgDrawText(text, width - right, height + bottom);
-
-}
-
-static void bindProgramVertexOrtho() {
-    // Default vertex sahder
-    rsgBindProgramVertex(gProgVertex);
-    // Setup the projectioni matrix
-    rs_matrix4x4 proj;
-    rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500);
-    rsgProgramVertexLoadProjectionMatrix(&proj);
-}
-
-static void displayShaderSamples() {
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadIdentity(&matrix);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNone);
-    rsgBindProgramFragment(gProgFragmentTexture);
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
-    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
-
-    float startX = 0, startY = 0;
-    float width = 256, height = 256;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1,
-                         startX + width, startY + height, 0, 1, 1,
-                         startX + width, startY, 0, 1, 0);
-
-    startX = 200; startY = 0;
-    width = 128; height = 128;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1,
-                         startX + width, startY + height, 0, 1, 1,
-                         startX + width, startY, 0, 1, 0);
-
-    rsgBindProgramStore(gProgStoreBlendAlpha);
-    rsgBindTexture(gProgFragmentTexture, 0, gTexTransparent);
-    startX = 0; startY = 200;
-    width = 128; height = 128;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1,
-                         startX + width, startY + height, 0, 1, 1,
-                         startX + width, startY, 0, 1, 0);
-
-    // Fragment program with simple color
-    rsgBindProgramFragment(gProgFragmentColor);
-    rsgProgramFragmentConstantColor(gProgFragmentColor, 0.9, 0.3, 0.3, 1);
-    rsgDrawRect(200, 300, 350, 450, 0);
-    rsgProgramFragmentConstantColor(gProgFragmentColor, 0.3, 0.9, 0.3, 1);
-    rsgDrawRect(50, 400, 400, 600, 0);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("Texture shader", 10, 50);
-    rsgDrawText("Alpha-blended texture shader", 10, 280);
-    rsgDrawText("Flat color shader", 100, 450);
-}
-
-static void displayBlendingSamples() {
-    int i;
-
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadIdentity(&matrix);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    rsgBindProgramFragment(gProgFragmentColor);
-
-    rsgBindProgramStore(gProgStoreBlendNone);
-    for (i = 0; i < 3; i ++) {
-        float iPlusOne = (float)(i + 1);
-        rsgProgramFragmentConstantColor(gProgFragmentColor,
-                                        0.1f*iPlusOne, 0.2f*iPlusOne, 0.3f*iPlusOne, 1);
-        float yPos = 150 * (float)i;
-        rsgDrawRect(0, yPos, 200, yPos + 200, 0);
-    }
-
-    rsgBindProgramStore(gProgStoreBlendAlpha);
-    for (i = 0; i < 3; i ++) {
-        float iPlusOne = (float)(i + 1);
-        rsgProgramFragmentConstantColor(gProgFragmentColor,
-                                        0.2f*iPlusOne, 0.3f*iPlusOne, 0.1f*iPlusOne, 0.5);
-        float yPos = 150 * (float)i;
-        rsgDrawRect(150, yPos, 350, yPos + 200, 0);
-    }
-
-    rsgBindProgramStore(gProgStoreBlendAdd);
-    for (i = 0; i < 3; i ++) {
-        float iPlusOne = (float)(i + 1);
-        rsgProgramFragmentConstantColor(gProgFragmentColor,
-                                        0.3f*iPlusOne, 0.1f*iPlusOne, 0.2f*iPlusOne, 0.5);
-        float yPos = 150 * (float)i;
-        rsgDrawRect(300, yPos, 500, yPos + 200, 0);
-    }
-
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("No Blending", 10, 50);
-    rsgDrawText("Alpha Blending", 160, 150);
-    rsgDrawText("Additive Blending", 320, 250);
-
-}
-
-static void displayMeshSamples() {
-
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadTranslate(&matrix, 128, 128, 0);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNone);
-    rsgBindProgramFragment(gProgFragmentTexture);
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
-    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
-
-    rsgDrawMesh(gMbyNMesh);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("User gen 10 by 10 grid mesh", 10, 250);
-}
-
-static void displayTextureSamplers() {
-
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadIdentity(&matrix);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNone);
-    rsgBindProgramFragment(gProgFragmentTexture);
-    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
-
-    // Linear clamp
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
-    float startX = 0, startY = 0;
-    float width = 300, height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.1,
-                         startX + width, startY + height, 0, 1.1, 1.1,
-                         startX + width, startY, 0, 1.1, 0);
-
-    // Linear Wrap
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearWrap);
-    startX = 0; startY = 300;
-    width = 300; height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.1,
-                         startX + width, startY + height, 0, 1.1, 1.1,
-                         startX + width, startY, 0, 1.1, 0);
-
-    // Nearest
-    rsgBindSampler(gProgFragmentTexture, 0, gNearestClamp);
-    startX = 300; startY = 0;
-    width = 300; height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.1,
-                         startX + width, startY + height, 0, 1.1, 1.1,
-                         startX + width, startY, 0, 1.1, 0);
-
-    rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
-    startX = 300; startY = 300;
-    width = 300; height = 300;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1.5,
-                         startX + width, startY + height, 0, 1.5, 1.5,
-                         startX + width, startY, 0, 1.5, 0);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("Filtering: linear clamp", 10, 290);
-    rsgDrawText("Filtering: linear wrap", 10, 590);
-    rsgDrawText("Filtering: nearest clamp", 310, 290);
-    rsgDrawText("Filtering: miplinear wrap", 310, 590);
-}
-
-static float gTorusRotation = 0;
-
-static void displayCullingSamples() {
-    rsgBindProgramVertex(gProgVertex);
-    // Setup the projectioni matrix with 60 degree field of view
-    rs_matrix4x4 proj;
-    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
-    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
-    rsgProgramVertexLoadProjectionMatrix(&proj);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNoneDepth);
-    rsgBindProgramFragment(gProgFragmentTexture);
-    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
-    rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
-
-    // Aplly a rotation to our mesh
-    gTorusRotation += 50.0f * gDt;
-    if (gTorusRotation > 360.0f) {
-        gTorusRotation -= 360.0f;
-    }
-
-    rs_matrix4x4 matrix;
-    // Position our model on the screen
-    rsMatrixLoadTranslate(&matrix, -2.0f, 0.0f, -10.0f);
-    rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-    // Use front face culling
-    rsgBindProgramRaster(gCullFront);
-    rsgDrawMesh(gTorusMesh);
-
-    rsMatrixLoadTranslate(&matrix, 2.0f, 0.0f, -10.0f);
-    rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-    // Use back face culling
-    rsgBindProgramRaster(gCullBack);
-    rsgDrawMesh(gTorusMesh);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("Displaying mesh front/back face culling", 10, rsgGetHeight() - 10);
-}
-
-static float gLight0Rotation = 0;
-static float gLight1Rotation = 0;
-
-static void setupCustomShaderLights() {
-    float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f};
-    float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f};
-    float4 light0DiffCol = {0.9f, 0.7f, 0.7f, 1.0f};
-    float4 light0SpecCol = {0.9f, 0.6f, 0.6f, 1.0f};
-    float4 light1DiffCol = {0.5f, 0.5f, 0.9f, 1.0f};
-    float4 light1SpecCol = {0.5f, 0.5f, 0.9f, 1.0f};
-
-    gLight0Rotation += 50.0f * gDt;
-    if (gLight0Rotation > 360.0f) {
-        gLight0Rotation -= 360.0f;
-    }
-    gLight1Rotation -= 50.0f * gDt;
-    if (gLight1Rotation > 360.0f) {
-        gLight1Rotation -= 360.0f;
-    }
-
-    rs_matrix4x4 l0Mat;
-    rsMatrixLoadRotate(&l0Mat, gLight0Rotation, 1.0f, 0.0f, 0.0f);
-    light0Pos = rsMatrixMultiply(&l0Mat, light0Pos);
-    rs_matrix4x4 l1Mat;
-    rsMatrixLoadRotate(&l1Mat, gLight1Rotation, 0.0f, 0.0f, 1.0f);
-    light1Pos = rsMatrixMultiply(&l1Mat, light1Pos);
-
-    // Set light 0 properties
-    gVSConstants->light0_Posision = light0Pos;
-    gVSConstants->light0_Diffuse = 1.0f;
-    gVSConstants->light0_Specular = 0.5f;
-    gVSConstants->light0_CosinePower = 10.0f;
-    // Set light 1 properties
-    gVSConstants->light1_Posision = light1Pos;
-    gVSConstants->light1_Diffuse = 1.0f;
-    gVSConstants->light1_Specular = 0.7f;
-    gVSConstants->light1_CosinePower = 25.0f;
-    rsgAllocationSyncAll(rsGetAllocation(gVSConstants));
-
-    gVSConstants2->light_Posision[0] = light0Pos;
-    gVSConstants2->light_Diffuse[0] = 1.0f;
-    gVSConstants2->light_Specular[0] = 0.5f;
-    gVSConstants2->light_CosinePower[0] = 10.0f;
-    gVSConstants2->light_Posision[1] = light1Pos;
-    gVSConstants2->light_Diffuse[1] = 1.0f;
-    gVSConstants2->light_Specular[1] = 0.7f;
-    gVSConstants2->light_CosinePower[1] = 25.0f;
-    rsgAllocationSyncAll(rsGetAllocation(gVSConstants2));
-
-    // Update fragmetn shader constants
-    // Set light 0 colors
-    gFSConstants->light0_DiffuseColor = light0DiffCol;
-    gFSConstants->light0_SpecularColor = light0SpecCol;
-    // Set light 1 colors
-    gFSConstants->light1_DiffuseColor = light1DiffCol;
-    gFSConstants->light1_SpecularColor = light1SpecCol;
-    rsgAllocationSyncAll(rsGetAllocation(gFSConstants));
-
-    gFSConstants2->light_DiffuseColor[0] = light0DiffCol;
-    gFSConstants2->light_SpecularColor[0] = light0SpecCol;
-    // Set light 1 colors
-    gFSConstants2->light_DiffuseColor[1] = light1DiffCol;
-    gFSConstants2->light_SpecularColor[1] = light1SpecCol;
-    rsgAllocationSyncAll(rsGetAllocation(gFSConstants2));
-}
-
-static void displayCustomShaderSamples() {
-
-    // Update vertex shader constants
-    // Load model matrix
-    // Aplly a rotation to our mesh
-    gTorusRotation += 50.0f * gDt;
-    if (gTorusRotation > 360.0f) {
-        gTorusRotation -= 360.0f;
-    }
-
-    // Position our model on the screen
-    rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
-    rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
-    rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
-    // Setup the projectioni matrix
-    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
-    rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
-    setupCustomShaderLights();
-
-    rsgBindProgramVertex(gProgVertexCustom);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNoneDepth);
-    rsgBindProgramFragment(gProgFragmentCustom);
-    rsgBindSampler(gProgFragmentCustom, 0, gLinearClamp);
-    rsgBindTexture(gProgFragmentCustom, 0, gTexTorus);
-
-    // Use back face culling
-    rsgBindProgramRaster(gCullBack);
-    rsgDrawMesh(gTorusMesh);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("Custom shader sample", 10, rsgGetHeight() - 10);
-}
-
-static void displayCustomShaderSamples2() {
-
-    // Update vertex shader constants
-    // Load model matrix
-    // Aplly a rotation to our mesh
-    gTorusRotation += 50.0f * gDt;
-    if (gTorusRotation > 360.0f) {
-        gTorusRotation -= 360.0f;
-    }
-
-    // Position our model on the screen
-    rsMatrixLoadTranslate(&gVSConstants2->model[1], 0.0f, 0.0f, -10.0f);
-    rsMatrixLoadIdentity(&gVSConstants2->model[0]);
-    rsMatrixRotate(&gVSConstants2->model[0], gTorusRotation, 1.0f, 0.0f, 0.0f);
-    rsMatrixRotate(&gVSConstants2->model[0], gTorusRotation, 0.0f, 0.0f, 1.0f);
-    // Setup the projectioni matrix
-    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
-    rsMatrixLoadPerspective(&gVSConstants2->proj, 30.0f, aspect, 0.1f, 100.0f);
-    setupCustomShaderLights();
-
-    rsgBindProgramVertex(gProgVertexCustom2);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNoneDepth);
-    rsgBindProgramFragment(gProgFragmentCustom2);
-    rsgBindSampler(gProgFragmentCustom2, 0, gLinearClamp);
-    rsgBindTexture(gProgFragmentCustom2, 0, gTexTorus);
-
-    // Use back face culling
-    rsgBindProgramRaster(gCullBack);
-    rsgDrawMesh(gTorusMesh);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("Custom shader sample with array uniforms", 10, rsgGetHeight() - 10);
-}
-
-static void displayCubemapShaderSample() {
-    // Update vertex shader constants
-    // Load model matrix
-    // Aplly a rotation to our mesh
-    gTorusRotation += 50.0f * gDt;
-    if (gTorusRotation > 360.0f) {
-        gTorusRotation -= 360.0f;
-    }
-
-    // Position our model on the screen
-    // Position our model on the screen
-    rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
-    rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
-    rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
-    // Setup the projectioni matrix
-    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
-    rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
-    rsAllocationMarkDirty(rsGetAllocation(gFSConstants));
-
-    rsgBindProgramVertex(gProgVertexCube);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNoneDepth);
-    rsgBindProgramFragment(gProgFragmentCube);
-    rsgBindSampler(gProgFragmentCube, 0, gLinearClamp);
-    rsgBindTexture(gProgFragmentCube, 0, gTexCube);
-
-    // Use back face culling
-    rsgBindProgramRaster(gCullBack);
-    rsgDrawMesh(gTorusMesh);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("Cubemap shader sample", 10, rsgGetHeight() - 10);
-}
-
-static void displayMultitextureSample() {
-    bindProgramVertexOrtho();
-    rs_matrix4x4 matrix;
-    rsMatrixLoadIdentity(&matrix);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNone);
-    rsgBindProgramFragment(gProgFragmentMultitex);
-    rsgBindSampler(gProgFragmentMultitex, 0, gLinearClamp);
-    rsgBindSampler(gProgFragmentMultitex, 1, gLinearWrap);
-    rsgBindSampler(gProgFragmentMultitex, 2, gLinearClamp);
-    rsgBindTexture(gProgFragmentMultitex, 0, gTexChecker);
-    rsgBindTexture(gProgFragmentMultitex, 1, gTexTorus);
-    rsgBindTexture(gProgFragmentMultitex, 2, gTexTransparent);
-
-    float startX = 0, startY = 0;
-    float width = 256, height = 256;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 1,
-                         startX + width, startY + height, 0, 1, 1,
-                         startX + width, startY, 0, 1, 0);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    rsgDrawText("Custom shader with multitexturing", 10, 280);
-}
-
-static float gAnisoTime = 0.0f;
-static uint anisoMode = 0;
-static void displayAnisoSample() {
-
-    gAnisoTime += gDt;
-
-    rsgBindProgramVertex(gProgVertex);
-    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
-    rs_matrix4x4 proj;
-    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
-    rsgProgramVertexLoadProjectionMatrix(&proj);
-
-    rs_matrix4x4 matrix;
-    // Fragment shader with texture
-    rsgBindProgramStore(gProgStoreBlendNone);
-    rsgBindProgramFragment(gProgFragmentTexture);
-    rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, -10.0f);
-    rsMatrixRotate(&matrix, -80, 1.0f, 0.0f, 0.0f);
-    rsgProgramVertexLoadModelMatrix(&matrix);
-
-    rsgBindProgramRaster(gCullNone);
-
-    rsgBindTexture(gProgFragmentTexture, 0, gTexChecker);
-
-    if (gAnisoTime >= 5.0f) {
-        gAnisoTime = 0.0f;
-        anisoMode ++;
-        anisoMode = anisoMode % 3;
-    }
-
-    if (anisoMode == 0) {
-        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso8);
-    } else if (anisoMode == 1) {
-        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso15);
-    } else {
-        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
-    }
-
-    float startX = -15;
-    float startY = -15;
-    float width = 30;
-    float height = 30;
-    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
-                         startX, startY + height, 0, 0, 10,
-                         startX + width, startY + height, 0, 10, 10,
-                         startX + width, startY, 0, 10, 0);
-
-    rsgBindProgramRaster(gCullBack);
-
-    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    rsgBindFont(gFontMono);
-    if (anisoMode == 0) {
-        rsgDrawText("Anisotropic filtering 8", 10, 40);
-    } else if (anisoMode == 1) {
-        rsgDrawText("Anisotropic filtering 15", 10, 40);
-    } else {
-        rsgDrawText("Miplinear filtering", 10, 40);
-    }
-}
-
-int root(int launchID) {
-
-    gDt = rsGetDt();
-
-    rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
-    rsgClearDepth(1.0f);
-
-    switch (gDisplayMode) {
-    case 0:
-        displayFontSamples();
-        break;
-    case 1:
-        displayShaderSamples();
-        break;
-    case 2:
-        displayBlendingSamples();
-        break;
-    case 3:
-        displayMeshSamples();
-        break;
-    case 4:
-        displayTextureSamplers();
-        break;
-    case 5:
-        displayCullingSamples();
-        break;
-    case 6:
-        displayCustomShaderSamples();
-        break;
-    case 7:
-        displayMultitextureSample();
-        break;
-    case 8:
-        displayAnisoSample();
-        break;
-    case 9:
-        displayCustomShaderSamples2();
-        break;
-    case 10:
-        displayCubemapShaderSample();
-        break;
-    }
-
-    return 10;
-}
diff --git a/java/Samples/src/com/android/samples/shader_def.rsh b/java/Samples/src/com/android/samples/shader_def.rsh
deleted file mode 100644
index 1d804c6..0000000
--- a/java/Samples/src/com/android/samples/shader_def.rsh
+++ /dev/null
@@ -1,83 +0,0 @@
-// 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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.samples)
-
-typedef struct VertexShaderConstants_s {
-    rs_matrix4x4 model;
-    rs_matrix4x4 proj;
-    float4 light0_Posision;
-    float light0_Diffuse;
-    float light0_Specular;
-    float light0_CosinePower;
-
-    float4 light1_Posision;
-    float light1_Diffuse;
-    float light1_Specular;
-    float light1_CosinePower;
-} VertexShaderConstants;
-
-typedef struct VertexShaderConstants2_s {
-    rs_matrix4x4 model[2];
-    rs_matrix4x4 proj;
-    float4 light_Posision[2];
-    float light_Diffuse[2];
-    float light_Specular[2];
-    float light_CosinePower[2];
-} VertexShaderConstants2;
-
-typedef struct VertexShaderConstants3_s {
-    rs_matrix4x4 model;
-    rs_matrix4x4 proj;
-    float time;
-} VertexShaderConstants3;
-
-
-typedef struct FragentShaderConstants_s {
-    float4 light0_DiffuseColor;
-    float4 light0_SpecularColor;
-
-    float4 light1_DiffuseColor;
-    float4 light1_SpecularColor;
-} FragentShaderConstants;
-
-typedef struct FragentShaderConstants2_s {
-    float4 light_DiffuseColor[2];
-    float4 light_SpecularColor[2];
-} FragentShaderConstants2;
-
-typedef struct FragentShaderConstants3_s {
-    float4 light0_DiffuseColor;
-    float4 light0_SpecularColor;
-    float4 light0_Posision;
-    float light0_Diffuse;
-    float light0_Specular;
-    float light0_CosinePower;
-
-    float4 light1_DiffuseColor;
-    float4 light1_SpecularColor;
-    float4 light1_Posision;
-    float light1_Diffuse;
-    float light1_Specular;
-    float light1_CosinePower;
-} FragentShaderConstants3;
-
-typedef struct VertexShaderInputs_s {
-    float4 position;
-    float3 normal;
-    float2 texture0;
-} VertexShaderInputs;
-
diff --git a/java/tests/Android.mk b/java/tests/Android.mk
deleted file mode 100644
index 6c992d5..0000000
--- a/java/tests/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-
-LOCAL_PACKAGE_NAME := RSTest
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/java/tests/AndroidManifest.xml b/java/tests/AndroidManifest.xml
deleted file mode 100644
index b660398..0000000
--- a/java/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.rs.test">
-    <application 
-        android:label="_RS_Test"
-        android:icon="@drawable/test_pattern">
-        <activity android:name="RSTest"
-                  android:screenOrientation="portrait">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/java/tests/res/drawable/test_pattern.png b/java/tests/res/drawable/test_pattern.png
deleted file mode 100644
index e7d1455..0000000
--- a/java/tests/res/drawable/test_pattern.png
+++ /dev/null
Binary files differ
diff --git a/java/tests/src/com/android/rs/test/RSTest.java b/java/tests/src/com/android/rs/test/RSTest.java
deleted file mode 100644
index 6b8fa6b..0000000
--- a/java/tests/src/com/android/rs/test/RSTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.rs.test;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Config;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-public class RSTest extends Activity {
-    //EventListener mListener = new EventListener();
-
-    private static final String LOG_TAG = "libRS_jni";
-    private static final boolean DEBUG  = false;
-    private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
-
-    private RSTestView mView;
-
-    // get the current looper (from your Activity UI thread for instance
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        // Create our Preview view and set it as the content of our
-        // Activity
-        mView = new RSTestView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity loses focus
-        super.onResume();
-        mView.resume();
-    }
-
-    @Override
-    protected void onPause() {
-        // Ideally a game should implement onResume() and onPause()
-        // to take appropriate action when the activity loses focus
-        super.onPause();
-        mView.pause();
-    }
-
-    static void log(String message) {
-        if (LOG_ENABLED) {
-            Log.v(LOG_TAG, message);
-        }
-    }
-
-
-}
diff --git a/java/tests/src/com/android/rs/test/RSTestCore.java b/java/tests/src/com/android/rs/test/RSTestCore.java
deleted file mode 100644
index 541bf22..0000000
--- a/java/tests/src/com/android/rs/test/RSTestCore.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.rs.test;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.util.Log;
-import java.util.ArrayList;
-import java.util.ListIterator;
-import java.util.Timer;
-import java.util.TimerTask;
-
-
-public class RSTestCore {
-    int mWidth;
-    int mHeight;
-    Context mCtx;
-
-    public RSTestCore(Context ctx) {
-        mCtx = ctx;
-    }
-
-    private Resources mRes;
-    private RenderScriptGL mRS;
-
-    private Font mFont;
-    ScriptField_ListAllocs_s mListAllocs;
-    int mLastX;
-    int mLastY;
-    private ScriptC_rslist mScript;
-
-    private ArrayList<UnitTest> unitTests;
-    private ListIterator<UnitTest> test_iter;
-    private UnitTest activeTest;
-    private boolean stopTesting;
-
-    /* Periodic timer for ensuring future tests get scheduled */
-    private Timer mTimer;
-    public static final int RS_TIMER_PERIOD = 100;
-
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        mRS = rs;
-        mRes = res;
-        mWidth = width;
-        mHeight = height;
-        stopTesting = false;
-
-        mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist);
-
-        unitTests = new ArrayList<UnitTest>();
-
-        unitTests.add(new UT_primitives(this, mRes, mCtx));
-        unitTests.add(new UT_rsdebug(this, mRes, mCtx));
-        unitTests.add(new UT_rstime(this, mRes, mCtx));
-        unitTests.add(new UT_rstypes(this, mRes, mCtx));
-        unitTests.add(new UT_math(this, mRes, mCtx));
-        unitTests.add(new UT_fp_mad(this, mRes, mCtx));
-        /*
-        unitTests.add(new UnitTest(null, "<Pass>", 1));
-        unitTests.add(new UnitTest());
-        unitTests.add(new UnitTest(null, "<Fail>", -1));
-
-        for (int i = 0; i < 20; i++) {
-            unitTests.add(new UnitTest(null, "<Pass>", 1));
-        }
-        */
-
-        UnitTest [] uta = new UnitTest[unitTests.size()];
-        uta = unitTests.toArray(uta);
-
-        mListAllocs = new ScriptField_ListAllocs_s(mRS, uta.length);
-        for (int i = 0; i < uta.length; i++) {
-            ScriptField_ListAllocs_s.Item listElem = new ScriptField_ListAllocs_s.Item();
-            listElem.text = Allocation.createFromString(mRS, uta[i].name, Allocation.USAGE_SCRIPT);
-            listElem.result = uta[i].result;
-            mListAllocs.set(listElem, i, false);
-            uta[i].setItem(listElem);
-        }
-
-        mListAllocs.copyAll();
-
-        mScript.bind_gList(mListAllocs);
-
-        mFont = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
-        mScript.set_gFont(mFont);
-
-        mRS.bindRootScript(mScript);
-
-        test_iter = unitTests.listIterator();
-        refreshTestResults(); /* Kick off the first test */
-
-        TimerTask pTask = new TimerTask() {
-            public void run() {
-                refreshTestResults();
-            }
-        };
-
-        mTimer = new Timer();
-        mTimer.schedule(pTask, RS_TIMER_PERIOD, RS_TIMER_PERIOD);
-    }
-
-    public void checkAndRunNextTest() {
-        if (activeTest != null) {
-            if (!activeTest.isAlive()) {
-                /* Properly clean up on our last test */
-                try {
-                    activeTest.join();
-                }
-                catch (InterruptedException e) {
-                }
-                activeTest = null;
-            }
-        }
-
-        if (!stopTesting && activeTest == null) {
-            if (test_iter.hasNext()) {
-                activeTest = test_iter.next();
-                activeTest.start();
-                /* This routine will only get called once when a new test
-                 * should start running. The message handler in UnitTest.java
-                 * ensures this. */
-            }
-            else {
-                if (mTimer != null) {
-                    mTimer.cancel();
-                    mTimer.purge();
-                    mTimer = null;
-                }
-            }
-        }
-    }
-
-    public void refreshTestResults() {
-        checkAndRunNextTest();
-
-        if (mListAllocs != null && mScript != null && mRS != null) {
-            mListAllocs.copyAll();
-
-            mScript.bind_gList(mListAllocs);
-            mRS.bindRootScript(mScript);
-        }
-    }
-
-    public void cleanup() {
-        stopTesting = true;
-        UnitTest t = activeTest;
-
-        /* Stop periodic refresh of testing */
-        if (mTimer != null) {
-            mTimer.cancel();
-            mTimer.purge();
-            mTimer = null;
-        }
-
-        /* Wait to exit until we finish the current test */
-        if (t != null) {
-            try {
-                t.join();
-            }
-            catch (InterruptedException e) {
-            }
-            t = null;
-        }
-
-    }
-
-    public void newTouchPosition(float x, float y, float pressure, int id) {
-    }
-
-    public void onActionDown(int x, int y) {
-        mScript.set_gDY(0.0f);
-        mLastX = x;
-        mLastY = y;
-        refreshTestResults();
-    }
-
-    public void onActionMove(int x, int y) {
-        int dx = mLastX - x;
-        int dy = mLastY - y;
-
-        if (Math.abs(dy) <= 2) {
-            dy = 0;
-        }
-
-        mScript.set_gDY(dy);
-
-        mLastX = x;
-        mLastY = y;
-        refreshTestResults();
-    }
-}
diff --git a/java/tests/src/com/android/rs/test/RSTestView.java b/java/tests/src/com/android/rs/test/RSTestView.java
deleted file mode 100644
index 368f286..0000000
--- a/java/tests/src/com/android/rs/test/RSTestView.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.rs.test;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class RSTestView extends RSSurfaceView {
-
-    private Context mCtx;
-
-    public RSTestView(Context context) {
-        super(context);
-        mCtx = context;
-        //setFocusable(true);
-    }
-
-    private RenderScriptGL mRS;
-    private RSTestCore mRender;
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-        if (mRS == null) {
-            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
-            mRS = createRenderScriptGL(sc);
-            mRS.setSurface(holder, w, h);
-            mRender = new RSTestCore(mCtx);
-            mRender.init(mRS, getResources(), w, h);
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        if(mRS != null) {
-            mRender.cleanup();
-            mRS = null;
-            destroyRenderScriptGL();
-        }
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event)
-    {
-        return super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev)
-    {
-        boolean ret = false;
-        int act = ev.getAction();
-        if (act == ev.ACTION_DOWN) {
-            mRender.onActionDown((int)ev.getX(), (int)ev.getY());
-            ret = true;
-        }
-        else if (act == ev.ACTION_MOVE) {
-            mRender.onActionMove((int)ev.getX(), (int)ev.getY());
-            ret = true;
-        }
-
-        return ret;
-    }
-}
diff --git a/java/tests/src/com/android/rs/test/UT_fp_mad.java b/java/tests/src/com/android/rs/test/UT_fp_mad.java
deleted file mode 100644
index f2c91af..0000000
--- a/java/tests/src/com/android/rs/test/UT_fp_mad.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.renderscript.*;
-
-public class UT_fp_mad extends UnitTest {
-    private Resources mRes;
-
-    protected UT_fp_mad(RSTestCore rstc, Resources res, Context ctx) {
-        super(rstc, "Fp_Mad", ctx);
-        mRes = res;
-    }
-
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
-        ScriptC_fp_mad s = new ScriptC_fp_mad(pRS, mRes, R.raw.fp_mad);
-        pRS.setMessageHandler(mRsMessage);
-        s.invoke_fp_mad_test(0, 0);
-        pRS.finish();
-        waitForMessage();
-        pRS.destroy();
-    }
-}
diff --git a/java/tests/src/com/android/rs/test/UT_math.java b/java/tests/src/com/android/rs/test/UT_math.java
deleted file mode 100644
index bf133be..0000000
--- a/java/tests/src/com/android/rs/test/UT_math.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.renderscript.*;
-
-public class UT_math extends UnitTest {
-    private Resources mRes;
-
-    protected UT_math(RSTestCore rstc, Resources res, Context ctx) {
-        super(rstc, "Math", ctx);
-        mRes = res;
-    }
-
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
-        ScriptC_math s = new ScriptC_math(pRS, mRes, R.raw.math);
-        pRS.setMessageHandler(mRsMessage);
-        s.invoke_math_test(0, 0);
-        pRS.finish();
-        waitForMessage();
-        pRS.destroy();
-    }
-}
diff --git a/java/tests/src/com/android/rs/test/UT_primitives.java b/java/tests/src/com/android/rs/test/UT_primitives.java
deleted file mode 100644
index b7a65a5..0000000
--- a/java/tests/src/com/android/rs/test/UT_primitives.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.renderscript.*;
-
-public class UT_primitives extends UnitTest {
-    private Resources mRes;
-
-    protected UT_primitives(RSTestCore rstc, Resources res, Context ctx) {
-        super(rstc, "Primitives", ctx);
-        mRes = res;
-    }
-
-    private boolean initializeGlobals(ScriptC_primitives s) {
-        float pF = s.get_floatTest();
-        if (pF != 1.99f) {
-            return false;
-        }
-        s.set_floatTest(2.99f);
-
-        double pD = s.get_doubleTest();
-        if (pD != 2.05) {
-            return false;
-        }
-        s.set_doubleTest(3.05);
-
-        byte pC = s.get_charTest();
-        if (pC != -8) {
-            return false;
-        }
-        s.set_charTest((byte)-16);
-
-        short pS = s.get_shortTest();
-        if (pS != -16) {
-            return false;
-        }
-        s.set_shortTest((short)-32);
-
-        int pI = s.get_intTest();
-        if (pI != -32) {
-            return false;
-        }
-        s.set_intTest(-64);
-
-        long pL = s.get_longTest();
-        if (pL != 17179869184l) {
-            return false;
-        }
-        s.set_longTest(17179869185l);
-
-        long puL = s.get_ulongTest();
-        if (puL != 4611686018427387904L) {
-            return false;
-        }
-        s.set_ulongTest(4611686018427387903L);
-
-
-        long pLL = s.get_longlongTest();
-        if (pLL != 68719476736L) {
-            return false;
-        }
-        s.set_longlongTest(68719476735L);
-
-        long pu64 = s.get_uint64_tTest();
-        if (pu64 != 117179869184l) {
-            return false;
-        }
-        s.set_uint64_tTest(117179869185l);
-
-        return true;
-    }
-
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
-        ScriptC_primitives s = new ScriptC_primitives(pRS, mRes, R.raw.primitives);
-        pRS.setMessageHandler(mRsMessage);
-        if (!initializeGlobals(s)) {
-            // initializeGlobals failed
-            result = -1;
-        } else {
-            s.invoke_primitives_test(0, 0);
-            pRS.finish();
-            waitForMessage();
-        }
-        pRS.destroy();
-    }
-}
diff --git a/java/tests/src/com/android/rs/test/UT_rsdebug.java b/java/tests/src/com/android/rs/test/UT_rsdebug.java
deleted file mode 100644
index 0614b1a..0000000
--- a/java/tests/src/com/android/rs/test/UT_rsdebug.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.renderscript.*;
-
-public class UT_rsdebug extends UnitTest {
-    private Resources mRes;
-
-    protected UT_rsdebug(RSTestCore rstc, Resources res, Context ctx) {
-        super(rstc, "rsDebug", ctx);
-        mRes = res;
-    }
-
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
-        ScriptC_rsdebug s = new ScriptC_rsdebug(pRS, mRes, R.raw.rsdebug);
-        pRS.setMessageHandler(mRsMessage);
-        s.invoke_test_rsdebug(0, 0);
-        pRS.finish();
-        waitForMessage();
-        pRS.destroy();
-    }
-}
diff --git a/java/tests/src/com/android/rs/test/UT_rstime.java b/java/tests/src/com/android/rs/test/UT_rstime.java
deleted file mode 100644
index f302e1a..0000000
--- a/java/tests/src/com/android/rs/test/UT_rstime.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.renderscript.*;
-
-public class UT_rstime extends UnitTest {
-    private Resources mRes;
-
-    protected UT_rstime(RSTestCore rstc, Resources res, Context ctx) {
-        super(rstc, "rsTime", ctx);
-        mRes = res;
-    }
-
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
-        ScriptC_rstime s = new ScriptC_rstime(pRS, mRes, R.raw.rstime);
-        pRS.setMessageHandler(mRsMessage);
-        s.invoke_test_rstime(0, 0);
-        pRS.finish();
-        waitForMessage();
-        pRS.destroy();
-    }
-}
diff --git a/java/tests/src/com/android/rs/test/UT_rstypes.java b/java/tests/src/com/android/rs/test/UT_rstypes.java
deleted file mode 100644
index 74211c8..0000000
--- a/java/tests/src/com/android/rs/test/UT_rstypes.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.renderscript.*;
-
-public class UT_rstypes extends UnitTest {
-    private Resources mRes;
-
-    protected UT_rstypes(RSTestCore rstc, Resources res, Context ctx) {
-        super(rstc, "rsTypes", ctx);
-        mRes = res;
-    }
-
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
-        ScriptC_rstypes s = new ScriptC_rstypes(pRS, mRes, R.raw.rstypes);
-        pRS.setMessageHandler(mRsMessage);
-        s.invoke_test_rstypes(0, 0);
-        pRS.finish();
-        waitForMessage();
-        pRS.destroy();
-    }
-}
diff --git a/java/tests/src/com/android/rs/test/UnitTest.java b/java/tests/src/com/android/rs/test/UnitTest.java
deleted file mode 100644
index a7722c7..0000000
--- a/java/tests/src/com/android/rs/test/UnitTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-import android.content.Context;
-import android.renderscript.RenderScript.RSMessageHandler;
-import android.util.Log;
-
-public class UnitTest extends Thread {
-    public String name;
-    public int result;
-    private ScriptField_ListAllocs_s.Item mItem;
-    private RSTestCore mRSTC;
-    private boolean msgHandled;
-    protected Context mCtx;
-
-    /* These constants must match those in shared.rsh */
-    public static final int RS_MSG_TEST_PASSED = 100;
-    public static final int RS_MSG_TEST_FAILED = 101;
-
-    private static int numTests = 0;
-    public int testID;
-
-    protected UnitTest(RSTestCore rstc, String n, int initResult, Context ctx) {
-        super();
-        mRSTC = rstc;
-        name = n;
-        msgHandled = false;
-        mCtx = ctx;
-        result = initResult;
-        testID = numTests++;
-    }
-
-    protected UnitTest(RSTestCore rstc, String n, Context ctx) {
-        this(rstc, n, 0, ctx);
-    }
-
-    protected UnitTest(RSTestCore rstc, Context ctx) {
-        this (rstc, "<Unknown>", ctx);
-    }
-
-    protected UnitTest(Context ctx) {
-        this (null, ctx);
-    }
-
-    protected RSMessageHandler mRsMessage = new RSMessageHandler() {
-        public void run() {
-            if (result == 0) {
-                switch (mID) {
-                    case RS_MSG_TEST_PASSED:
-                        result = 1;
-                        break;
-                    case RS_MSG_TEST_FAILED:
-                        result = -1;
-                        break;
-                    default:
-                        android.util.Log.v("RenderScript", "Unit test got unexpected message");
-                        return;
-                }
-            }
-
-            if (mItem != null) {
-                mItem.result = result;
-                msgHandled = true;
-                try {
-                    mRSTC.refreshTestResults();
-                }
-                catch (IllegalStateException e) {
-                    /* Ignore the case where our message receiver has been
-                       disconnected. This happens when we leave the application
-                       before it finishes running all of the unit tests. */
-                }
-            }
-        }
-    };
-
-    public void waitForMessage() {
-        while (!msgHandled) {
-            yield();
-        }
-    }
-
-    public void setItem(ScriptField_ListAllocs_s.Item item) {
-        mItem = item;
-    }
-
-    public void run() {
-        /* This method needs to be implemented for each subclass */
-        if (mRSTC != null) {
-            mRSTC.refreshTestResults();
-        }
-    }
-}
diff --git a/java/tests/src/com/android/rs/test/fp_mad.rs b/java/tests/src/com/android/rs/test/fp_mad.rs
deleted file mode 100644
index b6f2b2a..0000000
--- a/java/tests/src/com/android/rs/test/fp_mad.rs
+++ /dev/null
@@ -1,174 +0,0 @@
-#include "shared.rsh"
-
-const int TEST_COUNT = 1;
-
-static float data_f1[1025];
-static float4 data_f4[1025];
-
-static void test_mad4(uint32_t index) {
-    start();
-
-    float total = 0;
-    // Do ~1 billion ops
-    for (int ct=0; ct < 1000 * (1000 / 80); ct++) {
-        for (int i=0; i < (1000); i++) {
-            data_f4[i] = (data_f4[i] * 0.02f +
-                          data_f4[i+1] * 0.04f +
-                          data_f4[i+2] * 0.05f +
-                          data_f4[i+3] * 0.1f +
-                          data_f4[i+4] * 0.2f +
-                          data_f4[i+5] * 0.2f +
-                          data_f4[i+6] * 0.1f +
-                          data_f4[i+7] * 0.05f +
-                          data_f4[i+8] * 0.04f +
-                          data_f4[i+9] * 0.02f + 1.f);
-        }
-    }
-
-    float time = end(index);
-    rsDebug("fp_mad4 M ops", 1000.f / time);
-}
-
-static void test_mad(uint32_t index) {
-    start();
-
-    float total = 0;
-    // Do ~1 billion ops
-    for (int ct=0; ct < 1000 * (1000 / 20); ct++) {
-        for (int i=0; i < (1000); i++) {
-            data_f1[i] = (data_f1[i] * 0.02f +
-                          data_f1[i+1] * 0.04f +
-                          data_f1[i+2] * 0.05f +
-                          data_f1[i+3] * 0.1f +
-                          data_f1[i+4] * 0.2f +
-                          data_f1[i+5] * 0.2f +
-                          data_f1[i+6] * 0.1f +
-                          data_f1[i+7] * 0.05f +
-                          data_f1[i+8] * 0.04f +
-                          data_f1[i+9] * 0.02f + 1.f);
-        }
-    }
-
-    float time = end(index);
-    rsDebug("fp_mad M ops", 1000.f / time);
-}
-
-static void test_norm(uint32_t index) {
-    start();
-
-    float total = 0;
-    // Do ~10 M ops
-    for (int ct=0; ct < 1000 * 10; ct++) {
-        for (int i=0; i < (1000); i++) {
-            data_f4[i] = normalize(data_f4[i]);
-        }
-    }
-
-    float time = end(index);
-    rsDebug("fp_norm M ops", 10.f / time);
-}
-
-static void test_sincos4(uint32_t index) {
-    start();
-
-    float total = 0;
-    // Do ~10 M ops
-    for (int ct=0; ct < 1000 * 10 / 4; ct++) {
-        for (int i=0; i < (1000); i++) {
-            data_f4[i] = sin(data_f4[i]) * cos(data_f4[i]);
-        }
-    }
-
-    float time = end(index);
-    rsDebug("fp_sincos4 M ops", 10.f / time);
-}
-
-static void test_sincos(uint32_t index) {
-    start();
-
-    float total = 0;
-    // Do ~10 M ops
-    for (int ct=0; ct < 1000 * 10; ct++) {
-        for (int i=0; i < (1000); i++) {
-            data_f1[i] = sin(data_f1[i]) * cos(data_f1[i]);
-        }
-    }
-
-    float time = end(index);
-    rsDebug("fp_sincos M ops", 10.f / time);
-}
-
-static void test_clamp(uint32_t index) {
-    start();
-
-    // Do ~100 M ops
-    for (int ct=0; ct < 1000 * 100; ct++) {
-        for (int i=0; i < (1000); i++) {
-            data_f1[i] = clamp(data_f1[i], -1.f, 1.f);
-        }
-    }
-
-    float time = end(index);
-    rsDebug("fp_clamp M ops", 100.f / time);
-
-    start();
-    // Do ~100 M ops
-    for (int ct=0; ct < 1000 * 100; ct++) {
-        for (int i=0; i < (1000); i++) {
-            if (data_f1[i] < -1.f) data_f1[i] = -1.f;
-            if (data_f1[i] > -1.f) data_f1[i] = 1.f;
-        }
-    }
-
-    time = end(index);
-    rsDebug("fp_clamp ref M ops", 100.f / time);
-}
-
-static void test_clamp4(uint32_t index) {
-    start();
-
-    float total = 0;
-    // Do ~100 M ops
-    for (int ct=0; ct < 1000 * 100 /4; ct++) {
-        for (int i=0; i < (1000); i++) {
-            data_f4[i] = clamp(data_f4[i], -1.f, 1.f);
-        }
-    }
-
-    float time = end(index);
-    rsDebug("fp_clamp4 M ops", 100.f / time);
-}
-
-void fp_mad_test(uint32_t index, int test_num) {
-    int x;
-    for (x=0; x < 1025; x++) {
-        data_f1[x] = (x & 0xf) * 0.1f;
-        data_f4[x].x = (x & 0xf) * 0.1f;
-        data_f4[x].y = (x & 0xf0) * 0.1f;
-        data_f4[x].z = (x & 0x33) * 0.1f;
-        data_f4[x].w = (x & 0x77) * 0.1f;
-    }
-
-    test_mad4(index);
-    test_mad(index);
-
-    for (x=0; x < 1025; x++) {
-        data_f1[x] = (x & 0xf) * 0.1f + 1.f;
-        data_f4[x].x = (x & 0xf) * 0.1f + 1.f;
-        data_f4[x].y = (x & 0xf0) * 0.1f + 1.f;
-        data_f4[x].z = (x & 0x33) * 0.1f + 1.f;
-        data_f4[x].w = (x & 0x77) * 0.1f + 1.f;
-    }
-
-    test_norm(index);
-    test_sincos4(index);
-    test_sincos(index);
-    test_clamp4(index);
-    test_clamp(index);
-
-    // TODO Actually verify test result accuracy
-    rsDebug("fp_mad_test PASSED", 0);
-    rsSendToClientBlocking(RS_MSG_TEST_PASSED);
-}
-
-
diff --git a/java/tests/src/com/android/rs/test/math.rs b/java/tests/src/com/android/rs/test/math.rs
deleted file mode 100644
index 8cad82b..0000000
--- a/java/tests/src/com/android/rs/test/math.rs
+++ /dev/null
@@ -1,322 +0,0 @@
-#include "shared.rsh"
-
-// Testing math library
-
-volatile float f1;
-volatile float2 f2;
-volatile float3 f3;
-volatile float4 f4;
-
-volatile int i1;
-volatile int2 i2;
-volatile int3 i3;
-volatile int4 i4;
-
-volatile uint ui1;
-volatile uint2 ui2;
-volatile uint3 ui3;
-volatile uint4 ui4;
-
-volatile short s1;
-volatile short2 s2;
-volatile short3 s3;
-volatile short4 s4;
-
-volatile ushort us1;
-volatile ushort2 us2;
-volatile ushort3 us3;
-volatile ushort4 us4;
-
-volatile char c1;
-volatile char2 c2;
-volatile char3 c3;
-volatile char4 c4;
-
-volatile uchar uc1;
-volatile uchar2 uc2;
-volatile uchar3 uc3;
-volatile uchar4 uc4;
-
-#define TEST_FN_FUNC_FN(fnc)        \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1);                   \
-    f2 = fnc(f2);                   \
-    f3 = fnc(f3);                   \
-    f4 = fnc(f4);
-
-#define TEST_FN_FUNC_FN_PFN(fnc)    \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, (float*) &f1);     \
-    f2 = fnc(f2, (float2*) &f2);    \
-    f3 = fnc(f3, (float3*) &f3);    \
-    f4 = fnc(f4, (float4*) &f4);
-
-#define TEST_FN_FUNC_FN_FN(fnc)     \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, f1);               \
-    f2 = fnc(f2, f2);               \
-    f3 = fnc(f3, f3);               \
-    f4 = fnc(f4, f4);
-
-#define TEST_FN_FUNC_FN_F(fnc)      \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, f1);               \
-    f2 = fnc(f2, f1);               \
-    f3 = fnc(f3, f1);               \
-    f4 = fnc(f4, f1);
-
-#define TEST_FN_FUNC_FN_IN(fnc)     \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, i1);               \
-    f2 = fnc(f2, i2);               \
-    f3 = fnc(f3, i3);               \
-    f4 = fnc(f4, i4);
-
-#define TEST_FN_FUNC_FN_I(fnc)      \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, i1);               \
-    f2 = fnc(f2, i1);               \
-    f3 = fnc(f3, i1);               \
-    f4 = fnc(f4, i1);
-
-#define TEST_FN_FUNC_FN_FN_FN(fnc)  \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, f1, f1);           \
-    f2 = fnc(f2, f2, f2);           \
-    f3 = fnc(f3, f3, f3);           \
-    f4 = fnc(f4, f4, f4);
-
-#define TEST_FN_FUNC_FN_PIN(fnc)    \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, (int*) &i1);       \
-    f2 = fnc(f2, (int2*) &i2);      \
-    f3 = fnc(f3, (int3*) &i3);      \
-    f4 = fnc(f4, (int4*) &i4);
-
-#define TEST_FN_FUNC_FN_FN_PIN(fnc) \
-    rsDebug("Testing " #fnc, 0);    \
-    f1 = fnc(f1, f1, (int*) &i1);   \
-    f2 = fnc(f2, f2, (int2*) &i2);  \
-    f3 = fnc(f3, f3, (int3*) &i3);  \
-    f4 = fnc(f4, f4, (int4*) &i4);
-
-#define TEST_IN_FUNC_FN(fnc)        \
-    rsDebug("Testing " #fnc, 0);    \
-    i1 = fnc(f1);                   \
-    i2 = fnc(f2);                   \
-    i3 = fnc(f3);                   \
-    i4 = fnc(f4);
-
-
-static bool test_fp_math(uint32_t index) {
-    bool failed = false;
-    start();
-
-    TEST_FN_FUNC_FN(acos);
-    TEST_FN_FUNC_FN(acosh);
-    TEST_FN_FUNC_FN(acospi);
-    TEST_FN_FUNC_FN(asin);
-    TEST_FN_FUNC_FN(asinh);
-    TEST_FN_FUNC_FN(asinpi);
-    TEST_FN_FUNC_FN(atan);
-    TEST_FN_FUNC_FN_FN(atan2);
-    TEST_FN_FUNC_FN(atanh);
-    TEST_FN_FUNC_FN(atanpi);
-    TEST_FN_FUNC_FN_FN(atan2pi);
-    TEST_FN_FUNC_FN(cbrt);
-    TEST_FN_FUNC_FN(ceil);
-    TEST_FN_FUNC_FN_FN(copysign);
-    TEST_FN_FUNC_FN(cos);
-    TEST_FN_FUNC_FN(cosh);
-    TEST_FN_FUNC_FN(cospi);
-    TEST_FN_FUNC_FN(erfc);
-    TEST_FN_FUNC_FN(erf);
-    TEST_FN_FUNC_FN(exp);
-    TEST_FN_FUNC_FN(exp2);
-    TEST_FN_FUNC_FN(exp10);
-    TEST_FN_FUNC_FN(expm1);
-    TEST_FN_FUNC_FN(fabs);
-    TEST_FN_FUNC_FN_FN(fdim);
-    TEST_FN_FUNC_FN(floor);
-    TEST_FN_FUNC_FN_FN_FN(fma);
-    TEST_FN_FUNC_FN_FN(fmax);
-    TEST_FN_FUNC_FN_F(fmax);
-    TEST_FN_FUNC_FN_FN(fmin);
-    TEST_FN_FUNC_FN_F(fmin);
-    TEST_FN_FUNC_FN_FN(fmod);
-    TEST_FN_FUNC_FN_PFN(fract);
-    TEST_FN_FUNC_FN_PIN(frexp);
-    TEST_FN_FUNC_FN_FN(hypot);
-    TEST_IN_FUNC_FN(ilogb);
-    TEST_FN_FUNC_FN_IN(ldexp);
-    TEST_FN_FUNC_FN_I(ldexp);
-    TEST_FN_FUNC_FN(lgamma);
-    TEST_FN_FUNC_FN_PIN(lgamma);
-    TEST_FN_FUNC_FN(log);
-    TEST_FN_FUNC_FN(log2);
-    TEST_FN_FUNC_FN(log10);
-    TEST_FN_FUNC_FN(log1p);
-    TEST_FN_FUNC_FN(logb);
-    TEST_FN_FUNC_FN_FN_FN(mad);
-    TEST_FN_FUNC_FN_PFN(modf);
-    // nan
-    TEST_FN_FUNC_FN_FN(nextafter);
-    TEST_FN_FUNC_FN_FN(pow);
-    TEST_FN_FUNC_FN_IN(pown);
-    TEST_FN_FUNC_FN_FN(powr);
-    TEST_FN_FUNC_FN_FN(remainder);
-    TEST_FN_FUNC_FN_FN_PIN(remquo);
-    TEST_FN_FUNC_FN(rint);
-    TEST_FN_FUNC_FN_IN(rootn);
-    TEST_FN_FUNC_FN(round);
-    TEST_FN_FUNC_FN(rsqrt);
-    TEST_FN_FUNC_FN(sin);
-    TEST_FN_FUNC_FN_PFN(sincos);
-    TEST_FN_FUNC_FN(sinh);
-    TEST_FN_FUNC_FN(sinpi);
-    TEST_FN_FUNC_FN(sqrt);
-    TEST_FN_FUNC_FN(tan);
-    TEST_FN_FUNC_FN(tanh);
-    TEST_FN_FUNC_FN(tanpi);
-    TEST_FN_FUNC_FN(tgamma);
-    TEST_FN_FUNC_FN(trunc);
-
-    float time = end(index);
-
-    if (failed) {
-        rsDebug("test_fp_math FAILED", time);
-    }
-    else {
-        rsDebug("test_fp_math PASSED", time);
-    }
-
-    return failed;
-}
-
-#define DECL_INT(prefix)            \
-volatile char prefix##_c_1 = 1;     \
-volatile char2 prefix##_c_2 = 1;    \
-volatile char3 prefix##_c_3 = 1;    \
-volatile char4 prefix##_c_4 = 1;    \
-volatile uchar prefix##_uc_1 = 1;   \
-volatile uchar2 prefix##_uc_2 = 1;  \
-volatile uchar3 prefix##_uc_3 = 1;  \
-volatile uchar4 prefix##_uc_4 = 1;  \
-volatile short prefix##_s_1 = 1;    \
-volatile short2 prefix##_s_2 = 1;   \
-volatile short3 prefix##_s_3 = 1;   \
-volatile short4 prefix##_s_4 = 1;   \
-volatile ushort prefix##_us_1 = 1;  \
-volatile ushort2 prefix##_us_2 = 1; \
-volatile ushort3 prefix##_us_3 = 1; \
-volatile ushort4 prefix##_us_4 = 1; \
-volatile int prefix##_i_1 = 1;      \
-volatile int2 prefix##_i_2 = 1;     \
-volatile int3 prefix##_i_3 = 1;     \
-volatile int4 prefix##_i_4 = 1;     \
-volatile uint prefix##_ui_1 = 1;    \
-volatile uint2 prefix##_ui_2 = 1;   \
-volatile uint3 prefix##_ui_3 = 1;   \
-volatile uint4 prefix##_ui_4 = 1;   \
-volatile long prefix##_l_1 = 1;     \
-volatile ulong prefix##_ul_1 = 1;
-
-#define TEST_INT_OP_TYPE(op, type)                      \
-rsDebug("Testing " #op " for " #type "1", i++);         \
-res_##type##_1 = src1_##type##_1 op src2_##type##_1;    \
-rsDebug("Testing " #op " for " #type "2", i++);         \
-res_##type##_2 = src1_##type##_2 op src2_##type##_2;    \
-rsDebug("Testing " #op " for " #type "3", i++);         \
-res_##type##_3 = src1_##type##_3 op src2_##type##_3;    \
-rsDebug("Testing " #op " for " #type "4", i++);         \
-res_##type##_4 = src1_##type##_4 op src2_##type##_4;
-
-#define TEST_INT_OP(op)                     \
-TEST_INT_OP_TYPE(op, c)                     \
-TEST_INT_OP_TYPE(op, uc)                    \
-TEST_INT_OP_TYPE(op, s)                     \
-TEST_INT_OP_TYPE(op, us)                    \
-TEST_INT_OP_TYPE(op, i)                     \
-TEST_INT_OP_TYPE(op, ui)                    \
-rsDebug("Testing " #op " for l1", i++);     \
-res_l_1 = src1_l_1 op src2_l_1;             \
-rsDebug("Testing " #op " for ul1", i++);    \
-res_ul_1 = src1_ul_1 op src2_ul_1;
-
-DECL_INT(res)
-DECL_INT(src1)
-DECL_INT(src2)
-
-static bool test_basic_operators() {
-    bool failed = false;
-    int i = 0;
-
-    TEST_INT_OP(+);
-    TEST_INT_OP(-);
-    TEST_INT_OP(*);
-    TEST_INT_OP(/);
-    TEST_INT_OP(%);
-    TEST_INT_OP(<<);
-    TEST_INT_OP(>>);
-
-    if (failed) {
-        rsDebug("test_basic_operators FAILED", 0);
-    }
-    else {
-        rsDebug("test_basic_operators PASSED", 0);
-    }
-
-    return failed;
-}
-
-#define TEST_CVT(to, from, type)                        \
-rsDebug("Testing convert from " #from " to " #to, 0);   \
-to##1 = from##1;                                        \
-to##2 = convert_##type##2(from##2);                     \
-to##3 = convert_##type##3(from##3);                     \
-to##4 = convert_##type##4(from##4);
-
-#define TEST_CVT_MATRIX(to, type)   \
-TEST_CVT(to, c, type);              \
-TEST_CVT(to, uc, type);             \
-TEST_CVT(to, s, type);              \
-TEST_CVT(to, us, type);             \
-TEST_CVT(to, i, type);              \
-TEST_CVT(to, ui, type);             \
-TEST_CVT(to, f, type);              \
-
-static bool test_convert() {
-    bool failed = false;
-
-    TEST_CVT_MATRIX(c, char);
-    TEST_CVT_MATRIX(uc, uchar);
-    TEST_CVT_MATRIX(s, short);
-    TEST_CVT_MATRIX(us, ushort);
-    TEST_CVT_MATRIX(i, int);
-    TEST_CVT_MATRIX(ui, uint);
-    TEST_CVT_MATRIX(f, float);
-
-    if (failed) {
-        rsDebug("test_convert FAILED", 0);
-    }
-    else {
-        rsDebug("test_convert PASSED", 0);
-    }
-
-    return failed;
-}
-
-void math_test(uint32_t index, int test_num) {
-    bool failed = false;
-    failed |= test_convert();
-    failed |= test_fp_math(index);
-    failed |= test_basic_operators();
-
-    if (failed) {
-        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
-    }
-    else {
-        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
-    }
-}
-
diff --git a/java/tests/src/com/android/rs/test/primitives.rs b/java/tests/src/com/android/rs/test/primitives.rs
deleted file mode 100644
index ce451da..0000000
--- a/java/tests/src/com/android/rs/test/primitives.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "shared.rsh"
-
-// Testing primitive types
-float floatTest = 1.99f;
-double doubleTest = 2.05;
-char charTest = -8;
-short shortTest = -16;
-int intTest = -32;
-long longTest = 17179869184l; // 1 << 34
-long long longlongTest = 68719476736l; // 1 << 36
-
-uchar ucharTest = 8;
-ushort ushortTest = 16;
-uint uintTest = 32;
-ulong ulongTest = 4611686018427387904L;
-int64_t int64_tTest = -17179869184l; // - 1 << 34
-uint64_t uint64_tTest = 117179869184l;
-
-static bool test_primitive_types(uint32_t index) {
-    bool failed = false;
-    start();
-
-    _RS_ASSERT(floatTest == 2.99f);
-    _RS_ASSERT(doubleTest == 3.05);
-    _RS_ASSERT(charTest == -16);
-    _RS_ASSERT(shortTest == -32);
-    _RS_ASSERT(intTest == -64);
-    _RS_ASSERT(longTest == 17179869185l);
-    _RS_ASSERT(longlongTest == 68719476735l);
-
-    _RS_ASSERT(ucharTest == 8);
-    _RS_ASSERT(ushortTest == 16);
-    _RS_ASSERT(uintTest == 32);
-    _RS_ASSERT(ulongTest == 4611686018427387903L);
-    _RS_ASSERT(int64_tTest == -17179869184l);
-    _RS_ASSERT(uint64_tTest == 117179869185l);
-
-    float time = end(index);
-
-    if (failed) {
-        rsDebug("test_primitives FAILED", time);
-    }
-    else {
-        rsDebug("test_primitives PASSED", time);
-    }
-
-    return failed;
-}
-
-void primitives_test(uint32_t index, int test_num) {
-    bool failed = false;
-    failed |= test_primitive_types(index);
-
-    if (failed) {
-        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
-    }
-    else {
-        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
-    }
-}
-
diff --git a/java/tests/src/com/android/rs/test/rsdebug.rs b/java/tests/src/com/android/rs/test/rsdebug.rs
deleted file mode 100644
index f7942a5..0000000
--- a/java/tests/src/com/android/rs/test/rsdebug.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-#include "shared.rsh"
-
-// Testing primitive types
-float floatTest = 1.99f;
-double doubleTest = 2.05;
-char charTest = -8;
-short shortTest = -16;
-int intTest = -32;
-long longTest = 17179869184l; // 1 << 34
-long long longlongTest = 68719476736l; // 1 << 36
-
-uchar ucharTest = 8;
-ushort ushortTest = 16;
-uint uintTest = 32;
-ulong ulongTest = 4611686018427387904L;
-int64_t int64_tTest = -17179869184l; // - 1 << 34
-uint64_t uint64_tTest = 117179869184l;
-
-static bool basic_test(uint32_t index) {
-    bool failed = false;
-
-    // This test focuses primarily on compilation-time, not run-time.
-    // For this reason, none of the outputs are actually checked.
-
-    rsDebug("floatTest", floatTest);
-    rsDebug("doubleTest", doubleTest);
-    rsDebug("charTest", charTest);
-    rsDebug("shortTest", shortTest);
-    rsDebug("intTest", intTest);
-    rsDebug("longTest", longTest);
-    rsDebug("longlongTest", longlongTest);
-
-    rsDebug("ucharTest", ucharTest);
-    rsDebug("ushortTest", ushortTest);
-    rsDebug("uintTest", uintTest);
-    rsDebug("ulongTest", ulongTest);
-    rsDebug("int64_tTest", int64_tTest);
-    rsDebug("uint64_tTest", uint64_tTest);
-
-    return failed;
-}
-
-void test_rsdebug(uint32_t index, int test_num) {
-    bool failed = false;
-    failed |= basic_test(index);
-
-    if (failed) {
-        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
-        rsDebug("rsdebug_test FAILED", -1);
-    }
-    else {
-        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
-        rsDebug("rsdebug_test PASSED", 0);
-    }
-}
-
diff --git a/java/tests/src/com/android/rs/test/rslist.rs b/java/tests/src/com/android/rs/test/rslist.rs
deleted file mode 100644
index 67c2b86..0000000
--- a/java/tests/src/com/android/rs/test/rslist.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-// 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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.rs.test)
-
-#include "rs_graphics.rsh"
-
-float gDY;
-
-rs_font gFont;
-
-typedef struct ListAllocs_s {
-    rs_allocation text;
-    int result;
-} ListAllocs;
-
-ListAllocs *gList;
-
-void init() {
-    gDY = 0.0f;
-}
-
-int textPos = 0;
-
-int root(int launchID) {
-
-    rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-    rsgClearDepth(1.0f);
-
-    textPos -= (int)gDY*2;
-    gDY *= 0.95;
-
-    rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f);
-    rsgBindFont(gFont);
-
-    rs_allocation listAlloc;
-    rsSetObject(&listAlloc, rsGetAllocation(gList));
-    int allocSize = rsAllocationGetDimX(listAlloc);
-
-    int width = rsgGetWidth();
-    int height = rsgGetHeight();
-
-    int itemHeight = 80;
-    int totalItemHeight = itemHeight * allocSize;
-
-    /* Prevent scrolling above the top of the list */
-    int firstItem = height - totalItemHeight;
-    if (firstItem < 0) {
-        firstItem = 0;
-    }
-
-    /* Prevent scrolling past the last line of the list */
-    int lastItem = -1 * (totalItemHeight - height);
-    if (lastItem > 0) {
-        lastItem = 0;
-    }
-
-    if (textPos > firstItem) {
-        textPos = firstItem;
-    }
-    else if (textPos < lastItem) {
-        textPos = lastItem;
-    }
-
-    int currentYPos = itemHeight + textPos;
-
-    for(int i = 0; i < allocSize; i ++) {
-        if(currentYPos - itemHeight > height) {
-            break;
-        }
-
-        if(currentYPos > 0) {
-            switch(gList[i].result) {
-                case 1: /* Passed */
-                    rsgFontColor(0.5f, 0.9f, 0.5f, 1.0f);
-                    break;
-                case -1: /* Failed */
-                    rsgFontColor(0.9f, 0.5f, 0.5f, 1.0f);
-                    break;
-                case 0: /* Still Testing */
-                    rsgFontColor(0.9f, 0.9f, 0.5f, 1.0f);
-                    break;
-                default: /* Unknown */
-                    rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f);
-                    break;
-            }
-            rsgDrawRect(0, currentYPos - 1, width, currentYPos, 0);
-            rsgDrawText(gList[i].text, 30, currentYPos - 32);
-        }
-        currentYPos += itemHeight;
-    }
-
-    return 10;
-}
diff --git a/java/tests/src/com/android/rs/test/rstime.rs b/java/tests/src/com/android/rs/test/rstime.rs
deleted file mode 100644
index 5e3e078..0000000
--- a/java/tests/src/com/android/rs/test/rstime.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "shared.rsh"
-
-static bool basic_test(uint32_t index) {
-    bool failed = false;
-
-    rs_time_t curTime = rsTime(0);
-    rs_tm tm;
-    rsDebug("curTime", curTime);
-
-    rsLocaltime(&tm, &curTime);
-
-    rsDebug("tm.tm_sec", tm.tm_sec);
-    rsDebug("tm.tm_min", tm.tm_min);
-    rsDebug("tm.tm_hour", tm.tm_hour);
-    rsDebug("tm.tm_mday", tm.tm_mday);
-    rsDebug("tm.tm_mon", tm.tm_mon);
-    rsDebug("tm.tm_year", tm.tm_year);
-    rsDebug("tm.tm_wday", tm.tm_wday);
-    rsDebug("tm.tm_yday", tm.tm_yday);
-    rsDebug("tm.tm_isdst", tm.tm_isdst);
-
-    // Test a specific time (only valid for PST localtime)
-    curTime = 1294438893;
-    rsLocaltime(&tm, &curTime);
-
-    _RS_ASSERT(tm.tm_sec == 33);
-    _RS_ASSERT(tm.tm_min == 21);
-    _RS_ASSERT(tm.tm_hour == 14);
-    _RS_ASSERT(tm.tm_mday == 7);
-    _RS_ASSERT(tm.tm_mon == 0);
-    _RS_ASSERT(tm.tm_year == 111);
-    _RS_ASSERT(tm.tm_wday == 5);
-    _RS_ASSERT(tm.tm_yday == 6);
-    _RS_ASSERT(tm.tm_isdst == 0);
-
-    return failed;
-}
-
-void test_rstime(uint32_t index, int test_num) {
-    bool failed = false;
-    failed |= basic_test(index);
-
-    if (failed) {
-        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
-        rsDebug("rstime_test FAILED", -1);
-    }
-    else {
-        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
-        rsDebug("rstime_test PASSED", 0);
-    }
-}
-
diff --git a/java/tests/src/com/android/rs/test/rstypes.rs b/java/tests/src/com/android/rs/test/rstypes.rs
deleted file mode 100644
index f3bf244..0000000
--- a/java/tests/src/com/android/rs/test/rstypes.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "shared.rsh"
-#include "rs_graphics.rsh"
-
-rs_element elementTest;
-rs_type typeTest;
-rs_allocation allocationTest;
-rs_sampler samplerTest;
-rs_script scriptTest;
-rs_mesh meshTest;
-rs_program_fragment program_fragmentTest;
-rs_program_vertex program_vertexTest;
-rs_program_raster program_rasterTest;
-rs_program_store program_storeTest;
-rs_font fontTest;
-
-rs_matrix4x4 matrix4x4Test;
-rs_matrix3x3 matrix3x3Test;
-rs_matrix2x2 matrix2x2Test;
-
-struct my_struct {
-    int i;
-    rs_font fontTestStruct;
-};
-
-static bool basic_test(uint32_t index) {
-    bool failed = false;
-
-    rs_matrix4x4 matrix4x4TestLocal;
-    rs_matrix3x3 matrix3x3TestLocal;
-    rs_matrix2x2 matrix2x2TestLocal;
-
-    // This test focuses primarily on compilation-time, not run-time.
-    rs_element elementTestLocal;
-    rs_type typeTestLocal;
-    rs_allocation allocationTestLocal;
-    rs_sampler samplerTestLocal;
-    rs_script scriptTestLocal;
-    rs_mesh meshTestLocal;
-    rs_program_fragment program_fragmentTestLocal;
-    rs_program_vertex program_vertexTestLocal;
-    rs_program_raster program_rasterTestLocal;
-    rs_program_store program_storeTestLocal;
-    rs_font fontTestLocal;
-
-    rs_font fontTestLocalArray[4];
-
-    rs_font fontTestLocalPreInit = fontTest;
-
-    struct my_struct structTest;
-
-    rsSetObject(&fontTestLocal, fontTest);
-    //allocationTestLocal = allocationTest;
-
-    rsSetObject(&fontTest, fontTestLocal);
-    //allocationTest = allocationTestLocal;
-
-    /*for (int i = 0; i < 4; i++) {
-        rsSetObject(&fontTestLocalArray[i], fontTestLocal);
-    }*/
-
-    /*rsSetObject(&fontTest, fontTestLocalArray[3]);*/
-
-    return failed;
-}
-
-void test_rstypes(uint32_t index, int test_num) {
-    bool failed = false;
-    failed |= basic_test(index);
-
-    if (failed) {
-        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
-        rsDebug("rstypes_test FAILED", -1);
-    }
-    else {
-        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
-        rsDebug("rstypes_test PASSED", 0);
-    }
-}
-
diff --git a/java/tests/src/com/android/rs/test/shared.rsh b/java/tests/src/com/android/rs/test/shared.rsh
deleted file mode 100644
index 21be9af..0000000
--- a/java/tests/src/com/android/rs/test/shared.rsh
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.rs.test)
-
-typedef struct TestResult_s {
-    rs_allocation name;
-    bool pass;
-    float score;
-    int64_t time;
-} TestResult;
-//TestResult *g_results;
-
-static int64_t g_time;
-
-static void start(void) {
-    g_time = rsUptimeMillis();
-}
-
-static float end(uint32_t idx) {
-    int64_t t = rsUptimeMillis() - g_time;
-    //g_results[idx].time = t;
-    //rsDebug("test time", (int)t);
-    return ((float)t) / 1000.f;
-}
-
-#define _RS_ASSERT(b) \
-do { \
-    if (!(b)) { \
-        failed = true; \
-        rsDebug(#b " FAILED", 0); \
-    } \
-\
-} while (0)
-
-/* These constants must match those in UnitTest.java */
-static const int RS_MSG_TEST_PASSED = 100;
-static const int RS_MSG_TEST_FAILED = 101;
-
diff --git a/java/tests/src/com/android/rs/test/test_root.rs b/java/tests/src/com/android/rs/test/test_root.rs
deleted file mode 100644
index 6dc83ba..0000000
--- a/java/tests/src/com/android/rs/test/test_root.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Fountain test script
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.rs.test)
-
-#pragma stateFragment(parent)
-
-#include "rs_graphics.rsh"
-
-
-typedef struct TestResult {
-    rs_allocation name;
-    bool pass;
-    float score;
-} TestResult_t;
-TestResult_t *results;
-
-int root() {
-
-    return 0;
-}
-
-
diff --git a/rs.spec b/rs.spec
index 7e23cec..87d764d 100644
--- a/rs.spec
+++ b/rs.spec
@@ -1,6 +1,72 @@
 
+ContextDestroy {
+    direct
+}
+
+ContextGetMessage {
+    direct
+    param void *data
+    param size_t *receiveLen
+    param uint32_t *usrID
+    ret RsMessageToClientType
+}
+
+ContextPeekMessage {
+    direct
+    param size_t *receiveLen
+    param uint32_t *usrID
+    ret RsMessageToClientType
+}
+
+ContextInitToClient {
+    direct
+}
+
+ContextDeinitToClient {
+    direct
+}
+
+TypeCreate {
+    direct
+    param RsElement e
+    param uint32_t dimX
+    param uint32_t dimY
+    param uint32_t dimZ
+    param bool mips
+    param bool faces
+    ret RsType
+}
+
+AllocationCreateTyped {
+    direct
+    param RsType vtype
+    param RsAllocationMipmapControl mips
+    param uint32_t usages
+    ret RsAllocation
+}
+
+AllocationCreateFromBitmap {
+    direct
+    param RsType vtype
+    param RsAllocationMipmapControl mips
+    param const void *data
+    param uint32_t usages
+    ret RsAllocation
+}
+
+AllocationCubeCreateFromBitmap {
+    direct
+    param RsType vtype
+    param RsAllocationMipmapControl mips
+    param const void *data
+    param uint32_t usages
+    ret RsAllocation
+}
+
+
+
 ContextFinish {
-	handcodeApi
+	sync
 	}
 
 ContextBindRootScript {
@@ -36,7 +102,7 @@
 ContextSetSurface {
 	param uint32_t width
 	param uint32_t height
-	param ANativeWindow *sur
+	param RsNativeWindow sur
 	}
 
 ContextDump {
@@ -51,9 +117,8 @@
 }
 
 AssignName {
-	param void *obj
+	param RsObjectBase obj
 	param const char *name
-	param size_t len
 	}
 
 ObjDestroy {
@@ -69,10 +134,8 @@
 	}
 
 ElementCreate2 {
-	param size_t count
 	param const RsElement * elements
 	param const char ** names
-	param const size_t * nameLengths
 	param const uint32_t * arraySize
 	ret RsElement
 	}
@@ -80,7 +143,6 @@
 AllocationCopyToBitmap {
 	param RsAllocation alloc
 	param void * data
-	param size_t dataLen
 	}
 
 
@@ -90,9 +152,6 @@
 	param uint32_t lod
 	param uint32_t count
 	param const void *data
-	param uint32_t bytes
-	handcodeApi
-	togglePlay
 	}
 
 Allocation1DElementData {
@@ -101,9 +160,6 @@
 	param uint32_t lod
 	param const void *data
 	param uint32_t comp_offset
-	param uint32_t bytes
-	handcodeApi
-	togglePlay
 	}
 
 Allocation2DData {
@@ -115,7 +171,6 @@
 	param uint32_t w
 	param uint32_t h
 	param const void *data
-	param uint32_t bytes
 	}
 
 Allocation2DElementData {
@@ -126,7 +181,6 @@
 	param RsAllocationCubemapFace face
 	param const void *data
 	param uint32_t element_offset
-	param uint32_t bytes
 	}
 
 AllocationGenerateMipmaps {
@@ -155,24 +209,15 @@
 	param uint32_t dimY
 	}
 
-SamplerBegin {
-	}
-
-SamplerSet {
-	param RsSamplerParam p
-	param RsSamplerValue value
-	}
-
-SamplerSet2 {
-	param RsSamplerParam p
-	param float value
-	}
-
 SamplerCreate {
-	ret RsSampler
-	}
-
-
+    param RsSamplerValue magFilter
+    param RsSamplerValue minFilter
+    param RsSamplerValue wrapS
+    param RsSamplerValue wrapT
+    param RsSamplerValue wrapR
+    param float mAniso
+    ret RsSampler
+}
 
 ScriptBindAllocation {
 	param RsScript vtm
@@ -180,18 +225,11 @@
 	param uint32_t slot
 	}
 
-
-ScriptCBegin {
-	}
-
-
 ScriptSetTimeZone {
 	param RsScript s
 	param const char * timeZone
-	param uint32_t length
 	}
 
-
 ScriptInvoke {
 	param RsScript s
 	param uint32_t slot
@@ -201,11 +239,16 @@
 	param RsScript s
 	param uint32_t slot
 	param const void * data
-	param uint32_t dataLen
-	handcodeApi
-	togglePlay
 	}
 
+ScriptForEach {
+    param RsScript s
+    param uint32_t slot
+    param RsAllocation ain
+    param RsAllocation aout
+    param const void * usr
+}
+
 ScriptSetVarI {
 	param RsScript s
 	param uint32_t slot
@@ -240,55 +283,27 @@
 	param RsScript s
 	param uint32_t slot
 	param const void * data
-	param uint32_t dataLen
-	handcodeApi
-	togglePlay
 	}
 
 
-ScriptCSetText {
-	param const char * text
-	param uint32_t length
-	}
-
 ScriptCCreate {
-        param const char * packageName
         param const char * resName
         param const char * cacheDir
+	param const char * text
 	ret RsScript
 	}
 
 
-ProgramStoreBegin {
-	param RsElement in
-	param RsElement out
-	}
-
-ProgramStoreColorMask {
-	param bool r
-	param bool g
-	param bool b
-	param bool a
-	}
-
-ProgramStoreBlendFunc {
+ProgramStoreCreate {
+	param bool colorMaskR
+	param bool colorMaskG
+	param bool colorMaskB
+	param bool colorMaskA
+        param bool depthMask
+        param bool ditherEnable
 	param RsBlendSrcFunc srcFunc
 	param RsBlendDstFunc destFunc
-	}
-
-ProgramStoreDepthMask {
-	param bool enable
-}
-
-ProgramStoreDither {
-	param bool enable
-}
-
-ProgramStoreDepthFunc {
-	param RsDepthFunc func
-}
-
-ProgramStoreCreate {
+        param RsDepthFunc depthFunc
 	ret RsProgramStore
 	}
 
@@ -296,19 +311,11 @@
 	param bool pointSmooth
 	param bool lineSmooth
 	param bool pointSprite
+	param float lineWidth
+	param RsCullMode cull
 	ret RsProgramRaster
 }
 
-ProgramRasterSetLineWidth {
-	param RsProgramRaster pr
-	param float lw
-}
-
-ProgramRasterSetCullMode {
-	param RsProgramRaster pr
-	param RsCullMode mode
-}
-
 ProgramBindConstants {
 	param RsProgram vp
 	param uint32_t slot
@@ -330,17 +337,13 @@
 
 ProgramFragmentCreate {
 	param const char * shaderText
-	param uint32_t shaderLength
 	param const uint32_t * params
-	param uint32_t paramLength
 	ret RsProgramFragment
 	}
 
 ProgramVertexCreate {
 	param const char * shaderText
-	param uint32_t shaderLength
 	param const uint32_t * params
-	param uint32_t paramLength
 	ret RsProgramVertex
 	}
 
@@ -355,41 +358,13 @@
 	param const char *name
 	param float fontSize
 	param uint32_t dpi
-    param const void *data
-    param uint32_t dataLen
+	param const void *data
 	ret RsFont
 	}
 
 MeshCreate {
+	param RsAllocation *vtx
+	param RsAllocation *idx
+	param uint32_t *primType
 	ret RsMesh
-	param uint32_t vtxCount
-	param uint32_t idxCount
 	}
-
-MeshBindIndex {
-	param RsMesh mesh
-	param RsAllocation idx
-	param uint32_t primType
-	param uint32_t slot
-	}
-
-MeshBindVertex {
-	param RsMesh mesh
-	param RsAllocation vtx
-	param uint32_t slot
-	}
-
-MeshInitVertexAttribs {
-	param RsMesh mesh
-	}
-
-AnimationCreate {
-	param const float *inValues
-	param const float *outValues
-	param uint32_t valueCount
-	param RsAnimationInterpolation interp
-	param RsAnimationEdge pre
-	param RsAnimationEdge post
-	ret RsAnimation
-	}
-
diff --git a/rsAdapter.cpp b/rsAdapter.cpp
index 8d363fd..6e8ca70 100644
--- a/rsAdapter.cpp
+++ b/rsAdapter.cpp
@@ -15,11 +15,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#else
-#include "rsContextHostStub.h"
-#endif
 
 using namespace android;
 using namespace android::renderscript;
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index c598f03..5b84ca6 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -13,22 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef ANDROID_RS_BUILD_FOR_HOST
-#include "rsContext.h"
 
+#include "rsContext.h"
+#ifndef ANDROID_RS_SERIALIZE
 #include <GLES/gl.h>
 #include <GLES2/gl2.h>
 #include <GLES/glext.h>
-#else
-#include "rsContextHostStub.h"
-
-#include <OpenGL/gl.h>
-#include <OpenGl/glext.h>
-#endif
-
-#include "utils/StopWatch.h"
-
-static void rsaAllocationGenerateScriptMips(RsContext con, RsAllocation va);
+#endif //ANDROID_RS_SERIALIZE
 
 using namespace android;
 using namespace android::renderscript;
@@ -38,21 +29,22 @@
     : ObjectBase(rsc) {
     init(rsc, type);
 
-    mUsageFlags = usages;
-    mMipmapControl = mc;
+    mHal.state.usageFlags = usages;
+    mHal.state.mipmapControl = mc;
 
     allocScriptMemory();
-    if (mType->getElement()->getHasReferences()) {
-        memset(mPtr, 0, mType->getSizeBytes());
+    if (mHal.state.type->getElement()->getHasReferences()) {
+        memset(mHal.state.mallocPtr, 0, mHal.state.type->getSizeBytes());
     }
-    if (!mPtr) {
+    if (!mHal.state.mallocPtr) {
         LOGE("Allocation::Allocation, alloc failure");
     }
 }
 
 
 void Allocation::init(Context *rsc, const Type *type) {
-    mPtr = NULL;
+    memset(&mHal, 0, sizeof(mHal));
+    mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
 
     mCpuWrite = false;
     mCpuRead = false;
@@ -61,29 +53,37 @@
 
     mReadWriteRatio = 0;
     mUpdateSize = 0;
-    mUsageFlags = 0;
-    mMipmapControl = RS_ALLOCATION_MIPMAP_NONE;
 
     mTextureID = 0;
     mBufferID = 0;
-    mUploadDefered = false;
+    mRenderTargetID = 0;
+    mUploadDeferred = false;
 
     mUserBitmapCallback = NULL;
     mUserBitmapCallbackData = NULL;
 
-    mType.set(type);
-    rsAssert(type);
+    mHal.state.type.set(type);
+    updateCache();
+}
 
-    mPtr = NULL;
+void Allocation::updateCache() {
+    const Type *type = mHal.state.type.get();
+    mHal.state.dimensionX = type->getDimX();
+    mHal.state.dimensionY = type->getDimY();
+    mHal.state.dimensionZ = type->getDimZ();
+    mHal.state.hasFaces = type->getDimFaces();
+    mHal.state.hasMipmaps = type->getDimLOD();
+    mHal.state.elementSizeBytes = type->getElementSizeBytes();
+    mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences();
 }
 
 Allocation::~Allocation() {
     if (mUserBitmapCallback != NULL) {
         mUserBitmapCallback(mUserBitmapCallbackData);
-        mPtr = NULL;
+        mHal.state.mallocPtr = NULL;
     }
     freeScriptMemory();
-
+#ifndef ANDROID_RS_SERIALIZE
     if (mBufferID) {
         // Causes a SW crash....
         //LOGV(" mBufferID %i", mBufferID);
@@ -94,6 +94,11 @@
         glDeleteTextures(1, &mTextureID);
         mTextureID = 0;
     }
+    if (mRenderTargetID) {
+        glDeleteRenderbuffers(1, &mRenderTargetID);
+        mRenderTargetID = 0;
+    }
+#endif //ANDROID_RS_SERIALIZE
 }
 
 void Allocation::setCpuWritable(bool) {
@@ -112,14 +117,20 @@
     return false;
 }
 
-void Allocation::deferedUploadToTexture(const Context *rsc) {
-    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
-    mUploadDefered = true;
+void Allocation::deferredUploadToTexture(const Context *rsc) {
+    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
+    mUploadDeferred = true;
+}
+
+void Allocation::deferredAllocateRenderTarget(const Context *rsc) {
+    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET;
+    mUploadDeferred = true;
 }
 
 uint32_t Allocation::getGLTarget() const {
+#ifndef ANDROID_RS_SERIALIZE
     if (getIsTexture()) {
-        if (mType->getDimFaces()) {
+        if (mHal.state.type->getDimFaces()) {
             return GL_TEXTURE_CUBE_MAP;
         } else {
             return GL_TEXTURE_2D;
@@ -128,18 +139,19 @@
     if (getIsBufferObject()) {
         return GL_ARRAY_BUFFER;
     }
+#endif //ANDROID_RS_SERIALIZE
     return 0;
 }
 
 void Allocation::allocScriptMemory() {
-    rsAssert(!mPtr);
-    mPtr = malloc(mType->getSizeBytes());
+    rsAssert(!mHal.state.mallocPtr);
+    mHal.state.mallocPtr = malloc(mHal.state.type->getSizeBytes());
 }
 
 void Allocation::freeScriptMemory() {
-    if (mPtr) {
-        free(mPtr);
-        mPtr = NULL;
+    if (mHal.state.mallocPtr) {
+        free(mHal.state.mallocPtr);
+        mHal.state.mallocPtr = NULL;
     }
 }
 
@@ -153,21 +165,24 @@
     if (getIsBufferObject()) {
         uploadToBufferObject(rsc);
     }
+    if (getIsRenderTarget() && !getIsTexture()) {
+        allocateRenderTarget(rsc);
+    }
 
-    mUploadDefered = false;
+    mUploadDeferred = false;
 }
 
 void Allocation::uploadToTexture(const Context *rsc) {
-
-    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
-    GLenum type = mType->getElement()->getComponent().getGLType();
-    GLenum format = mType->getElement()->getComponent().getGLFormat();
+#ifndef ANDROID_RS_SERIALIZE
+    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
+    GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
+    GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
 
     if (!type || !format) {
         return;
     }
 
-    if (!mPtr) {
+    if (!mHal.state.mallocPtr) {
         return;
     }
 
@@ -182,7 +197,7 @@
             // Force a crash to 1: restart the app, 2: make sure we get a bugreport.
             LOGE("Upload to texture failed to gen mTextureID");
             rsc->dumpDebug();
-            mUploadDefered = true;
+            mUploadDeferred = true;
             return;
         }
         isFirstUpload = true;
@@ -190,13 +205,41 @@
 
     upload2DTexture(isFirstUpload);
 
-    if (!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
+    if (!(mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
         freeScriptMemory();
     }
 
-    rsc->checkError("Allocation::uploadToTexture");
+    //rsc->checkError("Allocation::uploadToTexture");
+#endif //ANDROID_RS_SERIALIZE
 }
 
+void Allocation::allocateRenderTarget(const Context *rsc) {
+#ifndef ANDROID_RS_SERIALIZE
+    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET;
+
+    GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
+    if (!format) {
+        return;
+    }
+
+    if (!mRenderTargetID) {
+        glGenRenderbuffers(1, &mRenderTargetID);
+
+        if (!mRenderTargetID) {
+            // This should generally not happen
+            LOGE("allocateRenderTarget failed to gen mRenderTargetID");
+            rsc->dumpDebug();
+            return;
+        }
+        glBindRenderbuffer(GL_RENDERBUFFER, mRenderTargetID);
+        glRenderbufferStorage(GL_RENDERBUFFER, format,
+                              mHal.state.type->getDimX(),
+                              mHal.state.type->getDimY());
+    }
+#endif //ANDROID_RS_SERIALIZE
+}
+
+#ifndef ANDROID_RS_SERIALIZE
 const static GLenum gFaceOrder[] = {
     GL_TEXTURE_CUBE_MAP_POSITIVE_X,
     GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
@@ -205,129 +248,134 @@
     GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
     GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
 };
+#endif //ANDROID_RS_SERIALIZE
 
 void Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
                                  uint32_t lod, RsAllocationCubemapFace face,
                                  uint32_t w, uint32_t h) {
-    GLenum type = mType->getElement()->getComponent().getGLType();
-    GLenum format = mType->getElement()->getComponent().getGLFormat();
+#ifndef ANDROID_RS_SERIALIZE
+    GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
+    GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
     GLenum target = (GLenum)getGLTarget();
     rsAssert(mTextureID);
     glBindTexture(target, mTextureID);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     GLenum t = GL_TEXTURE_2D;
-    if (mType->getDimFaces()) {
+    if (mHal.state.hasFaces) {
         t = gFaceOrder[face];
     }
     glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr);
+#endif //ANDROID_RS_SERIALIZE
 }
 
 void Allocation::upload2DTexture(bool isFirstUpload) {
-    GLenum type = mType->getElement()->getComponent().getGLType();
-    GLenum format = mType->getElement()->getComponent().getGLFormat();
+#ifndef ANDROID_RS_SERIALIZE
+    GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
+    GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
 
     GLenum target = (GLenum)getGLTarget();
     glBindTexture(target, mTextureID);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
     uint32_t faceCount = 1;
-    if (mType->getDimFaces()) {
+    if (mHal.state.hasFaces) {
         faceCount = 6;
     }
 
     for (uint32_t face = 0; face < faceCount; face ++) {
-        for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
-            const uint8_t *p = (const uint8_t *)mPtr;
-            p += mType->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
+        for (uint32_t lod = 0; lod < mHal.state.type->getLODCount(); lod++) {
+            const uint8_t *p = (const uint8_t *)mHal.state.mallocPtr;
+            p += mHal.state.type->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
 
             GLenum t = GL_TEXTURE_2D;
-            if (mType->getDimFaces()) {
+            if (mHal.state.hasFaces) {
                 t = gFaceOrder[face];
             }
 
             if (isFirstUpload) {
                 glTexImage2D(t, lod, format,
-                             mType->getLODDimX(lod), mType->getLODDimY(lod),
+                             mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod),
                              0, format, type, p);
             } else {
                 glTexSubImage2D(t, lod, 0, 0,
-                                mType->getLODDimX(lod), mType->getLODDimY(lod),
+                                mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod),
                                 format, type, p);
             }
         }
     }
 
-    if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
-#ifndef ANDROID_RS_BUILD_FOR_HOST
+    if (mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
         glGenerateMipmap(target);
-#endif //ANDROID_RS_BUILD_FOR_HOST
     }
+#endif //ANDROID_RS_SERIALIZE
 }
 
-void Allocation::deferedUploadToBufferObject(const Context *rsc) {
-    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
-    mUploadDefered = true;
+void Allocation::deferredUploadToBufferObject(const Context *rsc) {
+    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
+    mUploadDeferred = true;
 }
 
 void Allocation::uploadToBufferObject(const Context *rsc) {
-    rsAssert(!mType->getDimY());
-    rsAssert(!mType->getDimZ());
+#ifndef ANDROID_RS_SERIALIZE
+    rsAssert(!mHal.state.type->getDimY());
+    rsAssert(!mHal.state.type->getDimZ());
 
-    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
+    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
 
     if (!mBufferID) {
         glGenBuffers(1, &mBufferID);
     }
     if (!mBufferID) {
         LOGE("Upload to buffer object failed");
-        mUploadDefered = true;
+        mUploadDeferred = true;
         return;
     }
     GLenum target = (GLenum)getGLTarget();
     glBindBuffer(target, mBufferID);
-    glBufferData(target, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
+    glBufferData(target, mHal.state.type->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
     glBindBuffer(target, 0);
-    rsc->checkError("Allocation::uploadToBufferObject");
+    //rsc->checkError("Allocation::uploadToBufferObject");
+#endif //ANDROID_RS_SERIALIZE
 }
 
 void Allocation::uploadCheck(Context *rsc) {
-    if (mUploadDefered) {
+    if (mUploadDeferred) {
         syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
     }
 }
 
 void Allocation::read(void *data) {
-    memcpy(data, mPtr, mType->getSizeBytes());
+    memcpy(data, mHal.state.mallocPtr, mHal.state.type->getSizeBytes());
 }
 
 void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
                          uint32_t count, const void *data, uint32_t sizeBytes) {
-    uint32_t eSize = mType->getElementSizeBytes();
-    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
+    uint32_t eSize = mHal.state.type->getElementSizeBytes();
+    uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
     ptr += eSize * xoff;
     uint32_t size = count * eSize;
 
     if (size != sizeBytes) {
         LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
-        mType->dumpLOGV("type info");
+        mHal.state.type->dumpLOGV("type info");
         return;
     }
 
-    if (mType->getElement()->getHasReferences()) {
+    if (mHal.state.hasReferences) {
         incRefs(data, count);
         decRefs(ptr, count);
     }
 
     memcpy(ptr, data, size);
     sendDirty();
-    mUploadDefered = true;
+    mUploadDeferred = true;
 }
 
 void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
              uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
-    uint32_t eSize = mType->getElementSizeBytes();
+    uint32_t eSize = mHal.state.elementSizeBytes;
     uint32_t lineSize = eSize * w;
-    uint32_t destW = mType->getDimX();
+    uint32_t destW = mHal.state.dimensionX;
 
     //LOGE("data2d %p,  %i %i %i %i %i %i %p %i", this, xoff, yoff, lod, face, w, h, data, sizeBytes);
 
@@ -337,14 +385,14 @@
         return;
     }
 
-    if (mPtr) {
+    if (mHal.state.mallocPtr) {
         const uint8_t *src = static_cast<const uint8_t *>(data);
-        uint8_t *dst = static_cast<uint8_t *>(mPtr);
-        dst += mType->getLODFaceOffset(lod, face, xoff, yoff);
+        uint8_t *dst = static_cast<uint8_t *>(mHal.state.mallocPtr);
+        dst += mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff);
 
         //LOGE("            %p  %p  %i  ", dst, src, eSize);
         for (uint32_t line=yoff; line < (yoff+h); line++) {
-            if (mType->getElement()->getHasReferences()) {
+            if (mHal.state.hasReferences) {
                 incRefs(src, w);
                 decRefs(dst, w);
             }
@@ -353,7 +401,7 @@
             dst += destW * eSize;
         }
         sendDirty();
-        mUploadDefered = true;
+        mUploadDeferred = true;
     } else {
         update2DTexture(data, xoff, yoff, lod, face, w, h);
     }
@@ -366,27 +414,27 @@
 
 void Allocation::elementData(Context *rsc, uint32_t x, const void *data,
                                 uint32_t cIdx, uint32_t sizeBytes) {
-    uint32_t eSize = mType->getElementSizeBytes();
-    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
+    uint32_t eSize = mHal.state.elementSizeBytes;
+    uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
     ptr += eSize * x;
 
-    if (cIdx >= mType->getElement()->getFieldCount()) {
+    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
         LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
         rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
         return;
     }
 
-    if (x >= mType->getDimX()) {
+    if (x >= mHal.state.dimensionX) {
         LOGE("Error Allocation::subElementData X offset %i out of range.", x);
         rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
         return;
     }
 
-    const Element * e = mType->getElement()->getField(cIdx);
-    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
+    const Element * e = mHal.state.type->getElement()->getField(cIdx);
+    ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
 
     if (sizeBytes != e->getSizeBytes()) {
-        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
+        LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
         rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
         return;
     }
@@ -398,38 +446,38 @@
 
     memcpy(ptr, data, sizeBytes);
     sendDirty();
-    mUploadDefered = true;
+    mUploadDeferred = true;
 }
 
 void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
                                 const void *data, uint32_t cIdx, uint32_t sizeBytes) {
-    uint32_t eSize = mType->getElementSizeBytes();
-    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
-    ptr += eSize * (x + y * mType->getDimX());
+    uint32_t eSize = mHal.state.elementSizeBytes;
+    uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
+    ptr += eSize * (x + y * mHal.state.dimensionX);
 
-    if (x >= mType->getDimX()) {
+    if (x >= mHal.state.dimensionX) {
         LOGE("Error Allocation::subElementData X offset %i out of range.", x);
         rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
         return;
     }
 
-    if (y >= mType->getDimY()) {
+    if (y >= mHal.state.dimensionY) {
         LOGE("Error Allocation::subElementData X offset %i out of range.", x);
         rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
         return;
     }
 
-    if (cIdx >= mType->getElement()->getFieldCount()) {
+    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
         LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
         rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
         return;
     }
 
-    const Element * e = mType->getElement()->getField(cIdx);
-    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
+    const Element * e = mHal.state.type->getElement()->getField(cIdx);
+    ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
 
     if (sizeBytes != e->getSizeBytes()) {
-        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
+        LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
         rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
         return;
     }
@@ -441,14 +489,17 @@
 
     memcpy(ptr, data, sizeBytes);
     sendDirty();
-    mUploadDefered = true;
+    mUploadDeferred = true;
 }
 
 void Allocation::addProgramToDirty(const Program *p) {
+#ifndef ANDROID_RS_SERIALIZE
     mToDirtyList.push(p);
+#endif //ANDROID_RS_SERIALIZE
 }
 
 void Allocation::removeProgramToDirty(const Program *p) {
+#ifndef ANDROID_RS_SERIALIZE
     for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
         if (mToDirtyList[ct] == p) {
             mToDirtyList.removeAt(ct);
@@ -456,6 +507,7 @@
         }
     }
     rsAssert(0);
+#endif //ANDROID_RS_SERIALIZE
 }
 
 void Allocation::dumpLOGV(const char *prefix) const {
@@ -463,15 +515,15 @@
 
     String8 s(prefix);
     s.append(" type ");
-    if (mType.get()) {
-        mType->dumpLOGV(s.string());
+    if (mHal.state.type.get()) {
+        mHal.state.type->dumpLOGV(s.string());
     }
 
     LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
-          prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
+          prefix, mHal.state.mallocPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
 
     LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i",
-          prefix, mUsageFlags, mMipmapControl, mTextureID, mBufferID);
+          prefix, mHal.state.usageFlags, mHal.state.mipmapControl, mTextureID, mBufferID);
 }
 
 void Allocation::serialize(OStream *stream) const {
@@ -483,13 +535,13 @@
 
     // First thing we need to serialize is the type object since it will be needed
     // to initialize the class
-    mType->serialize(stream);
+    mHal.state.type->serialize(stream);
 
-    uint32_t dataSize = mType->getSizeBytes();
+    uint32_t dataSize = mHal.state.type->getSizeBytes();
     // Write how much data we are storing
     stream->addU32(dataSize);
     // Now write the data
-    stream->addByteArray(mPtr, dataSize);
+    stream->addByteArray(mHal.state.mallocPtr, dataSize);
 }
 
 Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
@@ -530,14 +582,16 @@
 }
 
 void Allocation::sendDirty() const {
+#ifndef ANDROID_RS_SERIALIZE
     for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
         mToDirtyList[ct]->forceDirty();
     }
+#endif //ANDROID_RS_SERIALIZE
 }
 
 void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
     const uint8_t *p = static_cast<const uint8_t *>(ptr);
-    const Element *e = mType->getElement();
+    const Element *e = mHal.state.type->getElement();
     uint32_t stride = e->getSizeBytes();
 
     p += stride * startOff;
@@ -550,7 +604,7 @@
 
 void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
     const uint8_t *p = static_cast<const uint8_t *>(ptr);
-    const Element *e = mType->getElement();
+    const Element *e = mHal.state.type->getElement();
     uint32_t stride = e->getSizeBytes();
 
     p += stride * startOff;
@@ -565,24 +619,26 @@
 }
 
 void Allocation::resize1D(Context *rsc, uint32_t dimX) {
-    Type *t = mType->cloneAndResize1D(rsc, dimX);
+    Type *t = mHal.state.type->cloneAndResize1D(rsc, dimX);
 
-    uint32_t oldDimX = mType->getDimX();
+    uint32_t oldDimX = mHal.state.dimensionX;
     if (dimX == oldDimX) {
         return;
     }
 
     if (dimX < oldDimX) {
-        decRefs(mPtr, oldDimX - dimX, dimX);
+        decRefs(mHal.state.mallocPtr, oldDimX - dimX, dimX);
     }
-    mPtr = realloc(mPtr, t->getSizeBytes());
+    mHal.state.mallocPtr = realloc(mHal.state.mallocPtr, t->getSizeBytes());
 
     if (dimX > oldDimX) {
-        const Element *e = mType->getElement();
+        const Element *e = mHal.state.type->getElement();
         uint32_t stride = e->getSizeBytes();
-        memset(((uint8_t *)mPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
+        memset(((uint8_t *)mHal.state.mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
     }
-    mType.set(t);
+
+    mHal.state.type.set(t);
+    updateCache();
 }
 
 void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
@@ -591,19 +647,22 @@
 
 /////////////////
 //
+#ifndef ANDROID_RS_SERIALIZE
 
 
 namespace android {
 namespace renderscript {
 
+static void AllocationGenerateScriptMips(RsContext con, RsAllocation va);
+
 void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
     Allocation *alloc = static_cast<Allocation *>(va);
-    alloc->deferedUploadToTexture(rsc);
+    alloc->deferredUploadToTexture(rsc);
 }
 
 void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
     Allocation *alloc = static_cast<Allocation *>(va);
-    alloc->deferedUploadToBufferObject(rsc);
+    alloc->deferredUploadToBufferObject(rsc);
 }
 
 static void mip565(const Adapter2D &out, const Adapter2D &in) {
@@ -674,8 +733,6 @@
     }
 }
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
-
 void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
     Allocation *a = static_cast<Allocation *>(va);
     a->syncAll(rsc, src);
@@ -684,7 +741,7 @@
 
 void rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) {
     Allocation *texAlloc = static_cast<Allocation *>(va);
-    rsaAllocationGenerateScriptMips(rsc, texAlloc);
+    AllocationGenerateScriptMips(rsc, texAlloc);
 }
 
 void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
@@ -724,7 +781,7 @@
     a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes);
 }
 
-void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) {
+void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t data_length) {
     Allocation *a = static_cast<Allocation *>(va);
     a->read(data);
 }
@@ -739,12 +796,7 @@
     a->resize2D(rsc, dimX, dimY);
 }
 
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
-}
-}
-
-static void rsaAllocationGenerateScriptMips(RsContext con, RsAllocation va) {
+static void AllocationGenerateScriptMips(RsContext con, RsAllocation va) {
     Context *rsc = static_cast<Context *>(con);
     Allocation *texAlloc = static_cast<Allocation *>(va);
     uint32_t numFaces = texAlloc->getType()->getDimFaces() ? 6 : 1;
@@ -761,30 +813,20 @@
     }
 }
 
-const void * rsaAllocationGetType(RsContext con, RsAllocation va) {
-    Allocation *a = static_cast<Allocation *>(va);
-    a->getType()->incUserRef();
-
-    return a->getType();
-}
-
-RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype,
-                                      RsAllocationMipmapControl mips,
-                                      uint32_t usages) {
-    Context *rsc = static_cast<Context *>(con);
+RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype,
+                                       RsAllocationMipmapControl mips,
+                                       uint32_t usages) {
     Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages, mips);
     alloc->incUserRef();
     return alloc;
 }
 
-
-RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
-                                           RsAllocationMipmapControl mips,
-                                           const void *data, uint32_t usages) {
-    Context *rsc = static_cast<Context *>(con);
+RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype,
+                                            RsAllocationMipmapControl mips,
+                                            const void *data, size_t data_length, uint32_t usages) {
     Type *t = static_cast<Type *>(vtype);
 
-    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, vtype, mips, usages);
+    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
     Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
     if (texAlloc == NULL) {
         LOGE("Memory allocation failure");
@@ -793,23 +835,22 @@
 
     memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
     if (mips == RS_ALLOCATION_MIPMAP_FULL) {
-        rsaAllocationGenerateScriptMips(rsc, texAlloc);
+        AllocationGenerateScriptMips(rsc, texAlloc);
     }
 
-    texAlloc->deferedUploadToTexture(rsc);
+    texAlloc->deferredUploadToTexture(rsc);
     return texAlloc;
 }
 
-RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
-                                               RsAllocationMipmapControl mips,
-                                               const void *data, uint32_t usages) {
-    Context *rsc = static_cast<Context *>(con);
+RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype,
+                                                RsAllocationMipmapControl mips,
+                                                const void *data, size_t data_length, uint32_t usages) {
     Type *t = static_cast<Type *>(vtype);
 
     // Cubemap allocation's faces should be Width by Width each.
     // Source data should have 6 * Width by Width pixels
     // Error checking is done in the java layer
-    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, t, mips, usages);
+    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
     Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
     if (texAlloc == NULL) {
         LOGE("Memory allocation failure");
@@ -834,9 +875,21 @@
     }
 
     if (mips == RS_ALLOCATION_MIPMAP_FULL) {
-        rsaAllocationGenerateScriptMips(rsc, texAlloc);
+        AllocationGenerateScriptMips(rsc, texAlloc);
     }
 
-    texAlloc->deferedUploadToTexture(rsc);
+    texAlloc->deferredUploadToTexture(rsc);
     return texAlloc;
 }
+
+}
+}
+
+const void * rsaAllocationGetType(RsContext con, RsAllocation va) {
+    Allocation *a = static_cast<Allocation *>(va);
+    a->getType()->incUserRef();
+
+    return a->getType();
+}
+
+#endif //ANDROID_RS_SERIALIZE
diff --git a/rsAllocation.h b/rsAllocation.h
index 4f5d5a8..d334841 100644
--- a/rsAllocation.h
+++ b/rsAllocation.h
@@ -29,10 +29,35 @@
     // The graphics equilivent of malloc.  The allocation contains a structure of elements.
 
 public:
+    struct Hal {
+        void * drv;
+
+        struct State {
+            ObjectBaseRef<const Type> type;
+            void * mallocPtr;
+
+            uint32_t usageFlags;
+            RsAllocationMipmapControl mipmapControl;
+
+            // Cached fields from the Type and Element
+            // to prevent pointer chasing in critical loops.
+            uint32_t dimensionX;
+            uint32_t dimensionY;
+            uint32_t dimensionZ;
+            uint32_t elementSizeBytes;
+            bool hasMipmaps;
+            bool hasFaces;
+            bool hasReferences;
+        };
+        State state;
+    };
+    Hal mHal;
+
     Allocation(Context *rsc, const Type *, uint32_t usages,
                RsAllocationMipmapControl mc = RS_ALLOCATION_MIPMAP_NONE);
 
     virtual ~Allocation();
+    void updateCache();
 
     void setCpuWritable(bool);
     void setGpuWritable(bool);
@@ -41,18 +66,22 @@
 
     bool fixAllocation();
 
-    void * getPtr() const {return mPtr;}
-    const Type * getType() const {return mType.get();}
+    void * getPtr() const {return mHal.state.mallocPtr;}
+    const Type * getType() const {return mHal.state.type.get();}
 
     void syncAll(Context *rsc, RsAllocationUsageType src);
 
-    void deferedUploadToTexture(const Context *rsc);
+    void deferredUploadToTexture(const Context *rsc);
     void uploadToTexture(const Context *rsc);
     uint32_t getTextureID() const {return mTextureID;}
 
+    void deferredAllocateRenderTarget(const Context *rsc);
+    void allocateRenderTarget(const Context *rsc);
+    uint32_t getRenderTargetID() const {return mRenderTargetID;}
+
     uint32_t getGLTarget() const;
 
-    void deferedUploadToBufferObject(const Context *rsc);
+    void deferredUploadToBufferObject(const Context *rsc);
     void uploadToBufferObject(const Context *rsc);
     uint32_t getBufferObjectID() const {return mBufferID;}
 
@@ -88,13 +117,16 @@
     virtual void uploadCheck(Context *rsc);
 
     bool getIsScript() const {
-        return (mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT) != 0;
+        return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) != 0;
     }
     bool getIsTexture() const {
-        return (mUsageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) != 0;
+        return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) != 0;
+    }
+    bool getIsRenderTarget() const {
+        return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) != 0;
     }
     bool getIsBufferObject() const {
-        return (mUsageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) != 0;
+        return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) != 0;
     }
 
     void incRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
@@ -102,14 +134,11 @@
 
     void sendDirty() const;
     bool getHasGraphicsMipmaps() const {
-        return mMipmapControl != RS_ALLOCATION_MIPMAP_NONE;
+        return mHal.state.mipmapControl != RS_ALLOCATION_MIPMAP_NONE;
     }
 
 
 protected:
-    ObjectBaseRef<const Type> mType;
-    void * mPtr;
-
     Vector<const Program *> mToDirtyList;
 
     // Is we have a non-null user bitmap callback we do not own the bits and
@@ -123,9 +152,6 @@
     bool mGpuWrite;
     bool mGpuRead;
 
-    uint32_t mUsageFlags;
-    RsAllocationMipmapControl mMipmapControl;
-
     // more usage hint data from the application
     // which can be used by a driver to pick the best memory type.
     // Likely ignored for now
@@ -142,7 +168,10 @@
     // is allowed.
     uint32_t mBufferID;
 
-    bool mUploadDefered;
+    // Is this a legal structure to be used as an FBO render target
+    uint32_t mRenderTargetID;
+
+    bool mUploadDeferred;
 
 private:
     void init(Context *rsc, const Type *);
diff --git a/rsAnimation.cpp b/rsAnimation.cpp
index 6abda3c..48b4f02 100644
--- a/rsAnimation.cpp
+++ b/rsAnimation.cpp
@@ -14,12 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#else
-#include "rsContextHostStub.h"
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
 #include "rsAnimation.h"
 
 
diff --git a/rsComponent.cpp b/rsComponent.cpp
index 81ade5d..e2ae043 100644
--- a/rsComponent.cpp
+++ b/rsComponent.cpp
@@ -16,10 +16,9 @@
 
 #include "rsComponent.h"
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
+#ifndef ANDROID_RS_SERIALIZE
 #include <GLES/gl.h>
-#else
-#include <OpenGL/gl.h>
+#include <GLES2/gl2.h>
 #endif
 
 using namespace android;
@@ -183,6 +182,7 @@
 }
 
 uint32_t Component::getGLType() const {
+#ifndef ANDROID_RS_SERIALIZE
     switch (mType) {
     case RS_TYPE_UNSIGNED_5_6_5:    return GL_UNSIGNED_SHORT_5_6_5;
     case RS_TYPE_UNSIGNED_5_5_5_1:  return GL_UNSIGNED_SHORT_5_5_5_1;
@@ -196,19 +196,22 @@
     case RS_TYPE_SIGNED_16:     return GL_SHORT;
     default:    break;
     }
-
+#endif //ANDROID_RS_SERIALIZE
     return 0;
 }
 
 uint32_t Component::getGLFormat() const {
+#ifndef ANDROID_RS_SERIALIZE
     switch (mKind) {
     case RS_KIND_PIXEL_L: return GL_LUMINANCE;
     case RS_KIND_PIXEL_A: return GL_ALPHA;
     case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
     case RS_KIND_PIXEL_RGB: return GL_RGB;
     case RS_KIND_PIXEL_RGBA: return GL_RGBA;
+    case RS_KIND_PIXEL_DEPTH: return GL_DEPTH_COMPONENT16;
     default: break;
     }
+#endif //ANDROID_RS_SERIALIZE
     return 0;
 }
 
diff --git a/rsContext.cpp b/rsContext.cpp
index 1dfedb3..bab5c58 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -18,9 +18,6 @@
 #include "rsContext.h"
 #include "rsThreadIO.h"
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/PixelFormat.h>
-#include <ui/EGLUtils.h>
-#include <ui/egl/android_natives.h>
 
 #include <sys/types.h>
 #include <sys/resource.h>
@@ -28,11 +25,6 @@
 
 #include <cutils/properties.h>
 
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
 #include <cutils/sched_policy.h>
 #include <sys/syscall.h>
 #include <string.h>
@@ -40,249 +32,47 @@
 using namespace android;
 using namespace android::renderscript;
 
-pthread_key_t Context::gThreadTLSKey = 0;
-uint32_t Context::gThreadTLSKeyCount = 0;
-uint32_t Context::gGLContextCount = 0;
 pthread_mutex_t Context::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t Context::gLibMutex = PTHREAD_MUTEX_INITIALIZER;
 
-static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
-    if (returnVal != EGL_TRUE) {
-        fprintf(stderr, "%s() returned %d\n", op, returnVal);
-    }
-
-    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
-            = eglGetError()) {
-        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
-                error);
-    }
-}
-
-void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
-
-#define X(VAL) {VAL, #VAL}
-    struct {EGLint attribute; const char* name;} names[] = {
-    X(EGL_BUFFER_SIZE),
-    X(EGL_ALPHA_SIZE),
-    X(EGL_BLUE_SIZE),
-    X(EGL_GREEN_SIZE),
-    X(EGL_RED_SIZE),
-    X(EGL_DEPTH_SIZE),
-    X(EGL_STENCIL_SIZE),
-    X(EGL_CONFIG_CAVEAT),
-    X(EGL_CONFIG_ID),
-    X(EGL_LEVEL),
-    X(EGL_MAX_PBUFFER_HEIGHT),
-    X(EGL_MAX_PBUFFER_PIXELS),
-    X(EGL_MAX_PBUFFER_WIDTH),
-    X(EGL_NATIVE_RENDERABLE),
-    X(EGL_NATIVE_VISUAL_ID),
-    X(EGL_NATIVE_VISUAL_TYPE),
-    X(EGL_SAMPLES),
-    X(EGL_SAMPLE_BUFFERS),
-    X(EGL_SURFACE_TYPE),
-    X(EGL_TRANSPARENT_TYPE),
-    X(EGL_TRANSPARENT_RED_VALUE),
-    X(EGL_TRANSPARENT_GREEN_VALUE),
-    X(EGL_TRANSPARENT_BLUE_VALUE),
-    X(EGL_BIND_TO_TEXTURE_RGB),
-    X(EGL_BIND_TO_TEXTURE_RGBA),
-    X(EGL_MIN_SWAP_INTERVAL),
-    X(EGL_MAX_SWAP_INTERVAL),
-    X(EGL_LUMINANCE_SIZE),
-    X(EGL_ALPHA_MASK_SIZE),
-    X(EGL_COLOR_BUFFER_TYPE),
-    X(EGL_RENDERABLE_TYPE),
-    X(EGL_CONFORMANT),
-   };
-#undef X
-
-    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
-        EGLint value = -1;
-        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
-        EGLint error = eglGetError();
-        if (returnVal && error == EGL_SUCCESS) {
-            LOGV(" %s: %d (0x%x)", names[j].name, value, value);
-        }
-    }
-}
-
-
 bool Context::initGLThread() {
     pthread_mutex_lock(&gInitMutex);
     LOGV("initGLThread start %p", this);
 
-    mEGL.mNumConfigs = -1;
-    EGLint configAttribs[128];
-    EGLint *configAttribsPtr = configAttribs;
-    EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
-
-    memset(configAttribs, 0, sizeof(configAttribs));
-
-    configAttribsPtr[0] = EGL_SURFACE_TYPE;
-    configAttribsPtr[1] = EGL_WINDOW_BIT;
-    configAttribsPtr += 2;
-
-    configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
-    configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
-    configAttribsPtr += 2;
-
-    if (mUserSurfaceConfig.depthMin > 0) {
-        configAttribsPtr[0] = EGL_DEPTH_SIZE;
-        configAttribsPtr[1] = mUserSurfaceConfig.depthMin;
-        configAttribsPtr += 2;
-    }
-
-    if (mDev->mForceSW) {
-        configAttribsPtr[0] = EGL_CONFIG_CAVEAT;
-        configAttribsPtr[1] = EGL_SLOW_CONFIG;
-        configAttribsPtr += 2;
-    }
-
-    configAttribsPtr[0] = EGL_NONE;
-    rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint))));
-
-    LOGV("%p initEGL start", this);
-    mEGL.mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    checkEglError("eglGetDisplay");
-
-    eglInitialize(mEGL.mDisplay, &mEGL.mMajorVersion, &mEGL.mMinorVersion);
-    checkEglError("eglInitialize");
-
-#if 1
-    PixelFormat pf = PIXEL_FORMAT_RGBA_8888;
-    if (mUserSurfaceConfig.alphaMin == 0) {
-        pf = PIXEL_FORMAT_RGBX_8888;
-    }
-
-    status_t err = EGLUtils::selectConfigForPixelFormat(mEGL.mDisplay, configAttribs, pf, &mEGL.mConfig);
-    if (err) {
-       LOGE("%p, couldn't find an EGLConfig matching the screen format\n", this);
-    }
-    if (props.mLogVisual) {
-        printEGLConfiguration(mEGL.mDisplay, mEGL.mConfig);
-    }
-#else
-    eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs);
-#endif
-
-    mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, context_attribs2);
-    checkEglError("eglCreateContext");
-    if (mEGL.mContext == EGL_NO_CONTEXT) {
+    if (!mHal.funcs.initGraphics(this)) {
         pthread_mutex_unlock(&gInitMutex);
-        LOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", this);
-        return false;
-    }
-    gGLContextCount++;
-
-
-    EGLint pbuffer_attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
-    mEGL.mSurfaceDefault = eglCreatePbufferSurface(mEGL.mDisplay, mEGL.mConfig, pbuffer_attribs);
-    checkEglError("eglCreatePbufferSurface");
-    if (mEGL.mSurfaceDefault == EGL_NO_SURFACE) {
-        LOGE("eglCreatePbufferSurface returned EGL_NO_SURFACE");
-        pthread_mutex_unlock(&gInitMutex);
-        deinitEGL();
+        LOGE("%p, initGraphics failed", this);
         return false;
     }
 
-    EGLBoolean ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurfaceDefault, mEGL.mSurfaceDefault, mEGL.mContext);
-    if (ret == EGL_FALSE) {
-        LOGE("eglMakeCurrent returned EGL_FALSE");
-        checkEglError("eglMakeCurrent", ret);
-        pthread_mutex_unlock(&gInitMutex);
-        deinitEGL();
-        return false;
-    }
-
-    mGL.mVersion = glGetString(GL_VERSION);
-    mGL.mVendor = glGetString(GL_VENDOR);
-    mGL.mRenderer = glGetString(GL_RENDERER);
-    mGL.mExtensions = glGetString(GL_EXTENSIONS);
-
-    //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
-    //LOGV("GL Version %s", mGL.mVersion);
-    //LOGV("GL Vendor %s", mGL.mVendor);
-    //LOGV("GL Renderer %s", mGL.mRenderer);
-    //LOGV("GL Extensions %s", mGL.mExtensions);
-
-    const char *verptr = NULL;
-    if (strlen((const char *)mGL.mVersion) > 9) {
-        if (!memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) {
-            verptr = (const char *)mGL.mVersion + 12;
-        }
-        if (!memcmp(mGL.mVersion, "OpenGL ES ", 10)) {
-            verptr = (const char *)mGL.mVersion + 9;
-        }
-    }
-
-    if (!verptr) {
-        LOGE("Error, OpenGL ES Lite not supported");
-        pthread_mutex_unlock(&gInitMutex);
-        deinitEGL();
-        return false;
-    } else {
-        sscanf(verptr, " %i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion);
-    }
-
-    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mGL.mMaxVertexAttribs);
-    glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &mGL.mMaxVertexUniformVectors);
-    glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGL.mMaxVertexTextureUnits);
-
-    glGetIntegerv(GL_MAX_VARYING_VECTORS, &mGL.mMaxVaryingVectors);
-    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGL.mMaxTextureImageUnits);
-
-    glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mGL.mMaxFragmentTextureImageUnits);
-    glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGL.mMaxFragmentUniformVectors);
-
-    mGL.OES_texture_npot = NULL != strstr((const char *)mGL.mExtensions, "GL_OES_texture_npot");
-    mGL.GL_IMG_texture_npot = NULL != strstr((const char *)mGL.mExtensions, "GL_IMG_texture_npot");
-    mGL.GL_NV_texture_npot_2D_mipmap = NULL != strstr((const char *)mGL.mExtensions, "GL_NV_texture_npot_2D_mipmap");
-    mGL.EXT_texture_max_aniso = 1.0f;
-    bool hasAniso = NULL != strstr((const char *)mGL.mExtensions, "GL_EXT_texture_filter_anisotropic");
-    if (hasAniso) {
-        glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &mGL.EXT_texture_max_aniso);
-    }
-
-    LOGV("initGLThread end %p", this);
     pthread_mutex_unlock(&gInitMutex);
     return true;
 }
 
 void Context::deinitEGL() {
     LOGV("%p, deinitEGL", this);
-
-    if (mEGL.mContext != EGL_NO_CONTEXT) {
-        eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-        eglDestroySurface(mEGL.mDisplay, mEGL.mSurfaceDefault);
-        if (mEGL.mSurface != EGL_NO_SURFACE) {
-            eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
-        }
-        eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
-        checkEglError("eglDestroyContext");
-    }
-
-    gGLContextCount--;
-    if (!gGLContextCount) {
-        eglTerminate(mEGL.mDisplay);
-    }
+    mHal.funcs.shutdownGraphics(this);
 }
 
 Context::PushState::PushState(Context *con) {
     mRsc = con;
-    mFragment.set(con->getProgramFragment());
-    mVertex.set(con->getProgramVertex());
-    mStore.set(con->getProgramStore());
-    mRaster.set(con->getProgramRaster());
-    mFont.set(con->getFont());
+    if (con->mIsGraphicsContext) {
+        mFragment.set(con->getProgramFragment());
+        mVertex.set(con->getProgramVertex());
+        mStore.set(con->getProgramStore());
+        mRaster.set(con->getProgramRaster());
+        mFont.set(con->getFont());
+    }
 }
 
 Context::PushState::~PushState() {
-    mRsc->setProgramFragment(mFragment.get());
-    mRsc->setProgramVertex(mVertex.get());
-    mRsc->setProgramStore(mStore.get());
-    mRsc->setProgramRaster(mRaster.get());
-    mRsc->setFont(mFont.get());
+    if (mRsc->mIsGraphicsContext) {
+        mRsc->setProgramFragment(mFragment.get());
+        mRsc->setProgramVertex(mVertex.get());
+        mRsc->setProgramStore(mStore.get());
+        mRsc->setProgramRaster(mRaster.get());
+        mRsc->setFont(mFont.get());
+    }
 }
 
 
@@ -293,38 +83,11 @@
     return ret;
 }
 
-void Context::checkError(const char *msg, bool isFatal) const {
-
-    GLenum err = glGetError();
-    if (err != GL_NO_ERROR) {
-        char buf[1024];
-        snprintf(buf, sizeof(buf), "GL Error = 0x%08x, from: %s", err, msg);
-
-        if (isFatal) {
-            setError(RS_ERROR_FATAL_DRIVER, buf);
-        } else {
-            switch (err) {
-            case GL_OUT_OF_MEMORY:
-                setError(RS_ERROR_OUT_OF_MEMORY, buf);
-                break;
-            default:
-                setError(RS_ERROR_DRIVER, buf);
-                break;
-            }
-        }
-
-        LOGE("%p, %s", this, buf);
-    }
-}
-
 uint32_t Context::runRootScript() {
-    glViewport(0, 0, mWidth, mHeight);
-
     timerSet(RS_TIMER_SCRIPT);
     mStateFragmentStore.mLast.clear();
     uint32_t ret = runScript(mRootScript.get());
 
-    checkError("runRootScript");
     return ret;
 }
 
@@ -396,20 +159,17 @@
 }
 
 bool Context::setupCheck() {
-    if (!mShaderCache.lookup(this, mVertex.get(), mFragment.get())) {
-        LOGE("Context::setupCheck() 1 fail");
-        return false;
-    }
 
-    mFragmentStore->setupGL2(this, &mStateFragmentStore);
-    mFragment->setupGL2(this, &mStateFragment, &mShaderCache);
-    mRaster->setupGL2(this, &mStateRaster);
-    mVertex->setupGL2(this, &mStateVertex, &mShaderCache);
+    mFragmentStore->setup(this, &mStateFragmentStore);
+    mFragment->setup(this, &mStateFragment);
+    mRaster->setup(this, &mStateRaster);
+    mVertex->setup(this, &mStateVertex);
+    mFBOCache.setup(this);
     return true;
 }
 
 void Context::setupProgramStore() {
-    mFragmentStore->setupGL2(this, &mStateFragmentStore);
+    mFragmentStore->setup(this, &mStateFragmentStore);
 }
 
 static bool getProp(const char *str) {
@@ -425,6 +185,8 @@
     mStateFont.getFontColor(&oldR, &oldG, &oldB, &oldA);
     uint32_t bufferLen = strlen(buffer);
 
+    ObjectBaseRef<Font> lastFont(getFont());
+    setFont(NULL);
     float shadowCol = 0.1f;
     mStateFont.setFontColor(shadowCol, shadowCol, shadowCol, 1.0f);
     mStateFont.renderText(buffer, bufferLen, 5, getHeight() - 6);
@@ -432,98 +194,92 @@
     mStateFont.setFontColor(1.0f, 0.7f, 0.0f, 1.0f);
     mStateFont.renderText(buffer, bufferLen, 4, getHeight() - 7);
 
+    setFont(lastFont.get());
     mStateFont.setFontColor(oldR, oldG, oldB, oldA);
 }
 
 void * Context::threadProc(void *vrsc) {
-     Context *rsc = static_cast<Context *>(vrsc);
-     rsc->mNativeThreadId = gettid();
+    Context *rsc = static_cast<Context *>(vrsc);
+    rsc->mNativeThreadId = gettid();
 
-     setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
-     rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
+    setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
+    rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
 
-     rsc->props.mLogTimes = getProp("debug.rs.profile");
-     rsc->props.mLogScripts = getProp("debug.rs.script");
-     rsc->props.mLogObjects = getProp("debug.rs.object");
-     rsc->props.mLogShaders = getProp("debug.rs.shader");
-     rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes");
-     rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms");
-     rsc->props.mLogVisual = getProp("debug.rs.visual");
+    rsc->props.mLogTimes = getProp("debug.rs.profile");
+    rsc->props.mLogScripts = getProp("debug.rs.script");
+    rsc->props.mLogObjects = getProp("debug.rs.object");
+    rsc->props.mLogShaders = getProp("debug.rs.shader");
+    rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes");
+    rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms");
+    rsc->props.mLogVisual = getProp("debug.rs.visual");
 
-     rsc->mTlsStruct = new ScriptTLSStruct;
-     if (!rsc->mTlsStruct) {
-         LOGE("Error allocating tls storage");
-         rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed allocation for TLS");
-         return NULL;
-     }
-     rsc->mTlsStruct->mContext = rsc;
-     rsc->mTlsStruct->mScript = NULL;
-     int status = pthread_setspecific(rsc->gThreadTLSKey, rsc->mTlsStruct);
-     if (status) {
-         LOGE("pthread_setspecific %i", status);
-     }
+    if (!rsdHalInit(rsc, 0, 0)) {
+        rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed initializing GL");
+        LOGE("Hal init failed");
+        return NULL;
+    }
+    rsc->mHal.funcs.setPriority(rsc, rsc->mThreadPriority);
 
-     if (!rsc->initGLThread()) {
-         rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed initializing GL");
-         return NULL;
-     }
+    if (rsc->mIsGraphicsContext) {
+        if (!rsc->initGLThread()) {
+            rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed initializing GL");
+            return NULL;
+        }
 
-     if (rsc->mIsGraphicsContext) {
-         rsc->mStateRaster.init(rsc);
-         rsc->setProgramRaster(NULL);
-         rsc->mStateVertex.init(rsc);
-         rsc->setProgramVertex(NULL);
-         rsc->mStateFragment.init(rsc);
-         rsc->setProgramFragment(NULL);
-         rsc->mStateFragmentStore.init(rsc);
-         rsc->setProgramStore(NULL);
-         rsc->mStateFont.init(rsc);
-         rsc->setFont(NULL);
-         rsc->mStateVertexArray.init(rsc);
-     }
+        rsc->mStateRaster.init(rsc);
+        rsc->setProgramRaster(NULL);
+        rsc->mStateVertex.init(rsc);
+        rsc->setProgramVertex(NULL);
+        rsc->mStateFragment.init(rsc);
+        rsc->setProgramFragment(NULL);
+        rsc->mStateFragmentStore.init(rsc);
+        rsc->setProgramStore(NULL);
+        rsc->mStateFont.init(rsc);
+        rsc->setFont(NULL);
+        rsc->mFBOCache.init(rsc);
+    }
 
-     rsc->mRunning = true;
-     bool mDraw = true;
-     while (!rsc->mExit) {
-         mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
-         mDraw &= (rsc->mRootScript.get() != NULL);
-         mDraw &= (rsc->mWndSurface != NULL);
+    rsc->mRunning = true;
+    bool mDraw = true;
+    while (!rsc->mExit) {
+        mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
+        mDraw &= (rsc->mRootScript.get() != NULL);
+        mDraw &= rsc->mHasSurface;
 
-         uint32_t targetTime = 0;
-         if (mDraw && rsc->mIsGraphicsContext) {
-             targetTime = rsc->runRootScript();
+        uint32_t targetTime = 0;
+        if (mDraw && rsc->mIsGraphicsContext) {
+            targetTime = rsc->runRootScript();
 
-             if (rsc->props.mLogVisual) {
-                 rsc->displayDebugStats();
-             }
+            if (rsc->props.mLogVisual) {
+                rsc->displayDebugStats();
+            }
 
-             mDraw = targetTime && !rsc->mPaused;
-             rsc->timerSet(RS_TIMER_CLEAR_SWAP);
-             eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
-             rsc->timerFrame();
-             rsc->timerSet(RS_TIMER_INTERNAL);
-             rsc->timerPrint();
-             rsc->timerReset();
-         }
-         if (targetTime > 1) {
-             int32_t t = (targetTime - (int32_t)(rsc->mTimeMSLastScript + rsc->mTimeMSLastSwap)) * 1000;
-             if (t > 0) {
-                 usleep(t);
-             }
-         }
-     }
+            mDraw = targetTime && !rsc->mPaused;
+            rsc->timerSet(RS_TIMER_CLEAR_SWAP);
+            rsc->mHal.funcs.swap(rsc);
+            rsc->timerFrame();
+            rsc->timerSet(RS_TIMER_INTERNAL);
+            rsc->timerPrint();
+            rsc->timerReset();
+        }
+        if (targetTime > 1) {
+            int32_t t = (targetTime - (int32_t)(rsc->mTimeMSLastScript + rsc->mTimeMSLastSwap)) * 1000;
+            if (t > 0) {
+                usleep(t);
+            }
+        }
+    }
 
-     LOGV("%p, RS Thread exiting", rsc);
+    LOGV("%p, RS Thread exiting", rsc);
 
-     if (rsc->mIsGraphicsContext) {
-         pthread_mutex_lock(&gInitMutex);
-         rsc->deinitEGL();
-         pthread_mutex_unlock(&gInitMutex);
-     }
-     delete rsc->mTlsStruct;
+    if (rsc->mIsGraphicsContext) {
+        pthread_mutex_lock(&gInitMutex);
+        rsc->deinitEGL();
+        pthread_mutex_unlock(&gInitMutex);
+    }
 
-     LOGV("%p, RS Thread exited", rsc);
-     return NULL;
+    LOGV("%p, RS Thread exited", rsc);
+    return NULL;
 }
 
 void Context::destroyWorkerThreadResources() {
@@ -541,62 +297,12 @@
          mStateFragment.deinit(this);
          mStateFragmentStore.deinit(this);
          mStateFont.deinit(this);
-         mShaderCache.cleanupAll();
+         mFBOCache.deinit(this);
     }
     //LOGV("destroyWorkerThreadResources 2");
     mExit = true;
 }
 
-void * Context::helperThreadProc(void *vrsc) {
-     Context *rsc = static_cast<Context *>(vrsc);
-     uint32_t idx = (uint32_t)android_atomic_inc(&rsc->mWorkers.mLaunchCount);
-
-     //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
-
-     rsc->mWorkers.mLaunchSignals[idx].init();
-     rsc->mWorkers.mNativeThreadId[idx] = gettid();
-
-#if 0
-     typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
-     cpu_set_t cpuset;
-     memset(&cpuset, 0, sizeof(cpuset));
-     cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
-     int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
-               sizeof(cpuset), &cpuset);
-     LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
-#endif
-
-     setpriority(PRIO_PROCESS, rsc->mWorkers.mNativeThreadId[idx], rsc->mThreadPriority);
-     int status = pthread_setspecific(rsc->gThreadTLSKey, rsc->mTlsStruct);
-     if (status) {
-         LOGE("pthread_setspecific %i", status);
-     }
-
-     while (!rsc->mExit) {
-         rsc->mWorkers.mLaunchSignals[idx].wait();
-         if (rsc->mWorkers.mLaunchCallback) {
-            rsc->mWorkers.mLaunchCallback(rsc->mWorkers.mLaunchData, idx);
-         }
-         android_atomic_dec(&rsc->mWorkers.mRunningCount);
-         rsc->mWorkers.mCompleteSignal.set();
-     }
-
-     //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
-     return NULL;
-}
-
-void Context::launchThreads(WorkerCallback_t cbk, void *data) {
-    mWorkers.mLaunchData = data;
-    mWorkers.mLaunchCallback = cbk;
-    mWorkers.mRunningCount = (int)mWorkers.mCount;
-    for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
-        mWorkers.mLaunchSignals[ct].set();
-    }
-    while (mWorkers.mRunningCount) {
-        mWorkers.mCompleteSignal.wait();
-    }
-}
-
 void Context::setPriority(int32_t p) {
     // Note: If we put this in the proper "background" policy
     // the wallpapers can become completly unresponsive at times.
@@ -613,9 +319,6 @@
     }
 #else
     setpriority(PRIO_PROCESS, mNativeThreadId, p);
-    for (uint32_t ct=0; ct < mWorkers.mCount; ct++) {
-        setpriority(PRIO_PROCESS, mWorkers.mNativeThreadId[ct], p);
-    }
 #endif
 }
 
@@ -626,6 +329,7 @@
     mPaused = false;
     mObjHead = NULL;
     mError = RS_ERROR_NONE;
+    mDPI = 96;
 }
 
 Context * Context::createContext(Device *dev, const RsSurfaceConfig *sc) {
@@ -640,6 +344,8 @@
 bool Context::initContext(Device *dev, const RsSurfaceConfig *sc) {
     pthread_mutex_lock(&gInitMutex);
 
+    mIO.init();
+
     dev->addContext(this);
     mDev = dev;
     if (sc) {
@@ -648,23 +354,11 @@
         memset(&mUserSurfaceConfig, 0, sizeof(mUserSurfaceConfig));
     }
 
-    memset(&mEGL, 0, sizeof(mEGL));
-    memset(&mGL, 0, sizeof(mGL));
     mIsGraphicsContext = sc != NULL;
 
     int status;
     pthread_attr_t threadAttr;
 
-    if (!gThreadTLSKeyCount) {
-        status = pthread_key_create(&gThreadTLSKey, NULL);
-        if (status) {
-            LOGE("Failed to init thread tls key.");
-            pthread_mutex_unlock(&gInitMutex);
-            return false;
-        }
-    }
-    gThreadTLSKeyCount++;
-
     pthread_mutex_unlock(&gInitMutex);
 
     // Global init done at this point.
@@ -675,20 +369,11 @@
         return false;
     }
 
-    mWndSurface = NULL;
+    mHasSurface = false;
 
     timerInit();
     timerSet(RS_TIMER_INTERNAL);
 
-    int cpu = sysconf(_SC_NPROCESSORS_ONLN);
-    LOGV("RS Launching thread(s), reported CPU count %i", cpu);
-    if (cpu < 2) cpu = 0;
-
-    mWorkers.mCount = (uint32_t)cpu;
-    mWorkers.mThreadId = (pthread_t *) calloc(mWorkers.mCount, sizeof(pthread_t));
-    mWorkers.mNativeThreadId = (pid_t *) calloc(mWorkers.mCount, sizeof(pid_t));
-    mWorkers.mLaunchSignals = new Signal[mWorkers.mCount];
-    mWorkers.mLaunchCallback = NULL;
     status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
     if (status) {
         LOGE("Failed to start rs context thread.");
@@ -699,20 +384,10 @@
     }
 
     if (mError != RS_ERROR_NONE) {
+        LOGE("Errors during thread init");
         return false;
     }
 
-    mWorkers.mCompleteSignal.init();
-    mWorkers.mRunningCount = 0;
-    mWorkers.mLaunchCount = 0;
-    for (uint32_t ct=0; ct < mWorkers.mCount; ct++) {
-        status = pthread_create(&mWorkers.mThreadId[ct], &threadAttr, helperThreadProc, this);
-        if (status) {
-            mWorkers.mCount = ct;
-            LOGE("Created fewer than expected number of RS threads.");
-            break;
-        }
-    }
     pthread_attr_destroy(&threadAttr);
     return true;
 }
@@ -720,7 +395,7 @@
 Context::~Context() {
     LOGV("Context::~Context");
 
-    mIO.mToCore.flush();
+    mIO.coreFlush();
     rsAssert(mExit);
     mExit = true;
     mPaused = false;
@@ -729,64 +404,29 @@
     mIO.shutdown();
     int status = pthread_join(mThreadId, &res);
 
-    // Cleanup compute threads.
-    mWorkers.mLaunchData = NULL;
-    mWorkers.mLaunchCallback = NULL;
-    mWorkers.mRunningCount = (int)mWorkers.mCount;
-    for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
-        mWorkers.mLaunchSignals[ct].set();
+    if (mHal.funcs.shutdownDriver) {
+        mHal.funcs.shutdownDriver(this);
     }
-    for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
-        int status = pthread_join(mWorkers.mThreadId[ct], &res);
-    }
-    rsAssert(!mWorkers.mRunningCount);
 
     // Global structure cleanup.
     pthread_mutex_lock(&gInitMutex);
     if (mDev) {
         mDev->removeContext(this);
-        --gThreadTLSKeyCount;
-        if (!gThreadTLSKeyCount) {
-            pthread_key_delete(gThreadTLSKey);
-        }
         mDev = NULL;
     }
     pthread_mutex_unlock(&gInitMutex);
     LOGV("Context::~Context done");
 }
 
-void Context::setSurface(uint32_t w, uint32_t h, ANativeWindow *sur) {
+void Context::setSurface(uint32_t w, uint32_t h, RsNativeWindow sur) {
     rsAssert(mIsGraphicsContext);
+    mHal.funcs.setSurface(this, w, h, sur);
 
-    EGLBoolean ret;
-    // WAR: Some drivers fail to handle 0 size surfaces correcntly.
-    // Use the pbuffer to avoid this pitfall.
-    if ((mEGL.mSurface != NULL) || (w == 0) || (h == 0)) {
-        ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurfaceDefault, mEGL.mSurfaceDefault, mEGL.mContext);
-        checkEglError("eglMakeCurrent", ret);
+    mHasSurface = sur != NULL;
+    mWidth = w;
+    mHeight = h;
 
-        ret = eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
-        checkEglError("eglDestroySurface", ret);
-
-        mEGL.mSurface = NULL;
-        mWidth = 1;
-        mHeight = 1;
-    }
-
-    mWndSurface = sur;
-    if (mWndSurface != NULL) {
-        mWidth = w;
-        mHeight = h;
-
-        mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL);
-        checkEglError("eglCreateWindowSurface");
-        if (mEGL.mSurface == EGL_NO_SURFACE) {
-            LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
-        }
-
-        ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext);
-        checkEglError("eglMakeCurrent", ret);
-
+    if (mWidth && mHeight) {
         mStateVertex.updateSize(this);
     }
 }
@@ -866,69 +506,18 @@
     }
 }
 
-RsMessageToClientType Context::peekMessageToClient(size_t *receiveLen, uint32_t *subID, bool wait) {
-    *receiveLen = 0;
-    if (!wait && mIO.mToClient.isEmpty()) {
-        return RS_MESSAGE_TO_CLIENT_NONE;
-    }
-
-    uint32_t bytesData = 0;
-    uint32_t commandID = 0;
-    const uint32_t *d = (const uint32_t *)mIO.mToClient.get(&commandID, &bytesData);
-    *receiveLen = bytesData - sizeof(uint32_t);
-    if (bytesData) {
-        *subID = d[0];
-    }
-    return (RsMessageToClientType)commandID;
+RsMessageToClientType Context::peekMessageToClient(size_t *receiveLen, uint32_t *subID) {
+    return (RsMessageToClientType)mIO.getClientHeader(receiveLen, subID);
 }
 
-RsMessageToClientType Context::getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen, bool wait) {
-    //LOGE("getMessageToClient %i %i", bufferLen, wait);
-    *receiveLen = 0;
-    if (!wait && mIO.mToClient.isEmpty()) {
-        return RS_MESSAGE_TO_CLIENT_NONE;
-    }
-
-    //LOGE("getMessageToClient 2 con=%p", this);
-    uint32_t bytesData = 0;
-    uint32_t commandID = 0;
-    const uint32_t *d = (const uint32_t *)mIO.mToClient.get(&commandID, &bytesData);
-    //LOGE("getMessageToClient 3    %i  %i", commandID, bytesData);
-
-    *receiveLen = bytesData - sizeof(uint32_t);
-    *subID = d[0];
-
-    //LOGE("getMessageToClient  %i %i", commandID, *subID);
-    if (bufferLen >= bytesData) {
-        memcpy(data, d+1, *receiveLen);
-        mIO.mToClient.next();
-        return (RsMessageToClientType)commandID;
-    }
-    return RS_MESSAGE_TO_CLIENT_RESIZE;
+RsMessageToClientType Context::getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen) {
+    return (RsMessageToClientType)mIO.getClientPayload(data, receiveLen, subID, bufferLen);
 }
 
 bool Context::sendMessageToClient(const void *data, RsMessageToClientType cmdID,
                                   uint32_t subID, size_t len, bool waitForSpace) const {
-    //LOGE("sendMessageToClient %i %i %i %i", cmdID, subID, len, waitForSpace);
-    if (cmdID == 0) {
-        LOGE("Attempting to send invalid command 0 to client.");
-        return false;
-    }
-    if (!waitForSpace) {
-        if (!mIO.mToClient.makeSpaceNonBlocking(len + 12)) {
-            // Not enough room, and not waiting.
-            return false;
-        }
-    }
-    //LOGE("sendMessageToClient 2");
-    uint32_t *p = (uint32_t *)mIO.mToClient.reserve(len + sizeof(subID));
-    p[0] = subID;
-    if (len > 0) {
-        memcpy(p+1, data, len);
-    }
-    mIO.mToClient.commit(cmdID, len + sizeof(subID));
-    //LOGE("sendMessageToClient 3");
-    return true;
+
+    return mIO.sendToClient(cmdID, subID, data, len, waitForSpace);
 }
 
 void Context::initToClient() {
@@ -938,7 +527,7 @@
 }
 
 void Context::deinitToClient() {
-    mIO.mToClient.shutdown();
+    mIO.clientShutdown();
 }
 
 void Context::setError(RsError e, const char *msg) const {
@@ -951,21 +540,9 @@
     LOGE("RS Context debug %p", this);
     LOGE("RS Context debug");
 
-    LOGE(" EGL ver %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
-    LOGE(" EGL context %p  surface %p,  Display=%p", mEGL.mContext, mEGL.mSurface, mEGL.mDisplay);
-    LOGE(" GL vendor: %s", mGL.mVendor);
-    LOGE(" GL renderer: %s", mGL.mRenderer);
-    LOGE(" GL Version: %s", mGL.mVersion);
-    LOGE(" GL Extensions: %s", mGL.mExtensions);
-    LOGE(" GL int Versions %i %i", mGL.mMajorVersion, mGL.mMinorVersion);
     LOGE(" RS width %i, height %i", mWidth, mHeight);
     LOGE(" RS running %i, exit %i, paused %i", mRunning, mExit, mPaused);
     LOGE(" RS pThreadID %li, nativeThreadID %i", mThreadId, mNativeThreadId);
-
-    LOGV("MAX Textures %i, %i  %i", mGL.mMaxVertexTextureUnits, mGL.mMaxFragmentTextureImageUnits, mGL.mMaxTextureImageUnits);
-    LOGV("MAX Attribs %i", mGL.mMaxVertexAttribs);
-    LOGV("MAX Uniforms %i, %i", mGL.mMaxVertexUniformVectors, mGL.mMaxFragmentUniformVectors);
-    LOGV("MAX Varyings %i", mGL.mMaxVaryingVectors);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////
@@ -1018,9 +595,9 @@
     rsc->setFont(font);
 }
 
-void rsi_AssignName(Context *rsc, void * obj, const char *name, uint32_t len) {
+void rsi_AssignName(Context *rsc, RsObjectBase obj, const char *name, uint32_t name_length) {
     ObjectBase *ob = static_cast<ObjectBase *>(obj);
-    rsc->assignName(ob, name, len);
+    rsc->assignName(ob, name, name_length);
 }
 
 void rsi_ObjDestroy(Context *rsc, void *optr) {
@@ -1037,7 +614,7 @@
     rsc->resume();
 }
 
-void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, ANativeWindow *sur) {
+void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
     rsc->setSurface(w, h, sur);
 }
 
@@ -1053,15 +630,37 @@
     rsc->destroyWorkerThreadResources();;
 }
 
-}
-}
-
-void rsContextDestroy(RsContext vcon) {
-    LOGV("rsContextDestroy %p", vcon);
-    Context *rsc = static_cast<Context *>(vcon);
+void rsi_ContextDestroy(Context *rsc) {
+    LOGV("rsContextDestroy %p", rsc);
     rsContextDestroyWorker(rsc);
     delete rsc;
-    LOGV("rsContextDestroy 2 %p", vcon);
+    LOGV("rsContextDestroy 2 %p", rsc);
+}
+
+
+RsMessageToClientType rsi_ContextPeekMessage(Context *rsc,
+                                           size_t * receiveLen, size_t receiveLen_length,
+                                           uint32_t * subID, size_t subID_length) {
+    return rsc->peekMessageToClient(receiveLen, subID);
+}
+
+RsMessageToClientType rsi_ContextGetMessage(Context *rsc, void * data, size_t data_length,
+                                          size_t * receiveLen, size_t receiveLen_length,
+                                          uint32_t * subID, size_t subID_length) {
+    rsAssert(subID_length == sizeof(uint32_t));
+    rsAssert(receiveLen_length == sizeof(size_t));
+    return rsc->getMessageToClient(data, receiveLen, subID, data_length);
+}
+
+void rsi_ContextInitToClient(Context *rsc) {
+    rsc->initToClient();
+}
+
+void rsi_ContextDeinitToClient(Context *rsc) {
+    rsc->deinitToClient();
+}
+
+}
 }
 
 RsContext rsContextCreate(RsDevice vdev, uint32_t version) {
@@ -1071,34 +670,16 @@
     return rsc;
 }
 
-RsContext rsContextCreateGL(RsDevice vdev, uint32_t version, RsSurfaceConfig sc) {
+RsContext rsContextCreateGL(RsDevice vdev, uint32_t version,
+                            RsSurfaceConfig sc, uint32_t dpi) {
     LOGV("rsContextCreateGL %p", vdev);
     Device * dev = static_cast<Device *>(vdev);
     Context *rsc = Context::createContext(dev, &sc);
+    rsc->setDPI(dpi);
     LOGV("rsContextCreateGL ret %p ", rsc);
     return rsc;
 }
 
-RsMessageToClientType rsContextPeekMessage(RsContext vrsc, size_t *receiveLen, uint32_t *subID, bool wait) {
-    Context * rsc = static_cast<Context *>(vrsc);
-    return rsc->peekMessageToClient(receiveLen, subID, wait);
-}
-
-RsMessageToClientType rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen, bool wait) {
-    Context * rsc = static_cast<Context *>(vrsc);
-    return rsc->getMessageToClient(data, receiveLen, subID, bufferLen, wait);
-}
-
-void rsContextInitToClient(RsContext vrsc) {
-    Context * rsc = static_cast<Context *>(vrsc);
-    rsc->initToClient();
-}
-
-void rsContextDeinitToClient(RsContext vrsc) {
-    Context * rsc = static_cast<Context *>(vrsc);
-    rsc->deinitToClient();
-}
-
 // Only to be called at a3d load time, before object is visible to user
 // not thread safe
 void rsaGetName(RsContext con, void * obj, const char **name) {
diff --git a/rsContext.h b/rsContext.h
index 9f94f26..be615a3 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -18,16 +18,18 @@
 #define ANDROID_RS_CONTEXT_H
 
 #include "rsUtils.h"
-#include "rsMutex.h"
-
-#include "rsThreadIO.h"
 #include "rsType.h"
-#include "rsMatrix.h"
 #include "rsAllocation.h"
 #include "rsMesh.h"
+
+#include "rs_hal.h"
+
+#ifndef ANDROID_RS_SERIALIZE
+#include "rsMutex.h"
+#include "rsThreadIO.h"
+#include "rsMatrix4x4.h"
 #include "rsDevice.h"
 #include "rsScriptC.h"
-#include "rsAllocation.h"
 #include "rsAdapter.h"
 #include "rsSampler.h"
 #include "rsFont.h"
@@ -35,13 +37,12 @@
 #include "rsProgramStore.h"
 #include "rsProgramRaster.h"
 #include "rsProgramVertex.h"
-#include "rsShaderCache.h"
-#include "rsVertexArray.h"
+#include "rsFBOCache.h"
 
 #include "rsgApiStructs.h"
 #include "rsLocklessFifo.h"
 
-#include <ui/egl/android_natives.h>
+#endif // ANDROID_RS_SERIALIZE
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -66,23 +67,24 @@
 #define CHECK_OBJ_OR_NULL(o)
 #endif
 
+#ifndef ANDROID_RS_SERIALIZE
+
 class Context {
 public:
+    struct Hal {
+        void * drv;
+
+        RsdHalFunctions funcs;
+    };
+    Hal mHal;
+
     static Context * createContext(Device *, const RsSurfaceConfig *sc);
     ~Context();
 
-    static pthread_key_t gThreadTLSKey;
-    static uint32_t gThreadTLSKeyCount;
-    static uint32_t gGLContextCount;
     static pthread_mutex_t gInitMutex;
     // Library mutex (for providing thread-safe calls from the runtime)
     static pthread_mutex_t gLibMutex;
 
-    struct ScriptTLSStruct {
-        Context * mContext;
-        Script * mScript;
-    };
-
     class PushState {
     public:
         PushState(Context *);
@@ -97,12 +99,8 @@
         Context *mRsc;
     };
 
-    ScriptTLSStruct *mTlsStruct;
     RsSurfaceConfig mUserSurfaceConfig;
 
-    typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
-
-    //StructuredAllocationContext mStateAllocation;
     ElementState mStateElement;
     TypeState mStateType;
     SamplerState mStateSampler;
@@ -110,11 +108,10 @@
     ProgramStoreState mStateFragmentStore;
     ProgramRasterState mStateRaster;
     ProgramVertexState mStateVertex;
-    VertexArrayState mStateVertexArray;
     FontState mStateFont;
 
     ScriptCState mScriptC;
-    ShaderCache mShaderCache;
+    FBOCache mFBOCache;
 
     void swapBuffers();
     void setRootScript(Script *);
@@ -137,15 +134,15 @@
 
     void pause();
     void resume();
-    void setSurface(uint32_t w, uint32_t h, ANativeWindow *sur);
+    void setSurface(uint32_t w, uint32_t h, RsNativeWindow sur);
     void setPriority(int32_t p);
     void destroyWorkerThreadResources();
 
     void assignName(ObjectBase *obj, const char *name, uint32_t len);
     void removeName(ObjectBase *obj);
 
-    RsMessageToClientType peekMessageToClient(size_t *receiveLen, uint32_t *subID, bool wait);
-    RsMessageToClientType getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen, bool wait);
+    RsMessageToClientType peekMessageToClient(size_t *receiveLen, uint32_t *subID);
+    RsMessageToClientType getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen);
     bool sendMessageToClient(const void *data, RsMessageToClientType cmdID, uint32_t subID, size_t len, bool waitForSpace) const;
     uint32_t runScript(Script *s);
 
@@ -199,62 +196,17 @@
     } props;
 
     void dumpDebug() const;
-    void checkError(const char *, bool isFatal = false) const;
     void setError(RsError e, const char *msg = NULL) const;
 
     mutable const ObjectBase * mObjHead;
 
-    bool ext_OES_texture_npot() const {return mGL.OES_texture_npot;}
-    bool ext_GL_IMG_texture_npot() const {return mGL.GL_IMG_texture_npot;}
-    bool ext_GL_NV_texture_npot_2D_mipmap() const {return mGL.GL_NV_texture_npot_2D_mipmap;}
-    float ext_texture_max_aniso() const {return mGL.EXT_texture_max_aniso; }
-    uint32_t getMaxFragmentTextures() const {return mGL.mMaxFragmentTextureImageUnits;}
-    uint32_t getMaxFragmentUniformVectors() const {return mGL.mMaxFragmentUniformVectors;}
-    uint32_t getMaxVertexUniformVectors() const {return mGL.mMaxVertexUniformVectors;}
-    uint32_t getMaxVertexAttributes() const {return mGL.mMaxVertexAttribs;}
+    uint32_t getDPI() const {return mDPI;}
+    void setDPI(uint32_t dpi) {mDPI = dpi;}
 
-    void launchThreads(WorkerCallback_t cbk, void *data);
-    uint32_t getWorkerPoolSize() const {return (uint32_t)mWorkers.mCount;}
-
-protected:
     Device *mDev;
+protected:
 
-    struct {
-        EGLint mNumConfigs;
-        EGLint mMajorVersion;
-        EGLint mMinorVersion;
-        EGLConfig mConfig;
-        EGLContext mContext;
-        EGLSurface mSurface;
-        EGLSurface mSurfaceDefault;
-        EGLDisplay mDisplay;
-    } mEGL;
-
-    struct {
-        const uint8_t * mVendor;
-        const uint8_t * mRenderer;
-        const uint8_t * mVersion;
-        const uint8_t * mExtensions;
-
-        uint32_t mMajorVersion;
-        uint32_t mMinorVersion;
-
-        int32_t mMaxVaryingVectors;
-        int32_t mMaxTextureImageUnits;
-
-        int32_t mMaxFragmentTextureImageUnits;
-        int32_t mMaxFragmentUniformVectors;
-
-        int32_t mMaxVertexAttribs;
-        int32_t mMaxVertexUniformVectors;
-        int32_t mMaxVertexTextureUnits;
-
-        bool OES_texture_npot;
-        bool GL_IMG_texture_npot;
-        bool GL_NV_texture_npot_2D_mipmap;
-        float EXT_texture_max_aniso;
-    } mGL;
-
+    uint32_t mDPI;
     uint32_t mWidth;
     uint32_t mHeight;
     int32_t mThreadPriority;
@@ -268,20 +220,6 @@
     pthread_t mThreadId;
     pid_t mNativeThreadId;
 
-    struct Workers {
-        volatile int mRunningCount;
-        volatile int mLaunchCount;
-        uint32_t mCount;
-        pthread_t *mThreadId;
-        pid_t *mNativeThreadId;
-        Signal mCompleteSignal;
-
-        Signal *mLaunchSignals;
-        WorkerCallback_t mLaunchCallback;
-        void *mLaunchData;
-    };
-    Workers mWorkers;
-
     ObjectBaseRef<Script> mRootScript;
     ObjectBaseRef<ProgramFragment> mFragment;
     ObjectBaseRef<ProgramVertex> mVertex;
@@ -304,7 +242,7 @@
     static void * threadProc(void *);
     static void * helperThreadProc(void *);
 
-    ANativeWindow *mWndSurface;
+    bool mHasSurface;
 
     Vector<ObjectBase *> mNames;
 
@@ -321,6 +259,39 @@
     uint32_t mAverageFPS;
 };
 
-}
-}
+#else
+
+class Context {
+public:
+    Context() {
+        mObjHead = NULL;
+    }
+    ~Context() {
+        ObjectBase::zeroAllUserRef(this);
+    }
+
+    ElementState mStateElement;
+    TypeState mStateType;
+
+    struct {
+        bool mLogTimes;
+        bool mLogScripts;
+        bool mLogObjects;
+        bool mLogShaders;
+        bool mLogShadersAttr;
+        bool mLogShadersUniforms;
+        bool mLogVisual;
+    } props;
+
+    void setError(RsError e, const char *msg = NULL) {  }
+
+    mutable const ObjectBase * mObjHead;
+
+protected:
+
+};
+#endif //ANDROID_RS_SERIALIZE
+
+} // renderscript
+} // android
 #endif
diff --git a/rsContextHostStub.h b/rsContextHostStub.h
deleted file mode 100644
index 8cfb38b..0000000
--- a/rsContextHostStub.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_RS_CONTEXT_HOST_STUB_H
-#define ANDROID_RS_CONTEXT_HOST_STUB_H
-
-#include "rsUtils.h"
-//#include "rsMutex.h"
-
-//#include "rsThreadIO.h"
-#include "rsType.h"
-#include "rsMatrix.h"
-#include "rsAllocation.h"
-#include "rsMesh.h"
-//#include "rsDevice.h"
-#include "rsScriptC.h"
-#include "rsAllocation.h"
-#include "rsAdapter.h"
-#include "rsSampler.h"
-#include "rsProgramFragment.h"
-#include "rsProgramStore.h"
-#include "rsProgramRaster.h"
-#include "rsProgramVertex.h"
-#include "rsShaderCache.h"
-#include "rsVertexArray.h"
-
-//#include "rsgApiStructs.h"
-//#include "rsLocklessFifo.h"
-
-//#include <ui/egl/android_natives.h>
-
-// ---------------------------------------------------------------------------
-namespace android {
-namespace renderscript {
-
-class Device;
-
-class Context {
-public:
-    Context(Device *, bool isGraphics, bool useDepth) {
-        mObjHead = NULL;
-    }
-    ~Context() {
-    }
-
-
-    //StructuredAllocationContext mStateAllocation;
-    ElementState mStateElement;
-    TypeState mStateType;
-    SamplerState mStateSampler;
-    //ProgramFragmentState mStateFragment;
-    ProgramStoreState mStateFragmentStore;
-    //ProgramRasterState mStateRaster;
-    //ProgramVertexState mStateVertex;
-    VertexArrayState mStateVertexArray;
-
-    //ScriptCState mScriptC;
-    ShaderCache mShaderCache;
-
-    RsSurfaceConfig mUserSurfaceConfig;
-
-    //bool setupCheck();
-
-    ProgramFragment * getDefaultProgramFragment() const {
-        return NULL;
-    }
-    ProgramVertex * getDefaultProgramVertex() const {
-        return NULL;
-    }
-    ProgramStore * getDefaultProgramStore() const {
-        return NULL;
-    }
-    ProgramRaster * getDefaultProgramRaster() const {
-        return NULL;
-    }
-
-    uint32_t getWidth() const {return 0;}
-    uint32_t getHeight() const {return 0;}
-
-    // Timers
-    enum Timers {
-        RS_TIMER_IDLE,
-        RS_TIMER_INTERNAL,
-        RS_TIMER_SCRIPT,
-        RS_TIMER_CLEAR_SWAP,
-        _RS_TIMER_TOTAL
-    };
-
-    bool checkVersion1_1() const {return false; }
-    bool checkVersion2_0() const {return false; }
-
-    struct {
-        bool mLogTimes;
-        bool mLogScripts;
-        bool mLogObjects;
-        bool mLogShaders;
-        bool mLogShadersAttr;
-        bool mLogShadersUniforms;
-        bool mLogVisual;
-    } props;
-
-    void dumpDebug() const {    }
-    void checkError(const char *) const {  };
-    void setError(RsError e, const char *msg = NULL) {  }
-
-    mutable const ObjectBase * mObjHead;
-
-    bool ext_OES_texture_npot() const {return mGL.OES_texture_npot;}
-    bool ext_GL_NV_texture_npot_2D_mipmap() const {return mGL.GL_NV_texture_npot_2D_mipmap;}
-    float ext_texture_max_aniso() const {return mGL.EXT_texture_max_aniso; }
-    uint32_t getMaxFragmentTextures() const {return mGL.mMaxFragmentTextureImageUnits;}
-    uint32_t getMaxFragmentUniformVectors() const {return mGL.mMaxFragmentUniformVectors;}
-    uint32_t getMaxVertexUniformVectors() const {return mGL.mMaxVertexUniformVectors;}
-    uint32_t getMaxVertexAttributes() const {return mGL.mMaxVertexAttribs;}
-
-protected:
-
-    struct {
-        const uint8_t * mVendor;
-        const uint8_t * mRenderer;
-        const uint8_t * mVersion;
-        const uint8_t * mExtensions;
-
-        uint32_t mMajorVersion;
-        uint32_t mMinorVersion;
-
-        int32_t mMaxVaryingVectors;
-        int32_t mMaxTextureImageUnits;
-
-        int32_t mMaxFragmentTextureImageUnits;
-        int32_t mMaxFragmentUniformVectors;
-
-        int32_t mMaxVertexAttribs;
-        int32_t mMaxVertexUniformVectors;
-        int32_t mMaxVertexTextureUnits;
-
-        bool OES_texture_npot;
-        bool GL_NV_texture_npot_2D_mipmap;
-        float EXT_texture_max_aniso;
-    } mGL;
-
-};
-
-}
-}
-#endif
diff --git a/rsDevice.cpp b/rsDevice.cpp
index dd96445..d7d03f6 100644
--- a/rsDevice.cpp
+++ b/rsDevice.cpp
@@ -15,11 +15,7 @@
  */
 
 #include "rsDevice.h"
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#else
-#include "rsContextHostStub.h"
-#endif
 
 using namespace android;
 using namespace android::renderscript;
diff --git a/rsElement.cpp b/rsElement.cpp
index 6ae8bb8..2b58e9e 100644
--- a/rsElement.cpp
+++ b/rsElement.cpp
@@ -15,13 +15,7 @@
  */
 
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include <GLES/gl.h>
-#else
-#include "rsContextHostStub.h"
-#include <OpenGL/gl.h>
-#endif
 
 using namespace android;
 using namespace android::renderscript;
@@ -65,7 +59,7 @@
 
 void Element::dumpLOGV(const char *prefix) const {
     ObjectBase::dumpLOGV(prefix);
-    LOGV("%s Element: fieldCount: %i,  size bytes: %i", prefix, mFieldCount, getSizeBytes());
+    LOGV("%s Element: fieldCount: %zu,  size bytes: %zu", prefix, mFieldCount, getSizeBytes());
     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
         LOGV("%s Element field index: %u ------------------", prefix, ct);
         LOGV("%s name: %s, offsetBits: %u, arraySize: %u",
@@ -353,13 +347,18 @@
     return (RsElement)e;
 }
 
+
 RsElement rsi_ElementCreate2(Context *rsc,
-                             size_t count,
                              const RsElement * ein,
+                             size_t ein_length,
+
                              const char ** names,
+                             size_t nameLengths_length,
                              const size_t * nameLengths,
-                             const uint32_t * arraySizes) {
-    const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths, arraySizes);
+
+                             const uint32_t * arraySizes,
+                             size_t arraySizes_length) {
+    const Element *e = Element::create(rsc, ein_length, (const Element **)ein, names, nameLengths, arraySizes);
     e->incUserRef();
     return (RsElement)e;
 }
diff --git a/rsFBOCache.cpp b/rsFBOCache.cpp
new file mode 100644
index 0000000..31a51b7
--- /dev/null
+++ b/rsFBOCache.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011 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 "rsFBOCache.h"
+
+#include "rsContext.h"
+#include "rsAllocation.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+FBOCache::FBOCache() {
+    mDirty = true;
+    mHal.state.colorTargetsCount = 1;
+    mHal.state.colorTargets = new ObjectBaseRef<Allocation>[mHal.state.colorTargetsCount];
+}
+
+FBOCache::~FBOCache() {
+    delete[] mHal.state.colorTargets;
+}
+
+void FBOCache::init(Context *rsc) {
+    rsc->mHal.funcs.framebuffer.init(rsc, this);
+}
+
+void FBOCache::deinit(Context *rsc) {
+    rsc->mHal.funcs.framebuffer.destroy(rsc, this);
+}
+
+void FBOCache::bindColorTarget(Context *rsc, Allocation *a, uint32_t slot) {
+    if (slot >= mHal.state.colorTargetsCount) {
+        LOGE("Invalid render target index");
+        return;
+    }
+    if (a != NULL) {
+        if (!a->getIsTexture()) {
+            LOGE("Invalid Color Target");
+            return;
+        }
+        if (a->getIsTexture()) {
+            if (a->getTextureID() == 0) {
+                a->deferredUploadToTexture(rsc);
+            }
+        } else if (a->getRenderTargetID() == 0) {
+            a->deferredAllocateRenderTarget(rsc);
+        }
+    }
+    mHal.state.colorTargets[slot].set(a);
+    mDirty = true;
+}
+
+void FBOCache::bindDepthTarget(Context *rsc, Allocation *a) {
+    if (a != NULL) {
+        if (!a->getIsRenderTarget()) {
+            LOGE("Invalid Depth Target");
+            return;
+        }
+        if (a->getIsTexture()) {
+            if (a->getTextureID() == 0) {
+                a->deferredUploadToTexture(rsc);
+            }
+        } else if (a->getRenderTargetID() == 0) {
+            a->deferredAllocateRenderTarget(rsc);
+        }
+    }
+    mHal.state.depthTarget.set(a);
+    mDirty = true;
+}
+
+void FBOCache::resetAll(Context *) {
+    for (uint32_t i = 0; i < mHal.state.colorTargetsCount; i ++) {
+        mHal.state.colorTargets[i].set(NULL);
+    }
+    mHal.state.depthTarget.set(NULL);
+    mDirty = true;
+}
+
+void FBOCache::setup(Context *rsc) {
+    if (!mDirty) {
+        return;
+    }
+
+    if (mHal.state.depthTarget.get() != NULL) {
+        mHal.state.depthTarget->uploadCheck(rsc);
+    }
+
+    for (uint32_t i = 0; i < mHal.state.colorTargetsCount; i ++) {
+        if (mHal.state.colorTargets[i].get() != NULL) {
+            mHal.state.colorTargets[i]->uploadCheck(rsc);
+        }
+    }
+
+    rsc->mHal.funcs.framebuffer.setActive(rsc, this);
+
+    mDirty = false;
+}
diff --git a/rsFBOCache.h b/rsFBOCache.h
new file mode 100644
index 0000000..f42e1f3
--- /dev/null
+++ b/rsFBOCache.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FRAME_BUFFER_OBJECT_CACHE_H
+#define ANDROID_FRAME_BUFFER_OBJECT_CACHE_H
+
+#include "rsObjectBase.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class Allocation;
+
+class FBOCache {
+public:
+    FBOCache();
+    ~FBOCache();
+
+    void init(Context *rsc);
+    void deinit(Context *rsc);
+
+    void bindColorTarget(Context *rsc, Allocation *a, uint32_t slot);
+    void bindDepthTarget(Context *, Allocation *a);
+    void resetAll(Context *);
+
+    void setup(Context *);
+
+    struct Hal {
+        mutable void *drv;
+
+        struct State {
+            ObjectBaseRef<Allocation> *colorTargets;
+            uint32_t colorTargetsCount;
+            ObjectBaseRef<Allocation> depthTarget;
+        };
+        State state;
+    };
+    Hal mHal;
+
+protected:
+    bool mDirty;
+    void checkError(Context *);
+    void setColorAttachment(Context *rsc);
+    void setDepthAttachment(Context *rsc);
+    bool renderToFramebuffer();
+
+};
+
+} // renderscript
+} // android
+
+#endif //ANDROID_FRAME_BUFFER_OBJECT_CACHE_H
diff --git a/rsFifo.cpp b/rsFifo.cpp
new file mode 100644
index 0000000..3d5d8c4
--- /dev/null
+++ b/rsFifo.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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 "rsFifoSocket.h"
+#include "utils/Timers.h"
+#include "utils/StopWatch.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+Fifo::Fifo() {
+
+}
+
+Fifo::~Fifo() {
+
+}
+
diff --git a/rsFifo.h b/rsFifo.h
new file mode 100644
index 0000000..f924b95
--- /dev/null
+++ b/rsFifo.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_FIFO_H
+#define ANDROID_RS_FIFO_H
+
+
+#include "rsUtils.h"
+
+namespace android {
+namespace renderscript {
+
+
+// A simple FIFO to be used as a producer / consumer between two
+// threads.  One is writer and one is reader.  The common cases
+// will not require locking.  It is not threadsafe for multiple
+// readers or writers by design.
+
+class Fifo {
+protected:
+    Fifo();
+    virtual ~Fifo();
+
+public:
+    void virtual writeAsync(const void *data, size_t bytes) = 0;
+    void virtual writeWaitReturn(void *ret, size_t retSize) = 0;
+    size_t virtual read(void *data, size_t bytes) = 0;
+    void virtual readReturn(const void *data, size_t bytes) = 0;
+
+    void virtual flush() = 0;
+
+};
+
+}
+}
+#endif
diff --git a/rsFifoSocket.cpp b/rsFifoSocket.cpp
new file mode 100644
index 0000000..848bba5
--- /dev/null
+++ b/rsFifoSocket.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 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 "rsFifoSocket.h"
+#include "utils/Timers.h"
+#include "utils/StopWatch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+FifoSocket::FifoSocket() {
+    sequence = 1;
+}
+
+FifoSocket::~FifoSocket() {
+
+}
+
+bool FifoSocket::init() {
+    int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
+    return false;
+}
+
+void FifoSocket::shutdown() {
+}
+
+void FifoSocket::writeAsync(const void *data, size_t bytes) {
+    if (bytes == 0) {
+        return;
+    }
+    //LOGE("writeAsync %p %i", data, bytes);
+    size_t ret = ::send(sv[0], data, bytes, 0);
+    //LOGE("writeAsync ret %i", ret);
+    rsAssert(ret == bytes);
+}
+
+void FifoSocket::writeWaitReturn(void *retData, size_t retBytes) {
+    //LOGE("writeWaitReturn %p %i", retData, retBytes);
+    size_t ret = ::recv(sv[0], retData, retBytes, 0);
+    //LOGE("writeWaitReturn %i", ret);
+    rsAssert(ret == retBytes);
+}
+
+size_t FifoSocket::read(void *data, size_t bytes) {
+    //LOGE("read %p %i", data, bytes);
+    size_t ret = ::recv(sv[1], data, bytes, 0);
+    rsAssert(ret == bytes);
+    //LOGE("read ret %i", ret);
+    return ret;
+}
+
+void FifoSocket::readReturn(const void *data, size_t bytes) {
+    LOGE("readReturn %p %i", data, bytes);
+    size_t ret = ::send(sv[1], data, bytes, 0);
+    LOGE("readReturn %i", ret);
+    rsAssert(ret == bytes);
+}
+
+
+void FifoSocket::flush() {
+}
+
+
diff --git a/rsFifoSocket.h b/rsFifoSocket.h
new file mode 100644
index 0000000..7df2b67
--- /dev/null
+++ b/rsFifoSocket.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_FIFO_SOCKET_H
+#define ANDROID_RS_FIFO_SOCKET_H
+
+
+#include "rsFifo.h"
+
+namespace android {
+namespace renderscript {
+
+
+class FifoSocket {
+public:
+    FifoSocket();
+    virtual ~FifoSocket();
+
+    bool init();
+    void shutdown();
+
+
+
+    void virtual writeAsync(const void *data, size_t bytes);
+    void virtual writeWaitReturn(void *ret, size_t retSize);
+    size_t virtual read(void *data, size_t bytes);
+    void virtual readReturn(const void *data, size_t bytes);
+
+    void virtual flush();
+
+protected:
+    int sv[2];
+    uint32_t sequence;
+
+
+};
+
+}
+}
+
+#endif
diff --git a/rsFileA3D.cpp b/rsFileA3D.cpp
index d34ddd6..cd02c24 100644
--- a/rsFileA3D.cpp
+++ b/rsFileA3D.cpp
@@ -15,12 +15,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#else
-#include "rsContextHostStub.h"
-#endif
-
 #include "rsFileA3D.h"
 
 #include "rsMesh.h"
@@ -249,31 +244,31 @@
             entry->mRsObj = Allocation::createFromStream(mRSC, mReadStream);
             break;
         case RS_A3D_CLASS_ID_PROGRAM_VERTEX:
-            entry->mRsObj = ProgramVertex::createFromStream(mRSC, mReadStream);
+            //entry->mRsObj = ProgramVertex::createFromStream(mRSC, mReadStream);
             break;
         case RS_A3D_CLASS_ID_PROGRAM_RASTER:
-            entry->mRsObj = ProgramRaster::createFromStream(mRSC, mReadStream);
+            //entry->mRsObj = ProgramRaster::createFromStream(mRSC, mReadStream);
             break;
         case RS_A3D_CLASS_ID_PROGRAM_FRAGMENT:
-            entry->mRsObj = ProgramFragment::createFromStream(mRSC, mReadStream);
+            //entry->mRsObj = ProgramFragment::createFromStream(mRSC, mReadStream);
             break;
         case RS_A3D_CLASS_ID_PROGRAM_STORE:
-            entry->mRsObj = ProgramStore::createFromStream(mRSC, mReadStream);
+            //entry->mRsObj = ProgramStore::createFromStream(mRSC, mReadStream);
             break;
         case RS_A3D_CLASS_ID_SAMPLER:
-            entry->mRsObj = Sampler::createFromStream(mRSC, mReadStream);
+            //entry->mRsObj = Sampler::createFromStream(mRSC, mReadStream);
             break;
         case RS_A3D_CLASS_ID_ANIMATION:
-            entry->mRsObj = Animation::createFromStream(mRSC, mReadStream);
+            //entry->mRsObj = Animation::createFromStream(mRSC, mReadStream);
             break;
         case RS_A3D_CLASS_ID_ADAPTER_1D:
-            entry->mRsObj = Adapter1D::createFromStream(mRSC, mReadStream);
+            //entry->mRsObj = Adapter1D::createFromStream(mRSC, mReadStream);
             break;
         case RS_A3D_CLASS_ID_ADAPTER_2D:
-            entry->mRsObj = Adapter2D::createFromStream(mRSC, mReadStream);
+            //entry->mRsObj = Adapter2D::createFromStream(mRSC, mReadStream);
             break;
         case RS_A3D_CLASS_ID_SCRIPT_C:
-            return NULL;
+            break;
     }
     if (entry->mRsObj) {
         entry->mRsObj->incUserRef();
diff --git a/rsFont.cpp b/rsFont.cpp
index 7fdfbe0..5e47ddb 100644
--- a/rsFont.cpp
+++ b/rsFont.cpp
@@ -15,21 +15,15 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#else
-#include "rsContextHostStub.h"
-#endif
 
 #include "rsFont.h"
 #include "rsProgramFragment.h"
 #include <cutils/properties.h>
-#include FT_BITMAP_H
 
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_BITMAP_H
 
 using namespace android;
 using namespace android::renderscript;
@@ -212,7 +206,7 @@
             }
         }
 
-        penX += (cachedGlyph->mAdvance.x >> 6);
+        penX += (cachedGlyph->mAdvanceX >> 6);
 
         // If we were given a specific number of glyphs, decrement
         if (numGlyphs > 0) {
@@ -242,7 +236,8 @@
         return;
     }
 
-    glyph->mAdvance = mFace->glyph->advance;
+    glyph->mAdvanceX = mFace->glyph->advance.x;
+    glyph->mAdvanceY = mFace->glyph->advance.y;
     glyph->mBitmapLeft = mFace->glyph->bitmap_left;
     glyph->mBitmapTop = mFace->glyph->bitmap_top;
 
@@ -457,7 +452,7 @@
 
     // This will dirty the texture and the shader so next time
     // we draw it will upload the data
-    mTextTexture->syncAll(mRSC, RS_ALLOCATION_USAGE_SCRIPT);
+    mTextTexture->deferredUploadToTexture(mRSC);
     mFontShaderF->bindTexture(mRSC, 0, mTextTexture.get());
 
     // Some debug code
@@ -507,12 +502,13 @@
     mFontSampler.set(sampler);
     mFontShaderF->bindSampler(mRSC, 0, sampler);
 
-    ProgramStore *fontStore = new ProgramStore(mRSC);
+    ProgramStore *fontStore = new ProgramStore(mRSC, true, true, true, true,
+                                               false, false,
+                                               RS_BLEND_SRC_SRC_ALPHA,
+                                               RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,
+                                               RS_DEPTH_FUNC_ALWAYS);
     mFontProgramStore.set(fontStore);
-    mFontProgramStore->setDepthFunc(RS_DEPTH_FUNC_ALWAYS);
-    mFontProgramStore->setBlendFunc(RS_BLEND_SRC_SRC_ALPHA, RS_BLEND_DST_ONE_MINUS_SRC_ALPHA);
-    mFontProgramStore->setDitherEnable(false);
-    mFontProgramStore->setDepthMask(false);
+    mFontProgramStore->init();
 }
 
 void FontState::initTextTexture() {
@@ -566,8 +562,7 @@
         indexPtr[i6 + 5] = i4 + 3;
     }
 
-    indexAlloc->deferedUploadToBufferObject(mRSC);
-    mIndexBuffer.set(indexAlloc);
+    indexAlloc->deferredUploadToBufferObject(mRSC);
 
     const Element *posElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
     const Element *texElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
@@ -584,7 +579,10 @@
     Allocation *vertexAlloc = new Allocation(mRSC, vertexDataType, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_VERTEX);
     mTextMeshPtr = (float*)vertexAlloc->getPtr();
 
-    mVertexArray.set(vertexAlloc);
+    mMesh.set(new Mesh(mRSC, 1, 1));
+    mMesh->setVertexBuffer(vertexAlloc, 0);
+    mMesh->setPrimitive(indexAlloc, RS_PRIMITIVE_TRIANGLE, 0);
+    mMesh->init();
 }
 
 // We don't want to allocate anything unless we actually draw text
@@ -624,18 +622,7 @@
         return;
     }
 
-    float *vtx = (float*)mVertexArray->getPtr();
-    float *tex = vtx + 3;
-
-    VertexArray::Attrib attribs[2];
-    attribs[0].set(GL_FLOAT, 3, 20, false, (uint32_t)vtx, "ATTRIB_position");
-    attribs[1].set(GL_FLOAT, 2, 20, false, (uint32_t)tex, "ATTRIB_texture0");
-    VertexArray va(attribs, 2);
-    va.setupGL2(mRSC, &mRSC->mStateVertexArray, &mRSC->mShaderCache);
-
-    mIndexBuffer->uploadCheck(mRSC);
-    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->getBufferObjectID());
-    glDrawElements(GL_TRIANGLES, mCurrentQuadIndex * 6, GL_UNSIGNED_SHORT, (uint16_t *)(0));
+    mMesh->renderPrimitiveRange(mRSC, 0, 0, mCurrentQuadIndex * 6);
 }
 
 void FontState::appendMeshQuad(float x1, float y1, float z1,
@@ -733,7 +720,7 @@
             String8 fullPath(getenv("ANDROID_ROOT"));
             fullPath += fontsDir;
 
-            mDefault.set(Font::create(mRSC, fullPath.string(), 16, 96));
+            mDefault.set(Font::create(mRSC, fullPath.string(), 8, mRSC->getDPI()));
         }
         currentFont = mDefault.get();
     }
@@ -786,8 +773,7 @@
 
     mFontShaderFConstant.clear();
 
-    mIndexBuffer.clear();
-    mVertexArray.clear();
+    mMesh.clear();
 
     mFontShaderF.clear();
     mFontSampler.clear();
@@ -807,10 +793,28 @@
     }
 }
 
+bool FontState::CacheTextureLine::fitBitmap(FT_Bitmap_ *bitmap, uint32_t *retOriginX, uint32_t *retOriginY) {
+    if ((uint32_t)bitmap->rows > mMaxHeight) {
+        return false;
+    }
+
+    if (mCurrentCol + (uint32_t)bitmap->width < mMaxWidth) {
+        *retOriginX = mCurrentCol;
+        *retOriginY = mCurrentRow;
+        mCurrentCol += bitmap->width;
+        mDirty = true;
+       return true;
+    }
+
+    return false;
+}
+
 namespace android {
 namespace renderscript {
 
-RsFont rsi_FontCreateFromFile(Context *rsc, char const *name, float fontSize, uint32_t dpi) {
+RsFont rsi_FontCreateFromFile(Context *rsc,
+                              char const *name, size_t name_length,
+                              float fontSize, uint32_t dpi) {
     Font *newFont = Font::create(rsc, name, fontSize, dpi);
     if (newFont) {
         newFont->incUserRef();
@@ -818,8 +822,11 @@
     return newFont;
 }
 
-RsFont rsi_FontCreateFromMemory(Context *rsc, char const *name, float fontSize, uint32_t dpi, const void *data, uint32_t dataLen) {
-    Font *newFont = Font::create(rsc, name, fontSize, dpi, data, dataLen);
+RsFont rsi_FontCreateFromMemory(Context *rsc,
+                                char const *name, size_t name_length,
+                                float fontSize, uint32_t dpi,
+                                const void *data, size_t data_length) {
+    Font *newFont = Font::create(rsc, name, fontSize, dpi, data, data_length);
     if (newFont) {
         newFont->incUserRef();
     }
diff --git a/rsFont.h b/rsFont.h
index 4820999..d18c0d9 100644
--- a/rsFont.h
+++ b/rsFont.h
@@ -23,8 +23,9 @@
 #include <utils/Vector.h>
 #include <utils/KeyedVector.h>
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+struct FT_LibraryRec_;
+struct FT_FaceRec_;
+struct FT_Bitmap_;
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -105,11 +106,12 @@
         float mBitmapMaxU;
         float mBitmapMaxV;
         // Minimize how much we call freetype
-        FT_UInt mGlyphIndex;
-        FT_Vector mAdvance;
+        int32_t mGlyphIndex;
+        int32_t mAdvanceX;
+        int32_t mAdvanceY;
         // Values below contain a glyph's origin in the bitmap
-        FT_Int mBitmapLeft;
-        FT_Int mBitmapTop;
+        int32_t mBitmapLeft;
+        int32_t mBitmapTop;
     };
 
     String8 mFontName;
@@ -120,7 +122,7 @@
     bool init(const char *name, float fontSize, uint32_t dpi, const void *data = NULL, uint32_t dataLen = 0);
 
     virtual void preDestroy() const;
-    FT_Face mFace;
+    FT_FaceRec_ *mFace;
     bool mInitialized;
     bool mHasKerning;
 
@@ -173,21 +175,7 @@
               mCurrentCol(currentCol), mDirty(false)  {
         }
 
-        bool fitBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY) {
-            if ((uint32_t)bitmap->rows > mMaxHeight) {
-                return false;
-            }
-
-            if (mCurrentCol + (uint32_t)bitmap->width < mMaxWidth) {
-                *retOriginX = mCurrentCol;
-                *retOriginY = mCurrentRow;
-                mCurrentCol += bitmap->width;
-                mDirty = true;
-               return true;
-            }
-
-            return false;
-        }
+        bool fitBitmap(FT_Bitmap_ *bitmap, uint32_t *retOriginX, uint32_t *retOriginY);
     };
 
     Vector<CacheTextureLine*> mCacheLines;
@@ -211,8 +199,8 @@
     float mWhiteThreshold;
 
     // Free type library, we only need one copy
-    FT_Library mLibrary;
-    FT_Library getLib();
+    FT_LibraryRec_ *mLibrary;
+    FT_LibraryRec_ *getLib();
     Vector<Font*> mActiveFonts;
 
     // Render state for the font
@@ -229,7 +217,7 @@
         return (uint8_t*)mTextTexture->getPtr();
     }
 
-    bool cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY);
+    bool cacheBitmap(FT_Bitmap_ *bitmap, uint32_t *retOriginX, uint32_t *retOriginY);
     const Type* getCacheTextureType() {
         return mTextTexture->getType();
     }
@@ -242,9 +230,7 @@
     uint32_t mMaxNumberOfQuads;
 
     void initVertexArrayBuffers();
-    ObjectBaseRef<Allocation> mIndexBuffer;
-    ObjectBaseRef<Allocation> mVertexArray;
-
+    ObjectBaseRef<Mesh> mMesh;
 
     bool mInitialized;
 
diff --git a/rsHandcode.h b/rsHandcode.h
deleted file mode 100644
index 6f21a35..0000000
--- a/rsHandcode.h
+++ /dev/null
@@ -1,97 +0,0 @@
-
-#define DATA_SYNC_SIZE 1024
-
-static inline void rsHCAPI_ContextFinish (RsContext rsc) {
-    ThreadIO *io = &((Context *)rsc)->mIO;
-    uint32_t size = sizeof(RS_CMD_ContextFinish);
-    RS_CMD_ContextFinish *cmd = static_cast<RS_CMD_ContextFinish *>(io->mToCore.reserve(size));
-    io->mToCore.commitSync(RS_CMD_ID_ContextFinish, size);
-}
-
-static inline void rsHCAPI_ScriptInvokeV (RsContext rsc, RsScript va, uint32_t slot, const void * data, uint32_t sizeBytes) {
-    ThreadIO *io = &((Context *)rsc)->mIO;
-    uint32_t size = sizeof(RS_CMD_ScriptInvokeV);
-    if (sizeBytes < DATA_SYNC_SIZE) {
-        size += (sizeBytes + 3) & ~3;
-    }
-    RS_CMD_ScriptInvokeV *cmd = static_cast<RS_CMD_ScriptInvokeV *>(io->mToCore.reserve(size));
-    cmd->s = va;
-    cmd->slot = slot;
-    cmd->dataLen = sizeBytes;
-    cmd->data = data;
-    if (sizeBytes < DATA_SYNC_SIZE) {
-        cmd->data = (void *)(cmd+1);
-        memcpy(cmd+1, data, sizeBytes);
-        io->mToCore.commit(RS_CMD_ID_ScriptInvokeV, size);
-    } else {
-        io->mToCore.commitSync(RS_CMD_ID_ScriptInvokeV, size);
-    }
-}
-
-
-static inline void rsHCAPI_ScriptSetVarV (RsContext rsc, RsScript va, uint32_t slot, const void * data, uint32_t sizeBytes) {
-    ThreadIO *io = &((Context *)rsc)->mIO;
-    uint32_t size = sizeof(RS_CMD_ScriptSetVarV);
-    if (sizeBytes < DATA_SYNC_SIZE) {
-        size += (sizeBytes + 3) & ~3;
-    }
-    RS_CMD_ScriptSetVarV *cmd = static_cast<RS_CMD_ScriptSetVarV *>(io->mToCore.reserve(size));
-    cmd->s = va;
-    cmd->slot = slot;
-    cmd->dataLen = sizeBytes;
-    cmd->data = data;
-    if (sizeBytes < DATA_SYNC_SIZE) {
-        cmd->data = (void *)(cmd+1);
-        memcpy(cmd+1, data, sizeBytes);
-        io->mToCore.commit(RS_CMD_ID_ScriptSetVarV, size);
-    } else {
-        io->mToCore.commitSync(RS_CMD_ID_ScriptSetVarV, size);
-    }
-}
-
-static inline void rsHCAPI_Allocation1DData (RsContext rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
-                                             uint32_t count, const void * data, uint32_t sizeBytes) {
-    ThreadIO *io = &((Context *)rsc)->mIO;
-    uint32_t size = sizeof(RS_CMD_Allocation1DData);
-    if (sizeBytes < DATA_SYNC_SIZE) {
-        size += (sizeBytes + 3) & ~3;
-    }
-    RS_CMD_Allocation1DData *cmd = static_cast<RS_CMD_Allocation1DData *>(io->mToCore.reserve(size));
-    cmd->va = va;
-    cmd->xoff = xoff;
-    cmd->lod = lod;
-    cmd->count = count;
-    cmd->data = data;
-    cmd->bytes = sizeBytes;
-    if (sizeBytes < DATA_SYNC_SIZE) {
-        cmd->data = (void *)(cmd+1);
-        memcpy(cmd+1, data, sizeBytes);
-        io->mToCore.commit(RS_CMD_ID_Allocation1DData, size);
-    } else {
-        io->mToCore.commitSync(RS_CMD_ID_Allocation1DData, size);
-    }
-}
-
-static inline void rsHCAPI_Allocation1DElementData (RsContext rsc, RsAllocation va, uint32_t x, uint32_t lod,
-                                                    const void * data, uint32_t comp_offset, uint32_t sizeBytes) {
-    ThreadIO *io = &((Context *)rsc)->mIO;
-    uint32_t size = sizeof(RS_CMD_Allocation1DElementData);
-    if (sizeBytes < DATA_SYNC_SIZE) {
-        size += (sizeBytes + 3) & ~3;
-    }
-    RS_CMD_Allocation1DElementData *cmd = static_cast<RS_CMD_Allocation1DElementData *>(io->mToCore.reserve(size));
-    cmd->va = va;
-    cmd->x = x;
-    cmd->lod = lod;
-    cmd->data = data;
-    cmd->comp_offset = comp_offset;
-    cmd->bytes = sizeBytes;
-    if (sizeBytes < DATA_SYNC_SIZE) {
-        cmd->data = (void *)(cmd+1);
-        memcpy(cmd+1, data, sizeBytes);
-        io->mToCore.commit(RS_CMD_ID_Allocation1DElementData, size);
-    } else {
-        io->mToCore.commitSync(RS_CMD_ID_Allocation1DElementData, size);
-    }
-}
-
diff --git a/rsMatrix.cpp b/rsMatrix.cpp
deleted file mode 100644
index ca41886..0000000
--- a/rsMatrix.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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.
- */
-
-#include "rsMatrix.h"
-
-#include "stdlib.h"
-#include "string.h"
-#include "math.h"
-
-using namespace android;
-using namespace android::renderscript;
-
-void Matrix::loadIdentity() {
-    set(0, 0, 1);
-    set(1, 0, 0);
-    set(2, 0, 0);
-    set(3, 0, 0);
-
-    set(0, 1, 0);
-    set(1, 1, 1);
-    set(2, 1, 0);
-    set(3, 1, 0);
-
-    set(0, 2, 0);
-    set(1, 2, 0);
-    set(2, 2, 1);
-    set(3, 2, 0);
-
-    set(0, 3, 0);
-    set(1, 3, 0);
-    set(2, 3, 0);
-    set(3, 3, 1);
-}
-
-void Matrix::load(const float *v) {
-    memcpy(m, v, sizeof(m));
-}
-
-void Matrix::load(const Matrix *v) {
-    memcpy(m, v->m, sizeof(m));
-}
-
-void Matrix::loadRotate(float rot, float x, float y, float z) {
-    float c, s;
-    m[3] = 0;
-    m[7] = 0;
-    m[11]= 0;
-    m[12]= 0;
-    m[13]= 0;
-    m[14]= 0;
-    m[15]= 1;
-    rot *= float(M_PI / 180.0f);
-    c = cosf(rot);
-    s = sinf(rot);
-
-    const float len = sqrtf(x*x + y*y + z*z);
-    if (len != 1) {
-        const float recipLen = 1.f / len;
-        x *= recipLen;
-        y *= recipLen;
-        z *= recipLen;
-    }
-    const float nc = 1.0f - c;
-    const float xy = x * y;
-    const float yz = y * z;
-    const float zx = z * x;
-    const float xs = x * s;
-    const float ys = y * s;
-    const float zs = z * s;
-    m[ 0] = x*x*nc +  c;
-    m[ 4] =  xy*nc - zs;
-    m[ 8] =  zx*nc + ys;
-    m[ 1] =  xy*nc + zs;
-    m[ 5] = y*y*nc +  c;
-    m[ 9] =  yz*nc - xs;
-    m[ 2] =  zx*nc - ys;
-    m[ 6] =  yz*nc + xs;
-    m[10] = z*z*nc +  c;
-}
-
-void Matrix::loadScale(float x, float y, float z) {
-    loadIdentity();
-    m[0] = x;
-    m[5] = y;
-    m[10] = z;
-}
-
-void Matrix::loadTranslate(float x, float y, float z) {
-    loadIdentity();
-    m[12] = x;
-    m[13] = y;
-    m[14] = z;
-}
-
-void Matrix::loadMultiply(const Matrix *lhs, const Matrix *rhs) {
-    for (int i=0 ; i<4 ; i++) {
-        float ri0 = 0;
-        float ri1 = 0;
-        float ri2 = 0;
-        float ri3 = 0;
-        for (int j=0 ; j<4 ; j++) {
-            const float rhs_ij = rhs->get(i,j);
-            ri0 += lhs->get(j,0) * rhs_ij;
-            ri1 += lhs->get(j,1) * rhs_ij;
-            ri2 += lhs->get(j,2) * rhs_ij;
-            ri3 += lhs->get(j,3) * rhs_ij;
-        }
-        set(i,0, ri0);
-        set(i,1, ri1);
-        set(i,2, ri2);
-        set(i,3, ri3);
-    }
-}
-
-void Matrix::loadOrtho(float l, float r, float b, float t, float n, float f) {
-    loadIdentity();
-    m[0] = 2 / (r - l);
-    m[5] = 2 / (t - b);
-    m[10]= -2 / (f - n);
-    m[12]= -(r + l) / (r - l);
-    m[13]= -(t + b) / (t - b);
-    m[14]= -(f + n) / (f - n);
-}
-
-void Matrix::loadFrustum(float l, float r, float b, float t, float n, float f) {
-    loadIdentity();
-    m[0] = 2 * n / (r - l);
-    m[5] = 2 * n / (t - b);
-    m[8] = (r + l) / (r - l);
-    m[9] = (t + b) / (t - b);
-    m[10]= -(f + n) / (f - n);
-    m[11]= -1;
-    m[14]= -2*f*n / (f - n);
-    m[15]= 0;
-}
-
-void Matrix::vectorMultiply(float *out, const float *in) const {
-    out[0] = (m[0] * in[0]) + (m[4] * in[1]) + (m[8] * in[2]) + m[12];
-    out[1] = (m[1] * in[0]) + (m[5] * in[1]) + (m[9] * in[2]) + m[13];
-    out[2] = (m[2] * in[0]) + (m[6] * in[1]) + (m[10] * in[2]) + m[14];
-    out[3] = (m[3] * in[0]) + (m[7] * in[1]) + (m[11] * in[2]) + m[15];
-}
diff --git a/rsMatrix2x2.cpp b/rsMatrix2x2.cpp
new file mode 100644
index 0000000..622113c
--- /dev/null
+++ b/rsMatrix2x2.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 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 "rsMatrix2x2.h"
+#include "rsMatrix3x3.h"
+#include "rsMatrix4x4.h"
+
+#include "stdlib.h"
+#include "string.h"
+#include "math.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+void Matrix2x2::loadIdentity() {
+    m[0] = 1.f;
+    m[1] = 0.f;
+    m[2] = 0.f;
+    m[3] = 1.f;
+}
+
+void Matrix2x2::load(const float *v) {
+    memcpy(m, v, sizeof(m));
+}
+
+void Matrix2x2::load(const rs_matrix2x2 *v) {
+    memcpy(m, v->m, sizeof(m));
+}
+
+void Matrix2x2::loadMultiply(const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
+    for (int i=0 ; i<2 ; i++) {
+        float ri0 = 0;
+        float ri1 = 0;
+        for (int j=0 ; j<2 ; j++) {
+            const float rhs_ij = ((const Matrix2x2 *)rhs)->get(i, j);
+            ri0 += ((const Matrix2x2 *)lhs)->get(j, 0) * rhs_ij;
+            ri1 += ((const Matrix2x2 *)lhs)->get(j, 1) * rhs_ij;
+        }
+        set(i, 0, ri0);
+        set(i, 1, ri1);
+    }
+}
+
+void Matrix2x2::transpose() {
+    float temp = m[1];
+    m[1] = m[2];
+    m[2] = temp;
+}
+
diff --git a/rsMatrix2x2.h b/rsMatrix2x2.h
new file mode 100644
index 0000000..4dcb84a
--- /dev/null
+++ b/rsMatrix2x2.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_MATRIX_2x2_H
+#define ANDROID_RS_MATRIX_2x2_H
+
+#include "rsType.h"
+
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+struct Matrix2x2 : public rs_matrix2x2 {
+    inline float get(uint32_t row, uint32_t col) const {
+        return m[row*2 + col];
+    }
+
+    inline void set(uint32_t row, uint32_t col, float v) {
+        m[row*2 + col] = v;
+    }
+
+    void loadIdentity();
+    void load(const float *);
+    void load(const rs_matrix2x2 *);
+
+    void loadMultiply(const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs);
+
+    void transpose();
+
+    void multiply(const rs_matrix2x2 *rhs) {
+        Matrix2x2 tmp;
+        tmp.loadMultiply(this, rhs);
+        load(&tmp);
+    }
+};
+
+}
+}
+
+
+
+
+#endif
+
+
+
+
+
diff --git a/rsMatrix3x3.cpp b/rsMatrix3x3.cpp
new file mode 100644
index 0000000..3f9a2d1
--- /dev/null
+++ b/rsMatrix3x3.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 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 "rsMatrix2x2.h"
+#include "rsMatrix3x3.h"
+#include "rsMatrix4x4.h"
+
+#include "stdlib.h"
+#include "string.h"
+#include "math.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+void Matrix3x3::loadIdentity() {
+    m[0] = 1.f;
+    m[1] = 0.f;
+    m[2] = 0.f;
+    m[3] = 0.f;
+    m[4] = 1.f;
+    m[5] = 0.f;
+    m[6] = 0.f;
+    m[7] = 0.f;
+    m[8] = 1.f;
+}
+
+void Matrix3x3::load(const float *v) {
+    memcpy(m, v, sizeof(m));
+}
+
+void Matrix3x3::load(const rs_matrix3x3 *v) {
+    memcpy(m, v->m, sizeof(m));
+}
+
+void Matrix3x3::loadMultiply(const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
+    for (int i=0 ; i<3 ; i++) {
+        float ri0 = 0;
+        float ri1 = 0;
+        float ri2 = 0;
+        for (int j=0 ; j<3 ; j++) {
+            const float rhs_ij = ((const Matrix3x3 *)rhs)->get(i, j);
+            ri0 += ((const Matrix3x3 *)lhs)->get(j, 0) * rhs_ij;
+            ri1 += ((const Matrix3x3 *)lhs)->get(j, 1) * rhs_ij;
+            ri2 += ((const Matrix3x3 *)lhs)->get(j, 2) * rhs_ij;
+        }
+        set(i, 0, ri0);
+        set(i, 1, ri1);
+        set(i, 2, ri2);
+    }
+}
+
+void Matrix3x3::transpose() {
+    int i, j;
+    float temp;
+    for (i = 0; i < 2; ++i) {
+        for (j = i + 1; j < 3; ++j) {
+            temp = get(i, j);
+            set(i, j, get(j, i));
+            set(j, i, temp);
+        }
+    }
+}
+
diff --git a/rsMatrix3x3.h b/rsMatrix3x3.h
new file mode 100644
index 0000000..f96d270
--- /dev/null
+++ b/rsMatrix3x3.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_MATRIX_3x3_H
+#define ANDROID_RS_MATRIX_3x3_H
+
+#include "rsType.h"
+
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+struct Matrix3x3 : public rs_matrix3x3 {
+    inline float get(uint32_t row, uint32_t col) const {
+        return m[row*3 + col];
+    }
+
+    inline void set(uint32_t row, uint32_t col, float v) {
+        m[row*3 + col] = v;
+    }
+
+    void loadIdentity();
+    void load(const float *);
+    void load(const rs_matrix3x3 *);
+
+    void loadMultiply(const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs);
+
+    void transpose();
+
+    void multiply(const rs_matrix3x3 *rhs) {
+        Matrix3x3 tmp;
+        tmp.loadMultiply(this, rhs);
+        load(&tmp);
+    }
+};
+
+}
+}
+
+
+
+
+#endif
+
+
+
+
+
diff --git a/rsMatrix4x4.cpp b/rsMatrix4x4.cpp
new file mode 100644
index 0000000..f34af47
--- /dev/null
+++ b/rsMatrix4x4.cpp
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2011 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 "rsMatrix2x2.h"
+#include "rsMatrix3x3.h"
+#include "rsMatrix4x4.h"
+
+#include "stdlib.h"
+#include "string.h"
+#include "math.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+//////////////////////////////////////////////////////////////////////////////
+// Heavy math functions
+//////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+// Returns true if the matrix was successfully inversed
+bool Matrix4x4::inverse() {
+    rs_matrix4x4 result;
+
+    int i, j;
+    for (i = 0; i < 4; ++i) {
+        for (j = 0; j < 4; ++j) {
+            // computeCofactor for int i, int j
+            int c0 = (i+1) % 4;
+            int c1 = (i+2) % 4;
+            int c2 = (i+3) % 4;
+            int r0 = (j+1) % 4;
+            int r1 = (j+2) % 4;
+            int r2 = (j+3) % 4;
+
+            float minor =
+                (m[c0 + 4*r0] * (m[c1 + 4*r1] * m[c2 + 4*r2] - m[c1 + 4*r2] * m[c2 + 4*r1]))
+                - (m[c0 + 4*r1] * (m[c1 + 4*r0] * m[c2 + 4*r2] - m[c1 + 4*r2] * m[c2 + 4*r0]))
+                + (m[c0 + 4*r2] * (m[c1 + 4*r0] * m[c2 + 4*r1] - m[c1 + 4*r1] * m[c2 + 4*r0]));
+
+            float cofactor = (i+j) & 1 ? -minor : minor;
+
+            result.m[4*i + j] = cofactor;
+        }
+    }
+
+    // Dot product of 0th column of source and 0th row of result
+    float det = m[0]*result.m[0] + m[4]*result.m[1] +
+                 m[8]*result.m[2] + m[12]*result.m[3];
+
+    if (fabs(det) < 1e-6) {
+        return false;
+    }
+
+    det = 1.0f / det;
+    for (i = 0; i < 16; ++i) {
+        m[i] = result.m[i] * det;
+    }
+
+    return true;
+}
+
+// Returns true if the matrix was successfully inversed
+bool Matrix4x4::inverseTranspose() {
+    rs_matrix4x4 result;
+
+    int i, j;
+    for (i = 0; i < 4; ++i) {
+        for (j = 0; j < 4; ++j) {
+            // computeCofactor for int i, int j
+            int c0 = (i+1) % 4;
+            int c1 = (i+2) % 4;
+            int c2 = (i+3) % 4;
+            int r0 = (j+1) % 4;
+            int r1 = (j+2) % 4;
+            int r2 = (j+3) % 4;
+
+            float minor = (m[c0 + 4*r0] * (m[c1 + 4*r1] * m[c2 + 4*r2] - m[c1 + 4*r2] * m[c2 + 4*r1]))
+                         - (m[c0 + 4*r1] * (m[c1 + 4*r0] * m[c2 + 4*r2] - m[c1 + 4*r2] * m[c2 + 4*r0]))
+                         + (m[c0 + 4*r2] * (m[c1 + 4*r0] * m[c2 + 4*r1] - m[c1 + 4*r1] * m[c2 + 4*r0]));
+
+            float cofactor = (i+j) & 1 ? -minor : minor;
+
+            result.m[4*j + i] = cofactor;
+        }
+    }
+
+    // Dot product of 0th column of source and 0th column of result
+    float det = m[0]*result.m[0] + m[4]*result.m[4] +
+                 m[8]*result.m[8] + m[12]*result.m[12];
+
+    if (fabs(det) < 1e-6) {
+        return false;
+    }
+
+    det = 1.0f / det;
+    for (i = 0; i < 16; ++i) {
+        m[i] = result.m[i] * det;
+    }
+
+    return true;
+}
+
+void Matrix4x4::transpose() {
+    int i, j;
+    float temp;
+    for (i = 0; i < 3; ++i) {
+        for (j = i + 1; j < 4; ++j) {
+            temp = m[i*4 + j];
+            m[i*4 + j] = m[j*4 + i];
+            m[j*4 + i] = temp;
+        }
+    }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////
+
+void Matrix4x4::loadIdentity() {
+    m[0] = 1.f;
+    m[1] = 0.f;
+    m[2] = 0.f;
+    m[3] = 0.f;
+    m[4] = 0.f;
+    m[5] = 1.f;
+    m[6] = 0.f;
+    m[7] = 0.f;
+    m[8] = 0.f;
+    m[9] = 0.f;
+    m[10] = 1.f;
+    m[11] = 0.f;
+    m[12] = 0.f;
+    m[13] = 0.f;
+    m[14] = 0.f;
+    m[15] = 1.f;
+}
+
+void Matrix4x4::load(const float *v) {
+    memcpy(m, v, sizeof(m));
+}
+
+void Matrix4x4::load(const rs_matrix4x4 *v) {
+    memcpy(m, v->m, sizeof(m));
+}
+
+void Matrix4x4::load(const rs_matrix3x3 *v) {
+    m[0] = v->m[0];
+    m[1] = v->m[1];
+    m[2] = v->m[2];
+    m[3] = 0.f;
+    m[4] = v->m[3];
+    m[5] = v->m[4];
+    m[6] = v->m[5];
+    m[7] = 0.f;
+    m[8] = v->m[6];
+    m[9] = v->m[7];
+    m[10] = v->m[8];
+    m[11] = 0.f;
+    m[12] = 0.f;
+    m[13] = 0.f;
+    m[14] = 0.f;
+    m[15] = 1.f;
+}
+
+void Matrix4x4::load(const rs_matrix2x2 *v) {
+    m[0] = v->m[0];
+    m[1] = v->m[1];
+    m[2] = 0.f;
+    m[3] = 0.f;
+    m[4] = v->m[2];
+    m[5] = v->m[3];
+    m[6] = 0.f;
+    m[7] = 0.f;
+    m[8] = 0.f;
+    m[9] = 0.f;
+    m[10] = 1.f;
+    m[11] = 0.f;
+    m[12] = 0.f;
+    m[13] = 0.f;
+    m[14] = 0.f;
+    m[15] = 1.f;
+}
+
+
+void Matrix4x4::loadRotate(float rot, float x, float y, float z) {
+    float c, s;
+    m[3] = 0;
+    m[7] = 0;
+    m[11]= 0;
+    m[12]= 0;
+    m[13]= 0;
+    m[14]= 0;
+    m[15]= 1;
+    rot *= float(M_PI / 180.0f);
+    c = cosf(rot);
+    s = sinf(rot);
+
+    const float len = x*x + y*y + z*z;
+    if (len != 1) {
+        const float recipLen = 1.f / sqrtf(len);
+        x *= recipLen;
+        y *= recipLen;
+        z *= recipLen;
+    }
+    const float nc = 1.0f - c;
+    const float xy = x * y;
+    const float yz = y * z;
+    const float zx = z * x;
+    const float xs = x * s;
+    const float ys = y * s;
+    const float zs = z * s;
+    m[ 0] = x*x*nc +  c;
+    m[ 4] =  xy*nc - zs;
+    m[ 8] =  zx*nc + ys;
+    m[ 1] =  xy*nc + zs;
+    m[ 5] = y*y*nc +  c;
+    m[ 9] =  yz*nc - xs;
+    m[ 2] =  zx*nc - ys;
+    m[ 6] =  yz*nc + xs;
+    m[10] = z*z*nc +  c;
+}
+
+void Matrix4x4::loadScale(float x, float y, float z) {
+    loadIdentity();
+    set(0, 0, x);
+    set(1, 1, y);
+    set(2, 2, z);
+}
+
+void Matrix4x4::loadTranslate(float x, float y, float z) {
+    loadIdentity();
+    m[12] = x;
+    m[13] = y;
+    m[14] = z;
+}
+
+void Matrix4x4::loadMultiply(const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
+    for (int i=0 ; i<4 ; i++) {
+        float ri0 = 0;
+        float ri1 = 0;
+        float ri2 = 0;
+        float ri3 = 0;
+        for (int j=0 ; j<4 ; j++) {
+            const float rhs_ij = ((const Matrix4x4 *)rhs)->get(i,j);
+            ri0 += ((const Matrix4x4 *)lhs)->get(j,0) * rhs_ij;
+            ri1 += ((const Matrix4x4 *)lhs)->get(j,1) * rhs_ij;
+            ri2 += ((const Matrix4x4 *)lhs)->get(j,2) * rhs_ij;
+            ri3 += ((const Matrix4x4 *)lhs)->get(j,3) * rhs_ij;
+        }
+        set(i,0, ri0);
+        set(i,1, ri1);
+        set(i,2, ri2);
+        set(i,3, ri3);
+    }
+}
+
+void Matrix4x4::loadOrtho(float left, float right, float bottom, float top, float near, float far) {
+    loadIdentity();
+    m[0] = 2.f / (right - left);
+    m[5] = 2.f / (top - bottom);
+    m[10]= -2.f / (far - near);
+    m[12]= -(right + left) / (right - left);
+    m[13]= -(top + bottom) / (top - bottom);
+    m[14]= -(far + near) / (far - near);
+}
+
+void Matrix4x4::loadFrustum(float left, float right, float bottom, float top, float near, float far) {
+    loadIdentity();
+    m[0] = 2.f * near / (right - left);
+    m[5] = 2.f * near / (top - bottom);
+    m[8] = (right + left) / (right - left);
+    m[9] = (top + bottom) / (top - bottom);
+    m[10]= -(far + near) / (far - near);
+    m[11]= -1.f;
+    m[14]= -2.f * far * near / (far - near);
+    m[15]= 0.f;
+}
+
+void Matrix4x4::loadPerspective(float fovy, float aspect, float near, float far) {
+    float top = near * tan((float) (fovy * M_PI / 360.0f));
+    float bottom = -top;
+    float left = bottom * aspect;
+    float right = top * aspect;
+    loadFrustum(left, right, bottom, top, near, far);
+}
+
+void Matrix4x4::vectorMultiply(float *out, const float *in) const {
+    out[0] = (m[0] * in[0]) + (m[4] * in[1]) + (m[8] * in[2]) + m[12];
+    out[1] = (m[1] * in[0]) + (m[5] * in[1]) + (m[9] * in[2]) + m[13];
+    out[2] = (m[2] * in[0]) + (m[6] * in[1]) + (m[10] * in[2]) + m[14];
+    out[3] = (m[3] * in[0]) + (m[7] * in[1]) + (m[11] * in[2]) + m[15];
+}
+
+void Matrix4x4::logv(const char *s) const {
+    LOGV("%s {%f, %f, %f, %f",  s, m[0], m[4], m[8], m[12]);
+    LOGV("%s  %f, %f, %f, %f",  s, m[1], m[5], m[9], m[13]);
+    LOGV("%s  %f, %f, %f, %f",  s, m[2], m[6], m[10], m[14]);
+    LOGV("%s  %f, %f, %f, %f}", s, m[3], m[7], m[11], m[15]);
+}
diff --git a/rsMatrix.h b/rsMatrix4x4.h
similarity index 67%
rename from rsMatrix.h
rename to rsMatrix4x4.h
index 4130b8e..d30184f 100644
--- a/rsMatrix.h
+++ b/rsMatrix4x4.h
@@ -14,57 +14,66 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_MATRIX_H
-#define ANDROID_RS_MATRIX_H
+#ifndef ANDROID_RS_MATRIX_4x4_H
+#define ANDROID_RS_MATRIX_4x4_H
 
+#include "rsType.h"
 
 
 // ---------------------------------------------------------------------------
 namespace android {
 namespace renderscript {
 
-struct Matrix {
-    float m[16];
-
-    inline float get(int i, int j) const {
-        return m[i*4 + j];
+struct Matrix4x4 : public rs_matrix4x4 {
+    float get(uint32_t row, uint32_t col) const {
+        return m[row*4 + col];
     }
 
-    inline void set(int i, int j, float v) {
-        m[i*4 + j] = v;
+    void set(uint32_t row, uint32_t col, float v) {
+        m[row*4 + col] = v;
     }
 
     void loadIdentity();
     void load(const float *);
-    void load(const Matrix *);
+    void load(const rs_matrix4x4 *);
+    void load(const rs_matrix3x3 *);
+    void load(const rs_matrix2x2 *);
 
     void loadRotate(float rot, float x, float y, float z);
     void loadScale(float x, float y, float z);
     void loadTranslate(float x, float y, float z);
-    void loadMultiply(const Matrix *lhs, const Matrix *rhs);
+    void loadMultiply(const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs);
 
     void loadOrtho(float l, float r, float b, float t, float n, float f);
     void loadFrustum(float l, float r, float b, float t, float n, float f);
+    void loadPerspective(float fovy, float aspect, float near, float far);
 
     void vectorMultiply(float *v4out, const float *v3in) const;
 
-    void multiply(const Matrix *rhs) {
-        Matrix tmp;
+    bool inverse();
+    bool inverseTranspose();
+    void transpose();
+
+    void logv(const char *s) const;
+
+
+    void multiply(const rs_matrix4x4 *rhs) {
+        Matrix4x4 tmp;
         tmp.loadMultiply(this, rhs);
         load(&tmp);
     }
     void rotate(float rot, float x, float y, float z) {
-        Matrix tmp;
+        Matrix4x4 tmp;
         tmp.loadRotate(rot, x, y, z);
         multiply(&tmp);
     }
     void scale(float x, float y, float z) {
-        Matrix tmp;
+        Matrix4x4 tmp;
         tmp.loadScale(x, y, z);
         multiply(&tmp);
     }
     void translate(float x, float y, float z) {
-        Matrix tmp;
+        Matrix4x4 tmp;
         tmp.loadTranslate(x, y, z);
         multiply(&tmp);
     }
diff --git a/rsMesh.cpp b/rsMesh.cpp
index baf4c53..3d0342d 100644
--- a/rsMesh.cpp
+++ b/rsMesh.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -14,214 +14,55 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
 
-#include <GLES/gl.h>
-#include <GLES2/gl2.h>
-#include <GLES/glext.h>
-#else
-#include "rsContextHostStub.h"
-
-#include <OpenGL/gl.h>
-#include <OpenGl/glext.h>
-#endif
-
 using namespace android;
 using namespace android::renderscript;
 
 Mesh::Mesh(Context *rsc) : ObjectBase(rsc) {
-    mPrimitives = NULL;
-    mPrimitivesCount = 0;
-    mVertexBuffers = NULL;
-    mVertexBufferCount = 0;
-    mAttribs = NULL;
-    mAttribAllocationIndex = NULL;
+    mHal.drv = NULL;
+    mHal.state.primitives = NULL;
+    mHal.state.primitivesCount = 0;
+    mHal.state.vertexBuffers = NULL;
+    mHal.state.vertexBuffersCount = 0;
+    mInitialized = false;
+}
 
-    mAttribCount = 0;
+Mesh::Mesh(Context *rsc,
+           uint32_t vertexBuffersCount,
+           uint32_t primitivesCount) : ObjectBase(rsc) {
+    mHal.drv = NULL;
+    mHal.state.primitivesCount = primitivesCount;
+    mHal.state.primitives = new Primitive_t *[mHal.state.primitivesCount];
+    for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
+        mHal.state.primitives[i] = new Primitive_t;
+    }
+    mHal.state.vertexBuffersCount = vertexBuffersCount;
+    mHal.state.vertexBuffers = new ObjectBaseRef<Allocation>[mHal.state.vertexBuffersCount];
 }
 
 Mesh::~Mesh() {
-    if (mVertexBuffers) {
-        delete[] mVertexBuffers;
+#ifndef ANDROID_RS_SERIALIZE
+    mRSC->mHal.funcs.mesh.destroy(mRSC, this);
+#endif
+
+    if (mHal.state.vertexBuffers) {
+        delete[] mHal.state.vertexBuffers;
     }
 
-    if (mPrimitives) {
-        for (uint32_t i = 0; i < mPrimitivesCount; i ++) {
-            delete mPrimitives[i];
+    if (mHal.state.primitives) {
+        for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
+            mHal.state.primitives[i]->mIndexBuffer.clear();
+            delete mHal.state.primitives[i];
         }
-        delete[] mPrimitives;
-    }
-
-    if (mAttribs) {
-        delete[] mAttribs;
-        delete[] mAttribAllocationIndex;
+        delete[] mHal.state.primitives;
     }
 }
 
-bool Mesh::isValidGLComponent(const Element *elem, uint32_t fieldIdx) {
-    // Do not create attribs for padding
-    if (elem->getFieldName(fieldIdx)[0] == '#') {
-        return false;
-    }
-
-    // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted.
-    // Filter rs types accordingly
-    RsDataType dt = elem->getField(fieldIdx)->getComponent().getType();
-    if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 &&
-       dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 &&
-       dt != RS_TYPE_SIGNED_16) {
-        return false;
-    }
-
-    // Now make sure they are not arrays
-    uint32_t arraySize = elem->getFieldArraySize(fieldIdx);
-    if (arraySize != 1) {
-        return false;
-    }
-
-    return true;
-}
-
-void Mesh::initVertexAttribs() {
-    // Count the number of gl attrs to initialize
-    mAttribCount = 0;
-    for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
-        const Element *elem = mVertexBuffers[ct]->getType()->getElement();
-        for (uint32_t ct=0; ct < elem->getFieldCount(); ct++) {
-            if (isValidGLComponent(elem, ct)) {
-                mAttribCount ++;
-            }
-        }
-    }
-
-    if (mAttribs) {
-        delete [] mAttribs;
-        delete [] mAttribAllocationIndex;
-        mAttribs = NULL;
-        mAttribAllocationIndex = NULL;
-    }
-    if (!mAttribCount) {
-        return;
-    }
-
-    mAttribs = new VertexArray::Attrib[mAttribCount];
-    mAttribAllocationIndex = new uint32_t[mAttribCount];
-
-    uint32_t userNum = 0;
-    for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
-        const Element *elem = mVertexBuffers[ct]->getType()->getElement();
-        uint32_t stride = elem->getSizeBytes();
-        for (uint32_t fieldI=0; fieldI < elem->getFieldCount(); fieldI++) {
-            const Component &c = elem->getField(fieldI)->getComponent();
-
-            if (!isValidGLComponent(elem, fieldI)) {
-                continue;
-            }
-
-            mAttribs[userNum].size = c.getVectorSize();
-            mAttribs[userNum].offset = elem->getFieldOffsetBytes(fieldI);
-            mAttribs[userNum].type = c.getGLType();
-            mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
-            mAttribs[userNum].stride = stride;
-            String8 tmp(RS_SHADER_ATTR);
-            tmp.append(elem->getFieldName(fieldI));
-            mAttribs[userNum].name.setTo(tmp.string());
-
-            // Remember which allocation this attribute came from
-            mAttribAllocationIndex[userNum] = ct;
-            userNum ++;
-        }
-    }
-}
-
-void Mesh::render(Context *rsc) const {
-    for (uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
-        renderPrimitive(rsc, ct);
-    }
-}
-
-void Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
-    if (primIndex >= mPrimitivesCount) {
-        LOGE("Invalid primitive index");
-        return;
-    }
-
-    Primitive_t *prim = mPrimitives[primIndex];
-
-    if (prim->mIndexBuffer.get()) {
-        renderPrimitiveRange(rsc, primIndex, 0, prim->mIndexBuffer->getType()->getDimX());
-        return;
-    }
-
-    renderPrimitiveRange(rsc, primIndex, 0, mVertexBuffers[0]->getType()->getDimX());
-}
-
-void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const {
-    if (len < 1 || primIndex >= mPrimitivesCount || mAttribCount == 0) {
-        LOGE("Invalid mesh or parameters");
-        return;
-    }
-
-    rsc->checkError("Mesh::renderPrimitiveRange 1");
-    for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
-        mVertexBuffers[ct]->uploadCheck(rsc);
-    }
-    // update attributes with either buffer information or data ptr based on their current state
-    for (uint32_t ct=0; ct < mAttribCount; ct++) {
-        uint32_t allocIndex = mAttribAllocationIndex[ct];
-        Allocation *alloc = mVertexBuffers[allocIndex].get();
-        if (alloc->getIsBufferObject()) {
-            mAttribs[ct].buffer = alloc->getBufferObjectID();
-            mAttribs[ct].ptr = NULL;
-        } else {
-            mAttribs[ct].buffer = 0;
-            mAttribs[ct].ptr = (const uint8_t*)alloc->getPtr();
-        }
-    }
-
-    VertexArray va(mAttribs, mAttribCount);
-    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
-
-    rsc->checkError("Mesh::renderPrimitiveRange 2");
-    Primitive_t *prim = mPrimitives[primIndex];
-    if (prim->mIndexBuffer.get()) {
-        prim->mIndexBuffer->uploadCheck(rsc);
-        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prim->mIndexBuffer->getBufferObjectID());
-        glDrawElements(prim->mGLPrimitive, len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2));
-    } else {
-        glDrawArrays(prim->mGLPrimitive, start, len);
-    }
-
-    rsc->checkError("Mesh::renderPrimitiveRange");
-}
-
-
-void Mesh::uploadAll(Context *rsc) {
-    for (uint32_t ct = 0; ct < mVertexBufferCount; ct ++) {
-        if (mVertexBuffers[ct].get()) {
-            mVertexBuffers[ct]->deferedUploadToBufferObject(rsc);
-        }
-    }
-
-    for (uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
-        if (mPrimitives[ct]->mIndexBuffer.get()) {
-            mPrimitives[ct]->mIndexBuffer->deferedUploadToBufferObject(rsc);
-        }
-    }
-}
-
-void Mesh::updateGLPrimitives() {
-    for (uint32_t i = 0; i < mPrimitivesCount; i ++) {
-        switch (mPrimitives[i]->mPrimitive) {
-            case RS_PRIMITIVE_POINT:          mPrimitives[i]->mGLPrimitive = GL_POINTS; break;
-            case RS_PRIMITIVE_LINE:           mPrimitives[i]->mGLPrimitive = GL_LINES; break;
-            case RS_PRIMITIVE_LINE_STRIP:     mPrimitives[i]->mGLPrimitive = GL_LINE_STRIP; break;
-            case RS_PRIMITIVE_TRIANGLE:       mPrimitives[i]->mGLPrimitive = GL_TRIANGLES; break;
-            case RS_PRIMITIVE_TRIANGLE_STRIP: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_STRIP; break;
-            case RS_PRIMITIVE_TRIANGLE_FAN:   mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_FAN; break;
-        }
-    }
+void Mesh::init() {
+#ifndef ANDROID_RS_SERIALIZE
+    mRSC->mHal.funcs.mesh.init(mRSC, this);
+#endif
 }
 
 void Mesh::serialize(OStream *stream) const {
@@ -232,15 +73,15 @@
     stream->addString(&name);
 
     // Store number of vertex streams
-    stream->addU32(mVertexBufferCount);
-    for (uint32_t vCount = 0; vCount < mVertexBufferCount; vCount ++) {
-        mVertexBuffers[vCount]->serialize(stream);
+    stream->addU32(mHal.state.vertexBuffersCount);
+    for (uint32_t vCount = 0; vCount < mHal.state.vertexBuffersCount; vCount ++) {
+        mHal.state.vertexBuffers[vCount]->serialize(stream);
     }
 
-    stream->addU32(mPrimitivesCount);
+    stream->addU32(mHal.state.primitivesCount);
     // Store the primitives
-    for (uint32_t pCount = 0; pCount < mPrimitivesCount; pCount ++) {
-        Primitive_t * prim = mPrimitives[pCount];
+    for (uint32_t pCount = 0; pCount < mHal.state.primitivesCount; pCount ++) {
+        Primitive_t * prim = mHal.state.primitives[pCount];
 
         stream->addU8((uint8_t)prim->mPrimitive);
 
@@ -261,57 +102,129 @@
         return NULL;
     }
 
-    Mesh * mesh = new Mesh(rsc);
-
     String8 name;
     stream->loadString(&name);
-    mesh->setName(name.string(), name.size());
 
-    mesh->mVertexBufferCount = stream->loadU32();
-    if (mesh->mVertexBufferCount) {
-        mesh->mVertexBuffers = new ObjectBaseRef<Allocation>[mesh->mVertexBufferCount];
+    uint32_t vertexBuffersCount = stream->loadU32();
+    ObjectBaseRef<Allocation> *vertexBuffers = NULL;
+    if (vertexBuffersCount) {
+        vertexBuffers = new ObjectBaseRef<Allocation>[vertexBuffersCount];
 
-        for (uint32_t vCount = 0; vCount < mesh->mVertexBufferCount; vCount ++) {
+        for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
             Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
-            mesh->mVertexBuffers[vCount].set(vertexAlloc);
+            vertexBuffers[vCount].set(vertexAlloc);
         }
     }
 
-    mesh->mPrimitivesCount = stream->loadU32();
-    if (mesh->mPrimitivesCount) {
-        mesh->mPrimitives = new Primitive_t *[mesh->mPrimitivesCount];
+    uint32_t primitivesCount = stream->loadU32();
+    ObjectBaseRef<Allocation> *indexBuffers = NULL;
+    RsPrimitive *primitives = NULL;
+    if (primitivesCount) {
+        indexBuffers = new ObjectBaseRef<Allocation>[primitivesCount];
+        primitives = new RsPrimitive[primitivesCount];
 
         // load all primitives
-        for (uint32_t pCount = 0; pCount < mesh->mPrimitivesCount; pCount ++) {
-            Primitive_t * prim = new Primitive_t;
-            mesh->mPrimitives[pCount] = prim;
-
-            prim->mPrimitive = (RsPrimitive)stream->loadU8();
+        for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
+            primitives[pCount] = (RsPrimitive)stream->loadU8();
 
             // Check to see if the index buffer was stored
             uint32_t isIndexPresent = stream->loadU32();
             if (isIndexPresent) {
                 Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
-                prim->mIndexBuffer.set(indexAlloc);
+                indexBuffers[pCount].set(indexAlloc);
             }
         }
     }
 
-    mesh->updateGLPrimitives();
-    mesh->initVertexAttribs();
-    mesh->uploadAll(rsc);
+    Mesh *mesh = new Mesh(rsc, vertexBuffersCount, primitivesCount);
+    mesh->setName(name.string(), name.size());
+    for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
+        mesh->setVertexBuffer(vertexBuffers[vCount].get(), vCount);
+    }
+    for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
+        mesh->setPrimitive(indexBuffers[pCount].get(), primitives[pCount], pCount);
+    }
 
+    // Cleanup
+    if (vertexBuffersCount) {
+        delete[] vertexBuffers;
+    }
+    if (primitivesCount) {
+        delete[] indexBuffers;
+        delete[] primitives;
+    }
+
+#ifndef ANDROID_RS_SERIALIZE
+    mesh->init();
+    mesh->uploadAll(rsc);
+#endif
     return mesh;
 }
 
+#ifndef ANDROID_RS_SERIALIZE
+
+void Mesh::render(Context *rsc) const {
+    for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
+        renderPrimitive(rsc, ct);
+    }
+}
+
+void Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
+    if (primIndex >= mHal.state.primitivesCount) {
+        LOGE("Invalid primitive index");
+        return;
+    }
+
+    Primitive_t *prim = mHal.state.primitives[primIndex];
+
+    if (prim->mIndexBuffer.get()) {
+        renderPrimitiveRange(rsc, primIndex, 0, prim->mIndexBuffer->getType()->getDimX());
+        return;
+    }
+
+    renderPrimitiveRange(rsc, primIndex, 0, mHal.state.vertexBuffers[0]->getType()->getDimX());
+}
+
+void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const {
+    if (len < 1 || primIndex >= mHal.state.primitivesCount) {
+        LOGE("Invalid mesh or parameters");
+        return;
+    }
+
+    for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) {
+        mHal.state.vertexBuffers[ct]->uploadCheck(rsc);
+    }
+
+    Primitive_t *prim = mHal.state.primitives[primIndex];
+    if (prim->mIndexBuffer.get()) {
+        prim->mIndexBuffer->uploadCheck(rsc);
+    }
+
+    mRSC->mHal.funcs.mesh.draw(mRSC, this, primIndex, start, len);
+}
+
+void Mesh::uploadAll(Context *rsc) {
+    for (uint32_t ct = 0; ct < mHal.state.vertexBuffersCount; ct ++) {
+        if (mHal.state.vertexBuffers[ct].get()) {
+            mHal.state.vertexBuffers[ct]->deferredUploadToBufferObject(rsc);
+        }
+    }
+
+    for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
+        if (mHal.state.primitives[ct]->mIndexBuffer.get()) {
+            mHal.state.primitives[ct]->mIndexBuffer->deferredUploadToBufferObject(rsc);
+        }
+    }
+}
+
 void Mesh::computeBBox() {
     float *posPtr = NULL;
     uint32_t vectorSize = 0;
     uint32_t stride = 0;
     uint32_t numVerts = 0;
     // First we need to find the position ptr and stride
-    for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
-        const Type *bufferType = mVertexBuffers[ct]->getType();
+    for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) {
+        const Type *bufferType = mHal.state.vertexBuffers[ct]->getType();
         const Element *bufferElem = bufferType->getElement();
 
         for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
@@ -319,7 +232,7 @@
                 vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
                 stride = bufferElem->getSizeBytes() / sizeof(float);
                 uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
-                posPtr = (float*)((uint8_t*)mVertexBuffers[ct]->getPtr() + offset);
+                posPtr = (float*)((uint8_t*)mHal.state.vertexBuffers[ct]->getPtr() + offset);
                 numVerts = bufferType->getDimX();
                 break;
             }
@@ -347,84 +260,63 @@
     }
 }
 
-
-MeshContext::MeshContext() {
-}
-
-MeshContext::~MeshContext() {
-}
-
 namespace android {
 namespace renderscript {
 
-RsMesh rsi_MeshCreate(Context *rsc, uint32_t vtxCount, uint32_t idxCount) {
-    Mesh *sm = new Mesh(rsc);
+RsMesh rsi_MeshCreate(Context *rsc,
+                      RsAllocation *vtx, uint32_t vtxCount,
+                      RsAllocation *idx, uint32_t idxCount,
+                      uint32_t *primType, uint32_t primTypeCount) {
+    rsAssert(idxCount == primTypeCount);
+    Mesh *sm = new Mesh(rsc, vtxCount, idxCount);
     sm->incUserRef();
 
-    sm->mPrimitivesCount = idxCount;
-    sm->mPrimitives = new Mesh::Primitive_t *[sm->mPrimitivesCount];
-    for (uint32_t ct = 0; ct < idxCount; ct ++) {
-        sm->mPrimitives[ct] = new Mesh::Primitive_t;
+    for (uint32_t i = 0; i < vtxCount; i ++) {
+        sm->setVertexBuffer((Allocation*)vtx[i], i);
     }
 
-    sm->mVertexBufferCount = vtxCount;
-    sm->mVertexBuffers = new ObjectBaseRef<Allocation>[vtxCount];
+    for (uint32_t i = 0; i < idxCount; i ++) {
+        sm->setPrimitive((Allocation*)idx[i], (RsPrimitive)primType[i], i);
+    }
+
+    sm->init();
 
     return sm;
 }
 
-void rsi_MeshBindVertex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t slot) {
-    Mesh *sm = static_cast<Mesh *>(mv);
-    rsAssert(slot < sm->mVertexBufferCount);
-
-    sm->mVertexBuffers[slot].set((Allocation *)va);
-}
-
-void rsi_MeshBindIndex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t primType, uint32_t slot) {
-    Mesh *sm = static_cast<Mesh *>(mv);
-    rsAssert(slot < sm->mPrimitivesCount);
-
-    sm->mPrimitives[slot]->mIndexBuffer.set((Allocation *)va);
-    sm->mPrimitives[slot]->mPrimitive = (RsPrimitive)primType;
-    sm->updateGLPrimitives();
-}
-
-void rsi_MeshInitVertexAttribs(Context *rsc, RsMesh mv) {
-    Mesh *sm = static_cast<Mesh *>(mv);
-    sm->initVertexAttribs();
-}
-
 }}
 
 void rsaMeshGetVertexBufferCount(RsContext con, RsMesh mv, int32_t *numVtx) {
     Mesh *sm = static_cast<Mesh *>(mv);
-    *numVtx = sm->mVertexBufferCount;
+    *numVtx = sm->mHal.state.vertexBuffersCount;
 }
 
 void rsaMeshGetIndexCount(RsContext con, RsMesh mv, int32_t *numIdx) {
     Mesh *sm = static_cast<Mesh *>(mv);
-    *numIdx = sm->mPrimitivesCount;
+    *numIdx = sm->mHal.state.primitivesCount;
 }
 
 void rsaMeshGetVertices(RsContext con, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount) {
     Mesh *sm = static_cast<Mesh *>(mv);
-    rsAssert(vtxDataCount == sm->mVertexBufferCount);
+    rsAssert(vtxDataCount == sm->mHal.state.vertexBuffersCount);
 
     for (uint32_t ct = 0; ct < vtxDataCount; ct ++) {
-        vtxData[ct] = sm->mVertexBuffers[ct].get();
-        sm->mVertexBuffers[ct]->incUserRef();
+        vtxData[ct] = sm->mHal.state.vertexBuffers[ct].get();
+        sm->mHal.state.vertexBuffers[ct]->incUserRef();
     }
 }
 
 void rsaMeshGetIndices(RsContext con, RsMesh mv, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount) {
     Mesh *sm = static_cast<Mesh *>(mv);
-    rsAssert(idxDataCount == sm->mPrimitivesCount);
+    rsAssert(idxDataCount == sm->mHal.state.primitivesCount);
 
     for (uint32_t ct = 0; ct < idxDataCount; ct ++) {
-        va[ct] = sm->mPrimitives[ct]->mIndexBuffer.get();
-        primType[ct] = sm->mPrimitives[ct]->mPrimitive;
-        if (sm->mPrimitives[ct]->mIndexBuffer.get()) {
-            sm->mPrimitives[ct]->mIndexBuffer->incUserRef();
+        va[ct] = sm->mHal.state.primitives[ct]->mIndexBuffer.get();
+        primType[ct] = sm->mHal.state.primitives[ct]->mPrimitive;
+        if (sm->mHal.state.primitives[ct]->mIndexBuffer.get()) {
+            sm->mHal.state.primitives[ct]->mIndexBuffer->incUserRef();
         }
     }
 }
+
+#endif
diff --git a/rsMesh.h b/rsMesh.h
index 410b70b..ed1e93d 100644
--- a/rsMesh.h
+++ b/rsMesh.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -29,64 +29,71 @@
 class Mesh : public ObjectBase {
 public:
     Mesh(Context *);
+    Mesh(Context *, uint32_t vertexBuffersCount, uint32_t primitivesCount);
     ~Mesh();
 
-    // Contains vertex data
-    // Position, normal, texcoord, etc could either be strided in one allocation
-    // of provided separetely in multiple ones
-    ObjectBaseRef<Allocation> *mVertexBuffers;
-    uint32_t mVertexBufferCount;
-
     // Either mIndexBuffer, mPrimitiveBuffer or both could have a NULL reference
     // If both are null, mPrimitive only would be used to render the mesh
-    struct Primitive_t
-    {
+    struct Primitive_t {
         ObjectBaseRef<Allocation> mIndexBuffer;
-
         RsPrimitive mPrimitive;
-        uint32_t mGLPrimitive;
     };
 
-    Primitive_t ** mPrimitives;
-    uint32_t mPrimitivesCount;
+    virtual void serialize(OStream *stream) const;
+    virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_MESH; }
+    static Mesh *createFromStream(Context *rsc, IStream *stream);
+    void init();
+
+    struct Hal {
+        mutable void *drv;
+
+        struct State {
+            // Contains vertex data
+            // Position, normal, texcoord, etc could either be strided in one allocation
+            // of provided separetely in multiple ones
+            ObjectBaseRef<Allocation> *vertexBuffers;
+            uint32_t vertexBuffersCount;
+
+            Primitive_t ** primitives;
+            uint32_t primitivesCount;
+        };
+        State state;
+    };
+    Hal mHal;
+
+    void setVertexBuffer(Allocation *vb, uint32_t index) {
+        mHal.state.vertexBuffers[index].set(vb);
+    }
+
+    void setPrimitive(Allocation *idx, RsPrimitive prim, uint32_t index) {
+        mHal.state.primitives[index]->mIndexBuffer.set(idx);
+        mHal.state.primitives[index]->mPrimitive = prim;
+    }
 
     void render(Context *) const;
     void renderPrimitive(Context *, uint32_t primIndex) const;
     void renderPrimitiveRange(Context *, uint32_t primIndex, uint32_t start, uint32_t len) const;
     void uploadAll(Context *);
-    void updateGLPrimitives();
-
-    virtual void serialize(OStream *stream) const;
-    virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_MESH; }
-    static Mesh *createFromStream(Context *rsc, IStream *stream);
 
     // Bounding volumes
     float mBBoxMin[3];
     float mBBoxMax[3];
     void computeBBox();
-
-    void initVertexAttribs();
-
 protected:
-    bool isValidGLComponent(const Element *elem, uint32_t fieldIdx);
-    // Attribues that allow us to map to GL
-    VertexArray::Attrib *mAttribs;
-    // This allows us to figure out which allocation the attribute
-    // belongs to. In the event the allocation is uploaded to GL
-    // buffer, it lets us properly map it
-    uint32_t *mAttribAllocationIndex;
-    uint32_t mAttribCount;
+    bool mInitialized;
 };
 
 class MeshContext {
 public:
-    MeshContext();
-    ~MeshContext();
+    MeshContext() {
+    }
+    ~MeshContext() {
+    }
 };
 
 }
 }
-#endif //ANDROID_RS_TRIANGLE_MESH_H
+#endif //ANDROID_RS_MESH_H
 
 
 
diff --git a/rsObjectBase.cpp b/rsObjectBase.cpp
index aec2f67..f428f94 100644
--- a/rsObjectBase.cpp
+++ b/rsObjectBase.cpp
@@ -15,13 +15,7 @@
  */
 
 #include "rsObjectBase.h"
-
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#else
-#include "rsContextHostStub.h"
-#endif
-
 
 using namespace android;
 using namespace android::renderscript;
diff --git a/rsProgram.cpp b/rsProgram.cpp
index 39b85e3..b1d8f48 100644
--- a/rsProgram.cpp
+++ b/rsProgram.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -14,69 +14,48 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#else
-#include "rsContextHostStub.h"
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
 #include "rsProgram.h"
 
 using namespace android;
 using namespace android::renderscript;
 
-Program::Program(Context *rsc) : ObjectBase(rsc) {
-   initMemberVars();
-}
-
 Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
                  const uint32_t * params, uint32_t paramLength)
-    : ObjectBase(rsc) {
+    : ProgramBase(rsc) {
 
     initMemberVars();
     for (uint32_t ct=0; ct < paramLength; ct+=2) {
         if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
-            mInputCount++;
-        }
-        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
-            mOutputCount++;
+            mHal.state.inputElementsCount++;
         }
         if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
-            mConstantCount++;
+            mHal.state.constantsCount++;
         }
         if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
-            mTextureCount++;
+            mHal.state.texturesCount++;
         }
     }
 
-    mTextures = new ObjectBaseRef<Allocation>[mTextureCount];
-    mSamplers = new ObjectBaseRef<Sampler>[mTextureCount];
-    mTextureTargets = new RsTextureTarget[mTextureCount];
-    mInputElements = new ObjectBaseRef<Element>[mInputCount];
-    mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
-    mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
-    mConstants = new ObjectBaseRef<Allocation>[mConstantCount];
+    mHal.state.textures = new ObjectBaseRef<Allocation>[mHal.state.texturesCount];
+    mHal.state.samplers = new ObjectBaseRef<Sampler>[mHal.state.texturesCount];
+    mHal.state.textureTargets = new RsTextureTarget[mHal.state.texturesCount];
+    mHal.state.inputElements = new ObjectBaseRef<Element>[mHal.state.inputElementsCount];
+    mHal.state.constantTypes = new ObjectBaseRef<Type>[mHal.state.constantsCount];
+    mHal.state.constants = new ObjectBaseRef<Allocation>[mHal.state.constantsCount];
 
     uint32_t input = 0;
-    uint32_t output = 0;
     uint32_t constant = 0;
     uint32_t texture = 0;
     for (uint32_t ct=0; ct < paramLength; ct+=2) {
         if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
-            mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
-        }
-        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
-            mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1]));
+            mHal.state.inputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
         }
         if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
-            mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
+            mHal.state.constantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
         }
         if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
-            mTextureTargets[texture++] = (RsTextureTarget)params[ct+1];
+            mHal.state.textureTargets[texture++] = (RsTextureTarget)params[ct+1];
         }
     }
     mIsInternal = false;
@@ -88,88 +67,69 @@
         shaderLength -= internalTokenLen;
     }
     mUserShader.setTo(shaderText, shaderLength);
-
-    initAttribAndUniformArray();
 }
 
 Program::~Program() {
-    if (mRSC->props.mLogShaders) {
-        LOGV("Program::~Program with shader id %u", mShaderID);
-    }
 
-    if (mShaderID) {
-        glDeleteShader(mShaderID);
-    }
-
-    for (uint32_t ct=0; ct < mConstantCount; ct++) {
+    for (uint32_t ct=0; ct < mHal.state.constantsCount; ct++) {
         bindAllocation(NULL, NULL, ct);
     }
 
-    for (uint32_t ct=0; ct < mTextureCount; ct++) {
+    for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) {
         bindTexture(NULL, ct, NULL);
         bindSampler(NULL, ct, NULL);
     }
-    delete[] mTextures;
-    delete[] mSamplers;
-    delete[] mTextureTargets;
-    delete[] mInputElements;
-    delete[] mOutputElements;
-    delete[] mConstantTypes;
-    delete[] mConstants;
-    delete[] mAttribNames;
-    delete[] mUniformNames;
-    delete[] mUniformArraySizes;
-    mInputCount = 0;
-    mOutputCount = 0;
-    mConstantCount = 0;
+    delete[] mHal.state.textures;
+    delete[] mHal.state.samplers;
+    delete[] mHal.state.textureTargets;
+    delete[] mHal.state.inputElements;
+    delete[] mHal.state.constantTypes;
+    delete[] mHal.state.constants;
+    mHal.state.inputElementsCount = 0;
+    mHal.state.constantsCount = 0;
+    mHal.state.texturesCount = 0;
 }
 
 void Program::initMemberVars() {
     mDirty = true;
-    mShaderID = 0;
-    mAttribCount = 0;
-    mUniformCount = 0;
-    mTextureCount = 0;
 
-    mTextures = NULL;
-    mSamplers = NULL;
-    mTextureTargets = NULL;
-    mInputElements = NULL;
-    mOutputElements = NULL;
-    mConstantTypes = NULL;
-    mConstants = NULL;
-    mAttribNames = NULL;
-    mUniformNames = NULL;
-    mUniformArraySizes = NULL;
-    mInputCount = 0;
-    mOutputCount = 0;
-    mConstantCount = 0;
-    mIsValid = false;
+    mHal.drv = NULL;
+    mHal.state.textures = NULL;
+    mHal.state.samplers = NULL;
+    mHal.state.textureTargets = NULL;
+    mHal.state.inputElements = NULL;
+    mHal.state.constantTypes = NULL;
+    mHal.state.constants = NULL;
+
+    mHal.state.inputElementsCount = 0;
+    mHal.state.constantsCount = 0;
+    mHal.state.texturesCount = 0;
+
     mIsInternal = false;
 }
 
 void Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot) {
     if (alloc != NULL) {
-        if (slot >= mConstantCount) {
+        if (slot >= mHal.state.constantsCount) {
             LOGE("Attempt to bind alloc at slot %u, on shader id %u, but const count is %u",
-                 slot, (uint32_t)this, mConstantCount);
+                 slot, (uint32_t)this, mHal.state.constantsCount);
             rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
             return;
         }
-        if (!alloc->getType()->isEqual(mConstantTypes[slot].get())) {
+        if (!alloc->getType()->isEqual(mHal.state.constantTypes[slot].get())) {
             LOGE("Attempt to bind alloc at slot %u, on shader id %u, but types mismatch",
                  slot, (uint32_t)this);
             rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
             return;
         }
     }
-    if (mConstants[slot].get() == alloc) {
+    if (mHal.state.constants[slot].get() == alloc) {
         return;
     }
-    if (mConstants[slot].get()) {
-        mConstants[slot].get()->removeProgramToDirty(this);
+    if (mHal.state.constants[slot].get()) {
+        mHal.state.constants[slot].get()->removeProgramToDirty(this);
     }
-    mConstants[slot].set(alloc);
+    mHal.state.constants[slot].set(alloc);
     if (alloc) {
         alloc->addProgramToDirty(this);
     }
@@ -177,327 +137,33 @@
 }
 
 void Program::bindTexture(Context *rsc, uint32_t slot, Allocation *a) {
-    if (slot >= mTextureCount) {
-        LOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mTextureCount);
+    if (slot >= mHal.state.texturesCount) {
+        LOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mHal.state.texturesCount);
         rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind texture");
         return;
     }
 
-    if (a && a->getType()->getDimFaces() && mTextureTargets[slot] != RS_TEXTURE_CUBE) {
+    if (a && a->getType()->getDimFaces() && mHal.state.textureTargets[slot] != RS_TEXTURE_CUBE) {
         LOGE("Attempt to bind cubemap to slot %u but 2d texture needed", slot);
         rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind cubemap to 2d texture slot");
         return;
     }
 
-    //LOGE("bindtex %i %p", slot, a);
-    mTextures[slot].set(a);
+    mHal.state.textures[slot].set(a);
     mDirty = true;
 }
 
 void Program::bindSampler(Context *rsc, uint32_t slot, Sampler *s) {
-    if (slot >= mTextureCount) {
-        LOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mTextureCount);
+    if (slot >= mHal.state.texturesCount) {
+        LOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mHal.state.texturesCount);
         rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind sampler");
         return;
     }
 
-    mSamplers[slot].set(s);
+    mHal.state.samplers[slot].set(s);
     mDirty = true;
 }
 
-String8 Program::getGLSLInputString() const {
-    String8 s;
-    for (uint32_t ct=0; ct < mInputCount; ct++) {
-        const Element *e = mInputElements[ct].get();
-        for (uint32_t field=0; field < e->getFieldCount(); field++) {
-            const Element *f = e->getField(field);
-
-            // Cannot be complex
-            rsAssert(!f->getFieldCount());
-            switch (f->getComponent().getVectorSize()) {
-            case 1: s.append("attribute float ATTRIB_"); break;
-            case 2: s.append("attribute vec2 ATTRIB_"); break;
-            case 3: s.append("attribute vec3 ATTRIB_"); break;
-            case 4: s.append("attribute vec4 ATTRIB_"); break;
-            default:
-                rsAssert(0);
-            }
-
-            s.append(e->getFieldName(field));
-            s.append(";\n");
-        }
-    }
-    return s;
-}
-
-String8 Program::getGLSLOutputString() const {
-    return String8();
-}
-
-String8 Program::getGLSLConstantString() const {
-    return String8();
-}
-
-void Program::createShader() {
-}
-
-bool Program::loadShader(Context *rsc, uint32_t type) {
-    mShaderID = glCreateShader(type);
-    rsAssert(mShaderID);
-
-    if (rsc->props.mLogShaders) {
-        LOGV("Loading shader type %x, ID %i", type, mShaderID);
-        LOGV("%s", mShader.string());
-    }
-
-    if (mShaderID) {
-        const char * ss = mShader.string();
-        glShaderSource(mShaderID, 1, &ss, NULL);
-        glCompileShader(mShaderID);
-
-        GLint compiled = 0;
-        glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
-        if (!compiled) {
-            GLint infoLen = 0;
-            glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
-            if (infoLen) {
-                char* buf = (char*) malloc(infoLen);
-                if (buf) {
-                    glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
-                    LOGE("Could not compile shader \n%s\n", buf);
-                    free(buf);
-                }
-                glDeleteShader(mShaderID);
-                mShaderID = 0;
-                rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,");
-                return false;
-            }
-        }
-    }
-
-    if (rsc->props.mLogShaders) {
-        LOGV("--Shader load result %x ", glGetError());
-    }
-    mIsValid = true;
-    return true;
-}
-
-void Program::setShader(const char *txt, uint32_t len) {
-    mUserShader.setTo(txt, len);
-}
-
-void Program::appendUserConstants() {
-    for (uint32_t ct=0; ct < mConstantCount; ct++) {
-        const Element *e = mConstantTypes[ct]->getElement();
-        for (uint32_t field=0; field < e->getFieldCount(); field++) {
-            const Element *f = e->getField(field);
-            const char *fn = e->getFieldName(field);
-
-            if (fn[0] == '#') {
-                continue;
-            }
-
-            // Cannot be complex
-            rsAssert(!f->getFieldCount());
-            if (f->getType() == RS_TYPE_MATRIX_4X4) {
-                mShader.append("uniform mat4 UNI_");
-            } else if (f->getType() == RS_TYPE_MATRIX_3X3) {
-                mShader.append("uniform mat3 UNI_");
-            } else if (f->getType() == RS_TYPE_MATRIX_2X2) {
-                mShader.append("uniform mat2 UNI_");
-            } else {
-                switch (f->getComponent().getVectorSize()) {
-                case 1: mShader.append("uniform float UNI_"); break;
-                case 2: mShader.append("uniform vec2 UNI_"); break;
-                case 3: mShader.append("uniform vec3 UNI_"); break;
-                case 4: mShader.append("uniform vec4 UNI_"); break;
-                default:
-                    rsAssert(0);
-                }
-            }
-
-            mShader.append(fn);
-            if (e->getFieldArraySize(field) > 1) {
-                mShader.appendFormat("[%d]", e->getFieldArraySize(field));
-            }
-            mShader.append(";\n");
-        }
-    }
-}
-
-void Program::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
-    RsDataType dataType = field->getType();
-    uint32_t elementSize = field->getSizeBytes() / sizeof(float);
-    for (uint32_t i = 0; i < arraySize; i ++) {
-        if (arraySize > 1) {
-            LOGV("Array Element [%u]", i);
-        }
-        if (dataType == RS_TYPE_MATRIX_4X4) {
-            LOGV("Matrix4x4");
-            LOGV("{%f, %f, %f, %f",  fd[0], fd[4], fd[8], fd[12]);
-            LOGV(" %f, %f, %f, %f",  fd[1], fd[5], fd[9], fd[13]);
-            LOGV(" %f, %f, %f, %f",  fd[2], fd[6], fd[10], fd[14]);
-            LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
-        } else if (dataType == RS_TYPE_MATRIX_3X3) {
-            LOGV("Matrix3x3");
-            LOGV("{%f, %f, %f",  fd[0], fd[3], fd[6]);
-            LOGV(" %f, %f, %f",  fd[1], fd[4], fd[7]);
-            LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
-        } else if (dataType == RS_TYPE_MATRIX_2X2) {
-            LOGV("Matrix2x2");
-            LOGV("{%f, %f",  fd[0], fd[2]);
-            LOGV(" %f, %f}", fd[1], fd[3]);
-        } else {
-            switch (field->getComponent().getVectorSize()) {
-            case 1:
-                LOGV("Uniform 1 = %f", fd[0]);
-                break;
-            case 2:
-                LOGV("Uniform 2 = %f %f", fd[0], fd[1]);
-                break;
-            case 3:
-                LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
-                break;
-            case 4:
-                LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
-                break;
-            default:
-                rsAssert(0);
-            }
-        }
-        LOGE("Element size %u data=%p", elementSize, fd);
-        fd += elementSize;
-        LOGE("New data=%p", fd);
-    }
-}
-
-void Program::setUniform(Context *rsc, const Element *field, const float *fd,
-                         int32_t slot, uint32_t arraySize ) {
-    RsDataType dataType = field->getType();
-    if (dataType == RS_TYPE_MATRIX_4X4) {
-        glUniformMatrix4fv(slot, arraySize, GL_FALSE, fd);
-    } else if (dataType == RS_TYPE_MATRIX_3X3) {
-        glUniformMatrix3fv(slot, arraySize, GL_FALSE, fd);
-    } else if (dataType == RS_TYPE_MATRIX_2X2) {
-        glUniformMatrix2fv(slot, arraySize, GL_FALSE, fd);
-    } else {
-        switch (field->getComponent().getVectorSize()) {
-        case 1:
-            glUniform1fv(slot, arraySize, fd);
-            break;
-        case 2:
-            glUniform2fv(slot, arraySize, fd);
-            break;
-        case 3:
-            glUniform3fv(slot, arraySize, fd);
-            break;
-        case 4:
-            glUniform4fv(slot, arraySize, fd);
-            break;
-        default:
-            rsAssert(0);
-        }
-    }
-}
-
-void Program::setupUserConstants(Context *rsc, ShaderCache *sc, bool isFragment) {
-    uint32_t uidx = 0;
-    for (uint32_t ct=0; ct < mConstantCount; ct++) {
-        Allocation *alloc = mConstants[ct].get();
-        if (!alloc) {
-            LOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set", (uint32_t)this, ct);
-            rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
-            continue;
-        }
-
-        const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
-        const Element *e = mConstantTypes[ct]->getElement();
-        for (uint32_t field=0; field < e->getFieldCount(); field++) {
-            const Element *f = e->getField(field);
-            const char *fieldName = e->getFieldName(field);
-            // If this field is padding, skip it
-            if (fieldName[0] == '#') {
-                continue;
-            }
-
-            uint32_t offset = e->getFieldOffsetBytes(field);
-            const float *fd = reinterpret_cast<const float *>(&data[offset]);
-
-            int32_t slot = -1;
-            uint32_t arraySize = 1;
-            if (!isFragment) {
-                slot = sc->vtxUniformSlot(uidx);
-                arraySize = sc->vtxUniformSize(uidx);
-            } else {
-                slot = sc->fragUniformSlot(uidx);
-                arraySize = sc->fragUniformSize(uidx);
-            }
-            if (rsc->props.mLogShadersUniforms) {
-                LOGV("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
-            }
-            uidx ++;
-            if (slot < 0) {
-                continue;
-            }
-
-            if (rsc->props.mLogShadersUniforms) {
-                logUniform(f, fd, arraySize);
-            }
-            setUniform(rsc, f, fd, slot, arraySize);
-        }
-    }
-}
-
-void Program::initAttribAndUniformArray() {
-    mAttribCount = 0;
-    for (uint32_t ct=0; ct < mInputCount; ct++) {
-        const Element *elem = mInputElements[ct].get();
-        for (uint32_t field=0; field < elem->getFieldCount(); field++) {
-            if (elem->getFieldName(field)[0] != '#') {
-                mAttribCount ++;
-            }
-        }
-    }
-
-    mUniformCount = 0;
-    for (uint32_t ct=0; ct < mConstantCount; ct++) {
-        const Element *elem = mConstantTypes[ct]->getElement();
-
-        for (uint32_t field=0; field < elem->getFieldCount(); field++) {
-            if (elem->getFieldName(field)[0] != '#') {
-                mUniformCount ++;
-            }
-        }
-    }
-    mUniformCount += mTextureCount;
-
-    if (mAttribCount) {
-        mAttribNames = new String8[mAttribCount];
-    }
-    if (mUniformCount) {
-        mUniformNames = new String8[mUniformCount];
-        mUniformArraySizes = new uint32_t[mUniformCount];
-    }
-}
-
-void Program::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix) {
-    rsAssert(e->getFieldCount());
-    for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
-        const Element *ce = e->getField(ct);
-        if (ce->getFieldCount()) {
-            initAddUserElement(ce, names, arrayLengths, count, prefix);
-        } else if (e->getFieldName(ct)[0] != '#') {
-            String8 tmp(prefix);
-            tmp.append(e->getFieldName(ct));
-            names[*count].setTo(tmp.string());
-            if (arrayLengths) {
-                arrayLengths[*count] = e->getFieldArraySize(ct);
-            }
-            (*count)++;
-        }
-    }
-}
-
 namespace android {
 namespace renderscript {
 
diff --git a/rsProgram.h b/rsProgram.h
index c48464d..948ba3e 100644
--- a/rsProgram.h
+++ b/rsProgram.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -17,101 +17,68 @@
 #ifndef ANDROID_RS_PROGRAM_H
 #define ANDROID_RS_PROGRAM_H
 
-#include "rsObjectBase.h"
+#include "rsProgramBase.h"
 #include "rsElement.h"
 
 // ---------------------------------------------------------------------------
 namespace android {
 namespace renderscript {
-class ShaderCache;
 
 #define RS_SHADER_INTERNAL "//rs_shader_internal\n"
 #define RS_SHADER_ATTR "ATTRIB_"
 #define RS_SHADER_UNI "UNI_"
 
-class Program : public ObjectBase {
+class Program : public ProgramBase {
 public:
 
-    Program(Context *);
     Program(Context *, const char * shaderText, uint32_t shaderLength,
                        const uint32_t * params, uint32_t paramLength);
     virtual ~Program();
 
     void bindAllocation(Context *, Allocation *, uint32_t slot);
-    virtual void createShader();
 
     bool isUserProgram() const {return !mIsInternal;}
 
     void bindTexture(Context *, uint32_t slot, Allocation *);
     void bindSampler(Context *, uint32_t slot, Sampler *);
 
-    uint32_t getShaderID() const {return mShaderID;}
-    void setShader(const char *, uint32_t len);
+    struct Hal {
+        mutable void *drv;
 
-    uint32_t getAttribCount() const {return mAttribCount;}
-    uint32_t getUniformCount() const {return mUniformCount;}
-    const String8 & getAttribName(uint32_t i) const {return mAttribNames[i];}
-    const String8 & getUniformName(uint32_t i) const {return mUniformNames[i];}
-    uint32_t getUniformArraySize(uint32_t i) const {return mUniformArraySizes[i];}
+        struct State {
+            // The difference between Textures and Constants is how they are accessed
+            // Texture lookups go though a sampler which in effect converts normalized
+            // coordinates into type specific.  Multiple samples may also be taken
+            // and filtered.
+            //
+            // Constants are strictly accessed by the shader code
+            ObjectBaseRef<Allocation> *textures;
+            RsTextureTarget *textureTargets;
+            uint32_t texturesCount;
 
-    String8 getGLSLInputString() const;
-    String8 getGLSLOutputString() const;
-    String8 getGLSLConstantString() const;
+            ObjectBaseRef<Sampler> *samplers;
+            uint32_t samplersCount;
 
-    bool isValid() const {return mIsValid;}
-    void forceDirty() const {mDirty = true;}
+            ObjectBaseRef<Allocation> *constants;
+            ObjectBaseRef<Type> *constantTypes;
+            uint32_t constantsCount;
+
+            ObjectBaseRef<Element> *inputElements;
+            uint32_t inputElementsCount;
+        };
+        State state;
+    };
+    Hal mHal;
 
 protected:
-    // Components not listed in "in" will be passed though
-    // unless overwritten by components in out.
-    ObjectBaseRef<Element> *mInputElements;
-    ObjectBaseRef<Element> *mOutputElements;
-    ObjectBaseRef<Type> *mConstantTypes;
-    ObjectBaseRef<Allocation> *mConstants;
-    uint32_t mInputCount;
-    uint32_t mOutputCount;
-    uint32_t mConstantCount;
-    bool mIsValid;
     bool mIsInternal;
-
-    // Applies to vertex and fragment shaders only
-    void appendUserConstants();
-    void setupUserConstants(Context *rsc, ShaderCache *sc, bool isFragment);
-    void initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix);
-
-    void initAttribAndUniformArray();
-
-    mutable bool mDirty;
-    String8 mShader;
     String8 mUserShader;
-    uint32_t mShaderID;
-
-    uint32_t mTextureCount;
-    uint32_t mAttribCount;
-    uint32_t mUniformCount;
-    String8 *mAttribNames;
-    String8 *mUniformNames;
-    uint32_t *mUniformArraySizes;
-
-    void logUniform(const Element *field, const float *fd, uint32_t arraySize );
-    void setUniform(Context *rsc, const Element *field, const float *fd, int32_t slot, uint32_t arraySize );
     void initMemberVars();
-
-    // The difference between Textures and Constants is how they are accessed
-    // Texture lookups go though a sampler which in effect converts normalized
-    // coordinates into type specific.  Multiple samples may also be taken
-    // and filtered.
-    //
-    // Constants are strictly accessed by programetic loads.
-    ObjectBaseRef<Allocation> *mTextures;
-    ObjectBaseRef<Sampler> *mSamplers;
-    RsTextureTarget *mTextureTargets;
-    bool loadShader(Context *, uint32_t type);
 };
 
 }
 }
-#endif
+#endif // ANDROID_RS_PROGRAM_H
 
 
 
diff --git a/rsProgramBase.h b/rsProgramBase.h
new file mode 100644
index 0000000..80da453
--- /dev/null
+++ b/rsProgramBase.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_PROGRAM_BASE_H
+#define ANDROID_RS_PROGRAM_BASE_H
+
+#include "rsObjectBase.h"
+#include "rsElement.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class ProgramBase : public ObjectBase {
+public:
+    ProgramBase(Context *rsc) : ObjectBase(rsc) {
+        mDirty = true;
+    }
+
+    void forceDirty() const {mDirty = true;}
+
+protected:
+    mutable bool mDirty;
+};
+
+}
+}
+#endif // ANDROID_RS_PROGRAM_BASE_H
+
+
+
diff --git a/rsProgramFragment.cpp b/rsProgramFragment.cpp
index 22cd5d3..e40fc7b 100644
--- a/rsProgramFragment.cpp
+++ b/rsProgramFragment.cpp
@@ -14,18 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#else
-#include "rsContextHostStub.h"
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
 #include "rsProgramFragment.h"
 
 using namespace android;
@@ -35,19 +24,16 @@
                                  uint32_t shaderLength, const uint32_t * params,
                                  uint32_t paramLength)
     : Program(rsc, shaderText, shaderLength, params, paramLength) {
-
     mConstantColor[0] = 1.f;
     mConstantColor[1] = 1.f;
     mConstantColor[2] = 1.f;
     mConstantColor[3] = 1.f;
 
-    init(rsc);
+    mRSC->mHal.funcs.fragment.init(mRSC, this, mUserShader.string(), mUserShader.length());
 }
 
 ProgramFragment::~ProgramFragment() {
-    if (mShaderID) {
-        mRSC->mShaderCache.cleanupFragment(mShaderID);
-    }
+    mRSC->mHal.funcs.fragment.destroy(mRSC, this);
 }
 
 void ProgramFragment::setConstantColor(Context *rsc, float r, float g, float b, float a) {
@@ -56,7 +42,7 @@
         rsc->setError(RS_ERROR_BAD_SHADER, "Cannot  set fixed function emulation color on user program");
         return;
     }
-    if (mConstants[0].get() == NULL) {
+    if (mHal.state.constants[0].get() == NULL) {
         LOGE("Unable to set fixed function emulation color because allocation is missing");
         rsc->setError(RS_ERROR_BAD_SHADER, "Unable to set fixed function emulation color because allocation is missing");
         return;
@@ -65,107 +51,26 @@
     mConstantColor[1] = g;
     mConstantColor[2] = b;
     mConstantColor[3] = a;
-    memcpy(mConstants[0]->getPtr(), mConstantColor, 4*sizeof(float));
+    memcpy(mHal.state.constants[0]->getPtr(), mConstantColor, 4*sizeof(float));
     mDirty = true;
 }
 
-void ProgramFragment::setupGL2(Context *rsc, ProgramFragmentState *state, ShaderCache *sc) {
-    //LOGE("sgl2 frag1 %x", glGetError());
+void ProgramFragment::setup(Context *rsc, ProgramFragmentState *state) {
     if ((state->mLast.get() == this) && !mDirty) {
         return;
     }
     state->mLast.set(this);
 
-    rsc->checkError("ProgramFragment::setupGL2 start");
-
-    rsc->checkError("ProgramFragment::setupGL2 begin uniforms");
-    setupUserConstants(rsc, sc, true);
-
-    uint32_t numTexturesToBind = mTextureCount;
-    uint32_t numTexturesAvailable = rsc->getMaxFragmentTextures();
-    if (numTexturesToBind >= numTexturesAvailable) {
-        LOGE("Attempting to bind %u textures on shader id %u, but only %u are available",
-             mTextureCount, (uint32_t)this, numTexturesAvailable);
-        rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available");
-        numTexturesToBind = numTexturesAvailable;
-    }
-
-    for (uint32_t ct=0; ct < numTexturesToBind; ct++) {
-        glActiveTexture(GL_TEXTURE0 + ct);
-        if (!mTextures[ct].get()) {
+    for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) {
+        if (!mHal.state.textures[ct].get()) {
             LOGE("No texture bound for shader id %u, texture unit %u", (uint)this, ct);
             rsc->setError(RS_ERROR_BAD_SHADER, "No texture bound");
             continue;
         }
-
-        mTextures[ct]->uploadCheck(rsc);
-        GLenum target = (GLenum)mTextures[ct]->getGLTarget();
-        if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) {
-            LOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct);
-            rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
-        }
-        glBindTexture(target, mTextures[ct]->getTextureID());
-        rsc->checkError("ProgramFragment::setupGL2 tex bind");
-        if (mSamplers[ct].get()) {
-            mSamplers[ct]->setupGL(rsc, mTextures[ct].get());
-        } else {
-            glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-            glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-            glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-            glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-            rsc->checkError("ProgramFragment::setupGL2 tex env");
-        }
-
-        glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
-        rsc->checkError("ProgramFragment::setupGL2 uniforms");
+        mHal.state.textures[ct]->uploadCheck(rsc);
     }
 
-    glActiveTexture(GL_TEXTURE0);
-    mDirty = false;
-    rsc->checkError("ProgramFragment::setupGL2");
-}
-
-void ProgramFragment::loadShader(Context *rsc) {
-    Program::loadShader(rsc, GL_FRAGMENT_SHADER);
-}
-
-void ProgramFragment::createShader() {
-    if (mUserShader.length() > 1) {
-        mShader.append("precision mediump float;\n");
-        appendUserConstants();
-        char buf[256];
-        for (uint32_t ct=0; ct < mTextureCount; ct++) {
-            if (mTextureTargets[ct] == RS_TEXTURE_2D) {
-                snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
-            } else {
-                snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
-            }
-            mShader.append(buf);
-        }
-        mShader.append(mUserShader);
-    } else {
-        LOGE("ProgramFragment::createShader cannot create program, shader code not defined");
-        rsAssert(0);
-    }
-}
-
-void ProgramFragment::init(Context *rsc) {
-    uint32_t uniformIndex = 0;
-    if (mUserShader.size() > 0) {
-        for (uint32_t ct=0; ct < mConstantCount; ct++) {
-            initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformIndex, RS_SHADER_UNI);
-        }
-    }
-    mTextureUniformIndexStart = uniformIndex;
-    char buf[256];
-    for (uint32_t ct=0; ct < mTextureCount; ct++) {
-        snprintf(buf, sizeof(buf), "UNI_Tex%i", ct);
-        mUniformNames[uniformIndex].setTo(buf);
-        mUniformArraySizes[uniformIndex] = 1;
-        uniformIndex++;
-    }
-
-    createShader();
+    rsc->mHal.funcs.fragment.setActive(rsc, this);
 }
 
 void ProgramFragment::serialize(OStream *stream) const {
diff --git a/rsProgramFragment.h b/rsProgramFragment.h
index 3d28946..d6e20cd 100644
--- a/rsProgramFragment.h
+++ b/rsProgramFragment.h
@@ -32,11 +32,8 @@
                              uint32_t paramLength);
     virtual ~ProgramFragment();
 
-    virtual void setupGL2(Context *, ProgramFragmentState *, ShaderCache *sc);
+    virtual void setup(Context *, ProgramFragmentState *);
 
-    virtual void createShader();
-    virtual void loadShader(Context *rsc);
-    virtual void init(Context *rsc);
     virtual void serialize(OStream *stream) const;
     virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_FRAGMENT; }
     static ProgramFragment *createFromStream(Context *rsc, IStream *stream);
diff --git a/rsProgramRaster.cpp b/rsProgramRaster.cpp
index f2b5b9a..435561d 100644
--- a/rsProgramRaster.cpp
+++ b/rsProgramRaster.cpp
@@ -14,16 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#else
-#include "rsContextHostStub.h"
-#include <OpenGL/gl.h>
-#include <OpenGl/glext.h>
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
 #include "rsProgramRaster.h"
 
 using namespace android;
@@ -31,49 +22,33 @@
 
 
 ProgramRaster::ProgramRaster(Context *rsc, bool pointSmooth,
-                             bool lineSmooth, bool pointSprite)
-    : Program(rsc) {
+                             bool lineSmooth, bool pointSprite,
+                             float lineWidth, RsCullMode cull)
+    : ProgramBase(rsc) {
 
-    mPointSmooth = pointSmooth;
-    mLineSmooth = lineSmooth;
-    mPointSprite = pointSprite;
-    mLineWidth = 1.0f;
-    mCull = RS_CULL_BACK;
+    memset(&mHal, 0, sizeof(mHal));
+
+    mHal.state.pointSmooth = pointSmooth;
+    mHal.state.lineSmooth = lineSmooth;
+    mHal.state.pointSprite = pointSprite;
+    mHal.state.lineWidth = lineWidth;
+    mHal.state.cull = cull;
+
+    rsc->mHal.funcs.raster.init(rsc, this);
 }
 
 ProgramRaster::~ProgramRaster() {
+    mRSC->mHal.funcs.raster.destroy(mRSC, this);
 }
 
-void ProgramRaster::setLineWidth(float s) {
-    mLineWidth = s;
-    mDirty = true;
-}
-
-void ProgramRaster::setCullMode(RsCullMode mode) {
-    mCull = mode;
-    mDirty = true;
-}
-
-void ProgramRaster::setupGL2(const Context *rsc, ProgramRasterState *state) {
+void ProgramRaster::setup(const Context *rsc, ProgramRasterState *state) {
     if (state->mLast.get() == this && !mDirty) {
         return;
     }
     state->mLast.set(this);
     mDirty = false;
 
-    switch (mCull) {
-        case RS_CULL_BACK:
-            glEnable(GL_CULL_FACE);
-            glCullFace(GL_BACK);
-            break;
-        case RS_CULL_FRONT:
-            glEnable(GL_CULL_FACE);
-            glCullFace(GL_FRONT);
-            break;
-        case RS_CULL_NONE:
-            glDisable(GL_CULL_FACE);
-            break;
-    }
+    rsc->mHal.funcs.raster.setActive(rsc, this);
 }
 
 void ProgramRaster::serialize(OStream *stream) const {
@@ -90,7 +65,7 @@
 }
 
 void ProgramRasterState::init(Context *rsc) {
-    ProgramRaster *pr = new ProgramRaster(rsc, false, false, false);
+    ProgramRaster *pr = new ProgramRaster(rsc, false, false, false, 1.f, RS_CULL_BACK);
     mDefault.set(pr);
 }
 
@@ -105,27 +80,15 @@
 RsProgramRaster rsi_ProgramRasterCreate(Context * rsc,
                                       bool pointSmooth,
                                       bool lineSmooth,
-                                      bool pointSprite) {
+                                      bool pointSprite,
+                                      float lineWidth,
+                                      RsCullMode cull) {
     ProgramRaster *pr = new ProgramRaster(rsc, pointSmooth,
-                                          lineSmooth, pointSprite);
+                                          lineSmooth, pointSprite, lineWidth, cull);
     pr->incUserRef();
     return pr;
 }
 
-void rsi_ProgramRasterSetLineWidth(Context * rsc,
-                                   RsProgramRaster vpr,
-                                   float s) {
-    ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
-    pr->setLineWidth(s);
-}
-
-void rsi_ProgramRasterSetCullMode(Context * rsc,
-                                  RsProgramRaster vpr,
-                                  RsCullMode mode) {
-    ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
-    pr->setCullMode(mode);
-}
-
 }
 }
 
diff --git a/rsProgramRaster.h b/rsProgramRaster.h
index 7958af9..efdb948 100644
--- a/rsProgramRaster.h
+++ b/rsProgramRaster.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-2011 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.
@@ -17,7 +17,7 @@
 #ifndef ANDROID_RS_PROGRAM_RASTER_H
 #define ANDROID_RS_PROGRAM_RASTER_H
 
-#include "rsProgram.h"
+#include "rsProgramBase.h"
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -25,28 +25,36 @@
 
 class ProgramRasterState;
 
-class ProgramRaster : public Program {
+class ProgramRaster : public ProgramBase {
 public:
     ProgramRaster(Context *rsc,
                   bool pointSmooth,
                   bool lineSmooth,
-                  bool pointSprite);
+                  bool pointSprite,
+                  float lineWidth,
+                  RsCullMode cull);
     virtual ~ProgramRaster();
 
-    virtual void setupGL2(const Context *, ProgramRasterState *);
+    virtual void setup(const Context *, ProgramRasterState *);
     virtual void serialize(OStream *stream) const;
     virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_RASTER; }
     static ProgramRaster *createFromStream(Context *rsc, IStream *stream);
 
-    void setLineWidth(float w);
-    void setCullMode(RsCullMode mode);
+    struct Hal {
+        mutable void *drv;
+
+        struct State {
+            bool pointSmooth;
+            bool lineSmooth;
+            bool pointSprite;
+            float lineWidth;
+            RsCullMode cull;
+        };
+        State state;
+    };
+    Hal mHal;
 
 protected:
-    bool mPointSmooth;
-    bool mLineSmooth;
-    bool mPointSprite;
-    float mLineWidth;
-    RsCullMode mCull;
 };
 
 class ProgramRasterState {
diff --git a/rsProgramStore.cpp b/rsProgramStore.cpp
index 72ac574..8fe890b 100644
--- a/rsProgramStore.cpp
+++ b/rsProgramStore.cpp
@@ -14,87 +14,44 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#else
-#include "rsContextHostStub.h"
-#include <OpenGL/gl.h>
-#include <OpenGl/glext.h>
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
 #include "rsProgramStore.h"
 
 using namespace android;
 using namespace android::renderscript;
 
 
-ProgramStore::ProgramStore(Context *rsc) : Program(rsc) {
-    mDitherEnable = true;
-    mBlendEnable = false;
-    mColorRWriteEnable = true;
-    mColorGWriteEnable = true;
-    mColorBWriteEnable = true;
-    mColorAWriteEnable = true;
-    mBlendSrc = GL_ONE;
-    mBlendDst = GL_ZERO;
+ProgramStore::ProgramStore(Context *rsc,
+                           bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
+                           bool depthMask, bool ditherEnable,
+                           RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+                           RsDepthFunc depthFunc) : ProgramBase(rsc) {
+    memset(&mHal, 0, sizeof(mHal));
 
-    mDepthTestEnable = false;
-    mDepthWriteEnable = true;
-    mDepthFunc = GL_LESS;
+    mHal.state.ditherEnable = ditherEnable;
+
+    mHal.state.colorRWriteEnable = colorMaskR;
+    mHal.state.colorGWriteEnable = colorMaskG;
+    mHal.state.colorBWriteEnable = colorMaskB;
+    mHal.state.colorAWriteEnable = colorMaskA;
+    mHal.state.blendSrc = srcFunc;
+    mHal.state.blendDst = destFunc;
+
+    mHal.state.depthWriteEnable = depthMask;
+    mHal.state.depthFunc = depthFunc;
 }
 
 ProgramStore::~ProgramStore() {
+    mRSC->mHal.funcs.store.destroy(mRSC, this);
 }
 
-void ProgramStore::setupGL2(const Context *rsc, ProgramStoreState *state) {
+void ProgramStore::setup(const Context *rsc, ProgramStoreState *state) {
     if (state->mLast.get() == this) {
         return;
     }
     state->mLast.set(this);
 
-    glColorMask(mColorRWriteEnable,
-                mColorGWriteEnable,
-                mColorBWriteEnable,
-                mColorAWriteEnable);
-    if (mBlendEnable) {
-        glEnable(GL_BLEND);
-        glBlendFunc(mBlendSrc, mBlendDst);
-    } else {
-        glDisable(GL_BLEND);
-    }
-
-    //LOGE("pfs  %i, %i, %x", mDepthWriteEnable, mDepthTestEnable, mDepthFunc);
-
-    if (rsc->mUserSurfaceConfig.depthMin > 0) {
-        glDepthMask(mDepthWriteEnable);
-        if (mDepthTestEnable || mDepthWriteEnable) {
-            glEnable(GL_DEPTH_TEST);
-            glDepthFunc(mDepthFunc);
-        } else {
-            glDisable(GL_DEPTH_TEST);
-        }
-    } else {
-        glDepthMask(false);
-        glDisable(GL_DEPTH_TEST);
-    }
-
-    if (rsc->mUserSurfaceConfig.stencilMin > 0) {
-    } else {
-        glStencilMask(0);
-        glDisable(GL_STENCIL_TEST);
-    }
-
-    if (mDitherEnable) {
-        glEnable(GL_DITHER);
-    } else {
-        glDisable(GL_DITHER);
-    }
-}
-
-void ProgramStore::setDitherEnable(bool enable) {
-    mDitherEnable = enable;
+    rsc->mHal.funcs.store.setActive(rsc, this);
 }
 
 void ProgramStore::serialize(OStream *stream) const {
@@ -104,123 +61,24 @@
     return NULL;
 }
 
-void ProgramStore::setDepthFunc(RsDepthFunc func) {
-    mDepthTestEnable = true;
-
-    switch (func) {
-    case RS_DEPTH_FUNC_ALWAYS:
-        mDepthTestEnable = false;
-        mDepthFunc = GL_ALWAYS;
-        break;
-    case RS_DEPTH_FUNC_LESS:
-        mDepthFunc = GL_LESS;
-        break;
-    case RS_DEPTH_FUNC_LEQUAL:
-        mDepthFunc = GL_LEQUAL;
-        break;
-    case RS_DEPTH_FUNC_GREATER:
-        mDepthFunc = GL_GREATER;
-        break;
-    case RS_DEPTH_FUNC_GEQUAL:
-        mDepthFunc = GL_GEQUAL;
-        break;
-    case RS_DEPTH_FUNC_EQUAL:
-        mDepthFunc = GL_EQUAL;
-        break;
-    case RS_DEPTH_FUNC_NOTEQUAL:
-        mDepthFunc = GL_NOTEQUAL;
-        break;
-    }
-}
-
-void ProgramStore::setDepthMask(bool mask) {
-    mDepthWriteEnable = mask;
-}
-
-void ProgramStore::setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst) {
-    mBlendEnable = true;
-    if ((src == RS_BLEND_SRC_ONE) &&
-        (dst == RS_BLEND_DST_ZERO)) {
-        mBlendEnable = false;
-    }
-
-    switch (src) {
-    case RS_BLEND_SRC_ZERO:
-        mBlendSrc = GL_ZERO;
-        break;
-    case RS_BLEND_SRC_ONE:
-        mBlendSrc = GL_ONE;
-        break;
-    case RS_BLEND_SRC_DST_COLOR:
-        mBlendSrc = GL_DST_COLOR;
-        break;
-    case RS_BLEND_SRC_ONE_MINUS_DST_COLOR:
-        mBlendSrc = GL_ONE_MINUS_DST_COLOR;
-        break;
-    case RS_BLEND_SRC_SRC_ALPHA:
-        mBlendSrc = GL_SRC_ALPHA;
-        break;
-    case RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA:
-        mBlendSrc = GL_ONE_MINUS_SRC_ALPHA;
-        break;
-    case RS_BLEND_SRC_DST_ALPHA:
-        mBlendSrc = GL_DST_ALPHA;
-        break;
-    case RS_BLEND_SRC_ONE_MINUS_DST_ALPHA:
-        mBlendSrc = GL_ONE_MINUS_DST_ALPHA;
-        break;
-    case RS_BLEND_SRC_SRC_ALPHA_SATURATE:
-        mBlendSrc = GL_SRC_ALPHA_SATURATE;
-        break;
-    }
-
-    switch (dst) {
-    case RS_BLEND_DST_ZERO:
-        mBlendDst = GL_ZERO;
-        break;
-    case RS_BLEND_DST_ONE:
-        mBlendDst = GL_ONE;
-        break;
-    case RS_BLEND_DST_SRC_COLOR:
-        mBlendDst = GL_SRC_COLOR;
-        break;
-    case RS_BLEND_DST_ONE_MINUS_SRC_COLOR:
-        mBlendDst = GL_ONE_MINUS_SRC_COLOR;
-        break;
-    case RS_BLEND_DST_SRC_ALPHA:
-        mBlendDst = GL_SRC_ALPHA;
-        break;
-    case RS_BLEND_DST_ONE_MINUS_SRC_ALPHA:
-        mBlendDst = GL_ONE_MINUS_SRC_ALPHA;
-        break;
-    case RS_BLEND_DST_DST_ALPHA:
-        mBlendDst = GL_DST_ALPHA;
-        break;
-    case RS_BLEND_DST_ONE_MINUS_DST_ALPHA:
-        mBlendDst = GL_ONE_MINUS_DST_ALPHA;
-        break;
-    }
-}
-
-void ProgramStore::setColorMask(bool r, bool g, bool b, bool a) {
-    mColorRWriteEnable = r;
-    mColorGWriteEnable = g;
-    mColorBWriteEnable = b;
-    mColorAWriteEnable = a;
+void ProgramStore::init() {
+    mRSC->mHal.funcs.store.init(mRSC, this);
 }
 
 ProgramStoreState::ProgramStoreState() {
-    mPFS = NULL;
 }
 
 ProgramStoreState::~ProgramStoreState() {
-    ObjectBase::checkDelete(mPFS);
-    mPFS = NULL;
 }
 
 void ProgramStoreState::init(Context *rsc) {
-    ProgramStore *pfs = new ProgramStore(rsc);
-    mDefault.set(pfs);
+    ProgramStore *ps = new ProgramStore(rsc,
+                                        true, true, true, true,
+                                        true, true,
+                                        RS_BLEND_SRC_ONE, RS_BLEND_DST_ZERO,
+                                        RS_DEPTH_FUNC_LESS);
+    ps->init();
+    mDefault.set(ps);
 }
 
 void ProgramStoreState::deinit(Context *rsc) {
@@ -228,40 +86,24 @@
     mLast.clear();
 }
 
+
 namespace android {
 namespace renderscript {
 
-void rsi_ProgramStoreBegin(Context * rsc, RsElement in, RsElement out) {
-    ObjectBase::checkDelete(rsc->mStateFragmentStore.mPFS);
-    rsc->mStateFragmentStore.mPFS = new ProgramStore(rsc);
-}
+RsProgramStore rsi_ProgramStoreCreate(Context *rsc,
+                                      bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
+                                      bool depthMask, bool ditherEnable,
+                                      RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+                                      RsDepthFunc depthFunc) {
 
-void rsi_ProgramStoreDepthFunc(Context *rsc, RsDepthFunc func) {
-    rsc->mStateFragmentStore.mPFS->setDepthFunc(func);
-}
-
-void rsi_ProgramStoreDepthMask(Context *rsc, bool mask) {
-    rsc->mStateFragmentStore.mPFS->setDepthMask(mask);
-}
-
-void rsi_ProgramStoreColorMask(Context *rsc, bool r, bool g, bool b, bool a) {
-    rsc->mStateFragmentStore.mPFS->setColorMask(r, g, b, a);
-}
-
-void rsi_ProgramStoreBlendFunc(Context *rsc, RsBlendSrcFunc src, RsBlendDstFunc dst) {
-    rsc->mStateFragmentStore.mPFS->setBlendFunc(src, dst);
-}
-
-RsProgramStore rsi_ProgramStoreCreate(Context *rsc) {
-    ProgramStore *pfs = rsc->mStateFragmentStore.mPFS;
+    ProgramStore *pfs = new ProgramStore(rsc,
+                                         colorMaskR, colorMaskG, colorMaskB, colorMaskA,
+                                         depthMask, ditherEnable,
+                                         srcFunc, destFunc, depthFunc);
+    pfs->init();
     pfs->incUserRef();
-    rsc->mStateFragmentStore.mPFS = 0;
     return pfs;
 }
 
-void rsi_ProgramStoreDither(Context *rsc, bool enable) {
-    rsc->mStateFragmentStore.mPFS->setDitherEnable(enable);
-}
-
 }
 }
diff --git a/rsProgramStore.h b/rsProgramStore.h
index f8eb7cf..77b3881 100644
--- a/rsProgramStore.h
+++ b/rsProgramStore.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -17,7 +17,7 @@
 #ifndef ANDROID_RS_PROGRAM_FRAGMENT_STORE_H
 #define ANDROID_RS_PROGRAM_FRAGMENT_STORE_H
 
-#include "rsProgram.h"
+#include "rsProgramBase.h"
 #include "rsStream.h"
 
 // ---------------------------------------------------------------------------
@@ -26,41 +26,46 @@
 
 class ProgramStoreState;
 
-class ProgramStore : public Program {
+class ProgramStore : public ProgramBase {
 public:
-    ProgramStore(Context *);
+    ProgramStore(Context *,
+                 bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
+                 bool depthMask, bool ditherEnable,
+                 RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+                 RsDepthFunc depthFunc);
     virtual ~ProgramStore();
 
-    virtual void setupGL2(const Context *, ProgramStoreState *);
-
-    void setDepthFunc(RsDepthFunc);
-    void setDepthMask(bool);
-
-    void setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst);
-    void setColorMask(bool, bool, bool, bool);
-
-    void setDitherEnable(bool);
+    virtual void setup(const Context *, ProgramStoreState *);
 
     virtual void serialize(OStream *stream) const;
     virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_STORE; }
     static ProgramStore *createFromStream(Context *rsc, IStream *stream);
 
+    void init();
+
+    struct Hal {
+        mutable void *drv;
+
+        struct State {
+            bool ditherEnable;
+
+            //bool blendEnable;
+            bool colorRWriteEnable;
+            bool colorGWriteEnable;
+            bool colorBWriteEnable;
+            bool colorAWriteEnable;
+            RsBlendSrcFunc blendSrc;
+            RsBlendDstFunc blendDst;
+
+            //bool depthTestEnable;
+            bool depthWriteEnable;
+            RsDepthFunc depthFunc;
+        };
+        State state;
+    };
+    Hal mHal;
+
 protected:
-    bool mDitherEnable;
-
-    bool mBlendEnable;
-    bool mColorRWriteEnable;
-    bool mColorGWriteEnable;
-    bool mColorBWriteEnable;
-    bool mColorAWriteEnable;
-    int32_t mBlendSrc;
-    int32_t mBlendDst;
-
-    bool mDepthTestEnable;
-    bool mDepthWriteEnable;
-    int32_t mDepthFunc;
-
-    bool mStencilTestEnable;
 };
 
 class ProgramStoreState {
@@ -72,9 +77,6 @@
 
     ObjectBaseRef<ProgramStore> mDefault;
     ObjectBaseRef<ProgramStore> mLast;
-
-
-    ProgramStore *mPFS;
 };
 
 }
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
index ad2beaf..534e8a6 100644
--- a/rsProgramVertex.cpp
+++ b/rsProgramVertex.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -14,18 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#else
-#include "rsContextHostStub.h"
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
 #include "rsProgramVertex.h"
 
 using namespace android;
@@ -36,73 +25,28 @@
                              uint32_t shaderLength, const uint32_t * params,
                              uint32_t paramLength)
     : Program(rsc, shaderText, shaderLength, params, paramLength) {
-    init(rsc);
+    mRSC->mHal.funcs.vertex.init(mRSC, this, mUserShader.string(), mUserShader.length());
 }
 
 ProgramVertex::~ProgramVertex() {
-    if (mShaderID) {
-        mRSC->mShaderCache.cleanupVertex(mShaderID);
-    }
+    mRSC->mHal.funcs.vertex.destroy(mRSC, this);
 }
 
-void ProgramVertex::loadShader(Context *rsc) {
-    Program::loadShader(rsc, GL_VERTEX_SHADER);
-}
-
-void ProgramVertex::createShader(Context *rsc) {
-    if (mUserShader.length() > 1) {
-
-        appendUserConstants();
-
-        for (uint32_t ct=0; ct < mInputCount; ct++) {
-            const Element *e = mInputElements[ct].get();
-            for (uint32_t field=0; field < e->getFieldCount(); field++) {
-                const Element *f = e->getField(field);
-                const char *fn = e->getFieldName(field);
-
-                if (fn[0] == '#') {
-                    continue;
-                }
-
-                // Cannot be complex
-                rsAssert(!f->getFieldCount());
-                switch (f->getComponent().getVectorSize()) {
-                case 1: mShader.append("attribute float ATTRIB_"); break;
-                case 2: mShader.append("attribute vec2 ATTRIB_"); break;
-                case 3: mShader.append("attribute vec3 ATTRIB_"); break;
-                case 4: mShader.append("attribute vec4 ATTRIB_"); break;
-                default:
-                    rsAssert(0);
-                }
-
-                mShader.append(fn);
-                mShader.append(";\n");
-            }
-        }
-        mShader.append(mUserShader);
-    } else {
-        rsc->setError(RS_ERROR_FATAL_UNKNOWN,
-                      "ProgramFragment::createShader cannot create program, shader code not defined");
-    }
-}
-
-void ProgramVertex::setupGL2(Context *rsc, ProgramVertexState *state, ShaderCache *sc) {
+void ProgramVertex::setup(Context *rsc, ProgramVertexState *state) {
     if ((state->mLast.get() == this) && !mDirty) {
         return;
     }
 
-    rsc->checkError("ProgramVertex::setupGL2 start");
-
     if (!isUserProgram()) {
-        if (mConstants[0].get() == NULL) {
+        if (mHal.state.constants[0].get() == NULL) {
             rsc->setError(RS_ERROR_FATAL_UNKNOWN,
                           "Unable to set fixed function emulation matrices because allocation is missing");
             return;
         }
-        float *f = static_cast<float *>(mConstants[0]->getPtr());
-        Matrix mvp;
+        float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
+        Matrix4x4 mvp;
         mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
-        Matrix t;
+        Matrix4x4 t;
         t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
         mvp.multiply(&t);
         for (uint32_t i = 0; i < 16; i ++) {
@@ -110,11 +54,9 @@
         }
     }
 
-    rsc->checkError("ProgramVertex::setupGL2 begin uniforms");
-    setupUserConstants(rsc, sc, false);
-
     state->mLast.set(this);
-    rsc->checkError("ProgramVertex::setupGL2");
+
+    rsc->mHal.funcs.vertex.setActive(rsc, this);
 }
 
 void ProgramVertex::setProjectionMatrix(Context *rsc, const rsc_Matrix *m) const {
@@ -123,12 +65,12 @@
                       "Attempting to set fixed function emulation matrix projection on user program");
         return;
     }
-    if (mConstants[0].get() == NULL) {
+    if (mHal.state.constants[0].get() == NULL) {
         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
                       "Unable to set fixed function emulation matrix projection because allocation is missing");
         return;
     }
-    float *f = static_cast<float *>(mConstants[0]->getPtr());
+    float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
     memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
     mDirty = true;
 }
@@ -139,12 +81,12 @@
                       "Attempting to set fixed function emulation matrix modelview on user program");
         return;
     }
-    if (mConstants[0].get() == NULL) {
+    if (mHal.state.constants[0].get() == NULL) {
         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
                       "Unable to set fixed function emulation matrix modelview because allocation is missing");
         return;
     }
-    float *f = static_cast<float *>(mConstants[0]->getPtr());
+    float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
     memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
     mDirty = true;
 }
@@ -155,12 +97,12 @@
                       "Attempting to set fixed function emulation matrix texture on user program");
         return;
     }
-    if (mConstants[0].get() == NULL) {
+    if (mHal.state.constants[0].get() == NULL) {
         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
                       "Unable to set fixed function emulation matrix texture because allocation is missing");
         return;
     }
-    float *f = static_cast<float *>(mConstants[0]->getPtr());
+    float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
     memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
     mDirty = true;
 }
@@ -171,12 +113,12 @@
                       "Attempting to get fixed function emulation matrix projection on user program");
         return;
     }
-    if (mConstants[0].get() == NULL) {
+    if (mHal.state.constants[0].get() == NULL) {
         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
                       "Unable to get fixed function emulation matrix projection because allocation is missing");
         return;
     }
-    float *f = static_cast<float *>(mConstants[0]->getPtr());
+    float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
     memcpy(m, &f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], sizeof(rsc_Matrix));
 }
 
@@ -184,27 +126,13 @@
     if (isUserProgram()) {
         return;
     }
-    float *f = static_cast<float *>(mConstants[0]->getPtr());
-    Matrix mvp;
-    mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET],
-                     (Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
+    float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
+    Matrix4x4 mvp;
+    mvp.loadMultiply((Matrix4x4 *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET],
+                     (Matrix4x4 *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
     mvp.vectorMultiply(v4out, v3in);
 }
 
-void ProgramVertex::init(Context *rsc) {
-    uint32_t attribCount = 0;
-    uint32_t uniformCount = 0;
-    if (mUserShader.size() > 0) {
-        for (uint32_t ct=0; ct < mInputCount; ct++) {
-            initAddUserElement(mInputElements[ct].get(), mAttribNames, NULL, &attribCount, RS_SHADER_ATTR);
-        }
-        for (uint32_t ct=0; ct < mConstantCount; ct++) {
-            initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
-        }
-    }
-    createShader(rsc);
-}
-
 void ProgramVertex::serialize(OStream *stream) const {
 }
 
@@ -273,7 +201,7 @@
 void ProgramVertexState::updateSize(Context *rsc) {
     float *f = static_cast<float *>(mDefaultAlloc->getPtr());
 
-    Matrix m;
+    Matrix4x4 m;
     m.loadOrtho(0,rsc->getWidth(), rsc->getHeight(),0, -1,1);
     memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m.m, sizeof(m));
     memcpy(&f[RS_PROGRAM_VERTEX_MVP_OFFSET], m.m, sizeof(m));
diff --git a/rsProgramVertex.h b/rsProgramVertex.h
index 2a5c863..5cfdd8b 100644
--- a/rsProgramVertex.h
+++ b/rsProgramVertex.h
@@ -31,7 +31,7 @@
                   const uint32_t * params, uint32_t paramLength);
     virtual ~ProgramVertex();
 
-    virtual void setupGL2(Context *rsc, ProgramVertexState *state, ShaderCache *sc);
+    virtual void setup(Context *rsc, ProgramVertexState *state);
 
     void setProjectionMatrix(Context *, const rsc_Matrix *) const;
     void getProjectionMatrix(Context *, rsc_Matrix *) const;
@@ -40,10 +40,6 @@
 
     void transformToScreen(Context *, float *v4out, const float *v3in) const;
 
-    virtual void createShader(Context *);
-    virtual void loadShader(Context *);
-    virtual void init(Context *);
-
     virtual void serialize(OStream *stream) const;
     virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_VERTEX; }
     static ProgramVertex *createFromStream(Context *rsc, IStream *stream);
diff --git a/rsRuntime.h b/rsRuntime.h
new file mode 100644
index 0000000..884f7b6
--- /dev/null
+++ b/rsRuntime.h
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+
+#include "rsContext.h"
+#include "rsScriptC.h"
+
+#include "utils/Timers.h"
+
+#include <time.h>
+
+namespace android {
+namespace renderscript {
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Context
+//////////////////////////////////////////////////////////////////////////////
+
+void rsrBindTexture(Context *, Script *, ProgramFragment *, uint32_t slot, Allocation *);
+void rsrBindSampler(Context *, Script *, ProgramFragment *, uint32_t slot, Sampler *);
+void rsrBindProgramStore(Context *, Script *, ProgramStore *);
+void rsrBindProgramFragment(Context *, Script *, ProgramFragment *);
+void rsrBindProgramVertex(Context *, Script *, ProgramVertex *);
+void rsrBindProgramRaster(Context *, Script *, ProgramRaster *);
+void rsrBindFrameBufferObjectColorTarget(Context *, Script *, Allocation *, uint32_t slot);
+void rsrBindFrameBufferObjectDepthTarget(Context *, Script *, Allocation *);
+void rsrClearFrameBufferObjectColorTarget(Context *, Script *, uint32_t slot);
+void rsrClearFrameBufferObjectDepthTarget(Context *, Script *);
+void rsrClearFrameBufferObjectTargets(Context *, Script *);
+
+//////////////////////////////////////////////////////////////////////////////
+// VP
+//////////////////////////////////////////////////////////////////////////////
+
+void rsrVpLoadProjectionMatrix(Context *, Script *, const rsc_Matrix *m);
+void rsrVpLoadModelMatrix(Context *, Script *, const rsc_Matrix *m);
+void rsrVpLoadTextureMatrix(Context *, Script *, const rsc_Matrix *m);
+void rsrPfConstantColor(Context *, Script *, ProgramFragment *, float r, float g, float b, float a);
+void rsrVpGetProjectionMatrix(Context *, Script *, rsc_Matrix *m);
+
+//////////////////////////////////////////////////////////////////////////////
+// Drawing
+//////////////////////////////////////////////////////////////////////////////
+
+void rsrDrawQuadTexCoords(Context *, Script *,
+                          float x1, float y1, float z1, float u1, float v1,
+                          float x2, float y2, float z2, float u2, float v2,
+                          float x3, float y3, float z3, float u3, float v3,
+                          float x4, float y4, float z4, float u4, float v4);
+void rsrDrawQuad(Context *, Script *,
+                 float x1, float y1, float z1,
+                 float x2, float y2, float z2,
+                 float x3, float y3, float z3,
+                 float x4, float y4, float z4);
+void rsrDrawSpriteScreenspace(Context *, Script *,
+                              float x, float y, float z, float w, float h);
+void rsrDrawRect(Context *, Script *, float x1, float y1, float x2, float y2, float z);
+void rsrDrawMesh(Context *, Script *, Mesh *);
+void rsrDrawMeshPrimitive(Context *, Script *, Mesh *, uint32_t primIndex);
+void rsrDrawMeshPrimitiveRange(Context *, Script *, Mesh *,
+                               uint32_t primIndex, uint32_t start, uint32_t len);
+void rsrMeshComputeBoundingBox(Context *, Script *, Mesh *,
+                               float *minX, float *minY, float *minZ,
+                               float *maxX, float *maxY, float *maxZ);
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+void rsrColor(Context *, Script *, float r, float g, float b, float a);
+void rsrFinish(Context *, Script *);
+void rsrAllocationSyncAll(Context *, Script *, Allocation *);
+void rsrClearColor(Context *, Script *, float r, float g, float b, float a);
+void rsrClearDepth(Context *, Script *, float v);
+uint32_t rsrGetWidth(Context *, Script *);
+uint32_t rsrGetHeight(Context *, Script *);
+void rsrDrawTextAlloc(Context *, Script *, Allocation *, int x, int y);
+void rsrDrawText(Context *, Script *, const char *text, int x, int y);
+void rsrSetMetrics(Context *, Script *, Font::Rect *metrics,
+                   int32_t *left, int32_t *right, int32_t *top, int32_t *bottom);
+void rsrMeasureTextAlloc(Context *, Script *, Allocation *,
+                         int32_t *left, int32_t *right, int32_t *top, int32_t *bottom);
+void rsrMeasureText(Context *, Script *, const char *text,
+                    int32_t *left, int32_t *right, int32_t *top, int32_t *bottom);
+void rsrBindFont(Context *, Script *, Font *);
+void rsrFontColor(Context *, Script *, float r, float g, float b, float a);
+
+//////////////////////////////////////////////////////////////////////////////
+// Time routines
+//////////////////////////////////////////////////////////////////////////////
+
+float rsrGetDt(Context *, Script *);
+time_t rsrTime(Context *, Script *, time_t *timer);
+tm* rsrLocalTime(Context *, Script *, tm *local, time_t *timer);
+int64_t rsrUptimeMillis(Context *, Script *);
+int64_t rsrUptimeNanos(Context *, Script *);
+
+//////////////////////////////////////////////////////////////////////////////
+// Message routines
+//////////////////////////////////////////////////////////////////////////////
+
+uint32_t rsrToClient(Context *, Script *, int cmdID, void *data, int len);
+uint32_t rsrToClientBlocking(Context *, Script *, int cmdID, void *data, int len);
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+void rsrSetObject(const Context *, const Script *, ObjectBase **dst, ObjectBase * src);
+void rsrClearObject(const Context *, const Script *, ObjectBase **dst);
+bool rsrIsObject(const Context *, const Script *, const ObjectBase *src);
+
+uint32_t rsrToClient(Context *, Script *, int cmdID, void *data, int len);
+uint32_t rsrToClientBlocking(Context *, Script *, int cmdID, void *data, int len);
+const Allocation * rsrGetAllocation(Context *, Script *, const void *ptr);
+
+void rsrAllocationMarkDirty(Context *, Script *, RsAllocation a);
+void rsrAllocationSyncAll(Context *, Script *, Allocation *a, RsAllocationUsageType source);
+
+
+void rsrForEach(Context *, Script *, Script *target,
+                Allocation *in,
+                Allocation *out,
+                const void *usr,
+                 uint32_t usrBytes,
+                const RsScriptCall *call);
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Heavy math functions
+//////////////////////////////////////////////////////////////////////////////
+
+
+void rsrMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v);
+float rsrMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col);
+void rsrMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v);
+float rsrMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col);
+void rsrMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v);
+float rsrMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col);
+void rsrMatrixLoadIdentity_4x4(rs_matrix4x4 *m);
+void rsrMatrixLoadIdentity_3x3(rs_matrix3x3 *m);
+void rsrMatrixLoadIdentity_2x2(rs_matrix2x2 *m);
+void rsrMatrixLoad_4x4_f(rs_matrix4x4 *m, const float *v);
+void rsrMatrixLoad_3x3_f(rs_matrix3x3 *m, const float *v);
+void rsrMatrixLoad_2x2_f(rs_matrix2x2 *m, const float *v);
+void rsrMatrixLoad_4x4_4x4(rs_matrix4x4 *m, const rs_matrix4x4 *v);
+void rsrMatrixLoad_4x4_3x3(rs_matrix4x4 *m, const rs_matrix3x3 *v);
+void rsrMatrixLoad_4x4_2x2(rs_matrix4x4 *m, const rs_matrix2x2 *v);
+void rsrMatrixLoad_3x3_3x3(rs_matrix3x3 *m, const rs_matrix3x3 *v);
+void rsrMatrixLoad_2x2_2x2(rs_matrix2x2 *m, const rs_matrix2x2 *v);
+void rsrMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
+void rsrMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z);
+void rsrMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z);
+void rsrMatrixLoadMultiply_4x4_4x4_4x4(rs_matrix4x4 *m, const rs_matrix4x4 *lhs,
+                                       const rs_matrix4x4 *rhs);
+void rsrMatrixMultiply_4x4_4x4(rs_matrix4x4 *m, const rs_matrix4x4 *rhs);
+void rsrMatrixLoadMultiply_3x3_3x3_3x3(rs_matrix3x3 *m, const rs_matrix3x3 *lhs,
+                                       const rs_matrix3x3 *rhs);
+void rsrMatrixMultiply_3x3_3x3(rs_matrix3x3 *m, const rs_matrix3x3 *rhs);
+void rsrMatrixLoadMultiply_2x2_2x2_2x2(rs_matrix2x2 *m, const rs_matrix2x2 *lhs,
+                                       const rs_matrix2x2 *rhs);
+void rsrMatrixMultiply_2x2_2x2(rs_matrix2x2 *m, const rs_matrix2x2 *rhs);
+void rsrMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
+void rsrMatrixScale(rs_matrix4x4 *m, float x, float y, float z);
+void rsrMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z);
+void rsrMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right,
+                        float bottom, float top, float near, float far);
+void rsrMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right,
+                          float bottom, float top, float near, float far);
+void rsrMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far);
+
+// Returns true if the matrix was successfully inversed
+bool rsrMatrixInverse_4x4(rs_matrix4x4 *m);
+// Returns true if the matrix was successfully inversed
+bool rsrMatrixInverseTranspose_4x4(rs_matrix4x4 *m);
+
+void rsrMatrixTranspose_4x4(rs_matrix4x4 *m);
+void rsrMatrixTranspose_3x3(rs_matrix3x3 *m);
+void rsrMatrixTranspose_2x2(rs_matrix2x2 *m);
+
+}
+}
diff --git a/rsSampler.cpp b/rsSampler.cpp
index c80aecc..2a05d16 100644
--- a/rsSampler.cpp
+++ b/rsSampler.cpp
@@ -14,16 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
-#include <GLES/gl.h>
-#include <GLES/glext.h>
 #include "rsContext.h"
-#else
-#include "rsContextHostStub.h"
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
 #include "rsSampler.h"
 
 
@@ -43,77 +34,18 @@
                  RsSamplerValue wrapT,
                  RsSamplerValue wrapR,
                  float aniso) : ObjectBase(rsc) {
-    mMagFilter = magFilter;
-    mMinFilter = minFilter;
-    mWrapS = wrapS;
-    mWrapT = wrapT;
-    mWrapR = wrapR;
-    mAniso = aniso;
+    mHal.state.magFilter = magFilter;
+    mHal.state.minFilter = minFilter;
+    mHal.state.wrapS = wrapS;
+    mHal.state.wrapT = wrapT;
+    mHal.state.wrapR = wrapR;
+    mHal.state.aniso = aniso;
+
+    mRSC->mHal.funcs.sampler.init(mRSC, this);
 }
 
 Sampler::~Sampler() {
-}
-
-void Sampler::setupGL(const Context *rsc, const Allocation *tex) {
-    GLenum trans[] = {
-        GL_NEAREST, //RS_SAMPLER_NEAREST,
-        GL_LINEAR, //RS_SAMPLER_LINEAR,
-        GL_LINEAR_MIPMAP_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
-        GL_REPEAT, //RS_SAMPLER_WRAP,
-        GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
-        GL_LINEAR_MIPMAP_NEAREST, //RS_SAMPLER_LINEAR_MIP_NEAREST
-    };
-
-    GLenum transNP[] = {
-        GL_NEAREST, //RS_SAMPLER_NEAREST,
-        GL_LINEAR, //RS_SAMPLER_LINEAR,
-        GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
-        GL_CLAMP_TO_EDGE, //RS_SAMPLER_WRAP,
-        GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
-        GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_NEAREST,
-    };
-
-    // This tells us the correct texture type
-    GLenum target = (GLenum)tex->getGLTarget();
-
-    if (!rsc->ext_OES_texture_npot() && tex->getType()->getIsNp2()) {
-        if (tex->getHasGraphicsMipmaps() &&
-            (rsc->ext_GL_NV_texture_npot_2D_mipmap() || rsc->ext_GL_IMG_texture_npot())) {
-            if (rsc->ext_GL_NV_texture_npot_2D_mipmap()) {
-                glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
-            } else {
-                switch (trans[mMinFilter]) {
-                case GL_LINEAR_MIPMAP_LINEAR:
-                    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
-                    break;
-                default:
-                    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
-                    break;
-                }
-            }
-        } else {
-            glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]);
-        }
-        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, transNP[mMagFilter]);
-        glTexParameteri(target, GL_TEXTURE_WRAP_S, transNP[mWrapS]);
-        glTexParameteri(target, GL_TEXTURE_WRAP_T, transNP[mWrapT]);
-    } else {
-        if (tex->getHasGraphicsMipmaps()) {
-            glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
-        } else {
-            glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]);
-        }
-        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, trans[mMagFilter]);
-        glTexParameteri(target, GL_TEXTURE_WRAP_S, trans[mWrapS]);
-        glTexParameteri(target, GL_TEXTURE_WRAP_T, trans[mWrapT]);
-    }
-
-    float anisoValue = rsMin(rsc->ext_texture_max_aniso(), mAniso);
-    if (rsc->ext_texture_max_aniso() > 1.0f) {
-        glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue);
-    }
-
-    rsc->checkError("Sampler::setupGL2 tex env");
+    mRSC->mHal.funcs.sampler.destroy(mRSC, this);
 }
 
 void Sampler::bindToContext(SamplerState *ss, uint32_t slot) {
@@ -139,66 +71,14 @@
 namespace android {
 namespace renderscript {
 
-
-void rsi_SamplerBegin(Context *rsc) {
-    SamplerState * ss = &rsc->mStateSampler;
-
-    ss->mMagFilter = RS_SAMPLER_LINEAR;
-    ss->mMinFilter = RS_SAMPLER_LINEAR;
-    ss->mWrapS = RS_SAMPLER_WRAP;
-    ss->mWrapT = RS_SAMPLER_WRAP;
-    ss->mWrapR = RS_SAMPLER_WRAP;
-    ss->mAniso = 1.0f;
-}
-
-void rsi_SamplerSet(Context *rsc, RsSamplerParam param, RsSamplerValue value) {
-    SamplerState * ss = &rsc->mStateSampler;
-
-    switch (param) {
-    case RS_SAMPLER_MAG_FILTER:
-        ss->mMagFilter = value;
-        break;
-    case RS_SAMPLER_MIN_FILTER:
-        ss->mMinFilter = value;
-        break;
-    case RS_SAMPLER_WRAP_S:
-        ss->mWrapS = value;
-        break;
-    case RS_SAMPLER_WRAP_T:
-        ss->mWrapT = value;
-        break;
-    case RS_SAMPLER_WRAP_R:
-        ss->mWrapR = value;
-        break;
-    default:
-        LOGE("Attempting to set invalid value on sampler");
-        break;
-    }
-}
-
-void rsi_SamplerSet2(Context *rsc, RsSamplerParam param, float value) {
-    SamplerState * ss = &rsc->mStateSampler;
-
-    switch (param) {
-    case RS_SAMPLER_ANISO:
-        ss->mAniso = value;
-        break;
-    default:
-        LOGE("Attempting to set invalid value on sampler");
-        break;
-    }
-}
-
-RsSampler rsi_SamplerCreate(Context *rsc) {
-    SamplerState * ss = &rsc->mStateSampler;
-
-    Sampler * s = new Sampler(rsc,
-                              ss->mMagFilter,
-                              ss->mMinFilter,
-                              ss->mWrapS,
-                              ss->mWrapT,
-                              ss->mWrapR,
-                              ss->mAniso);
+RsSampler rsi_SamplerCreate(Context * rsc,
+                            RsSamplerValue magFilter,
+                            RsSamplerValue minFilter,
+                            RsSamplerValue wrapS,
+                            RsSamplerValue wrapT,
+                            RsSamplerValue wrapR,
+                            float aniso) {
+    Sampler * s = new Sampler(rsc, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
     s->incUserRef();
     return s;
 }
diff --git a/rsSampler.h b/rsSampler.h
index 737bb8b..90b6082 100644
--- a/rsSampler.h
+++ b/rsSampler.h
@@ -40,9 +40,6 @@
 
     virtual ~Sampler();
 
-    void bind(Allocation *);
-    void setupGL(const Context *, const Allocation *);
-
     void bindToContext(SamplerState *, uint32_t slot);
     void unbindFromContext(SamplerState *);
 
@@ -50,14 +47,22 @@
     virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_SAMPLER; }
     static Sampler *createFromStream(Context *rsc, IStream *stream);
 
-protected:
-    RsSamplerValue mMagFilter;
-    RsSamplerValue mMinFilter;
-    RsSamplerValue mWrapS;
-    RsSamplerValue mWrapT;
-    RsSamplerValue mWrapR;
-    float mAniso;
+    struct Hal {
+        mutable void *drv;
 
+        struct State {
+            RsSamplerValue magFilter;
+            RsSamplerValue minFilter;
+            RsSamplerValue wrapS;
+            RsSamplerValue wrapT;
+            RsSamplerValue wrapR;
+            float aniso;
+        };
+        State state;
+    };
+    Hal mHal;
+
+protected:
     int32_t mBoundSlot;
 
 private:
@@ -67,13 +72,6 @@
 
 class SamplerState {
 public:
-    RsSamplerValue mMagFilter;
-    RsSamplerValue mMinFilter;
-    RsSamplerValue mWrapS;
-    RsSamplerValue mWrapT;
-    RsSamplerValue mWrapR;
-    float mAniso;
-
     ObjectBaseRef<Sampler> mSamplers[RS_MAX_SAMPLER_SLOT];
 };
 
diff --git a/rsScript.cpp b/rsScript.cpp
index 9ada9c2..7641cab 100644
--- a/rsScript.cpp
+++ b/rsScript.cpp
@@ -21,6 +21,7 @@
 
 Script::Script(Context *rsc) : ObjectBase(rsc) {
     memset(&mEnviroment, 0, sizeof(mEnviroment));
+    memset(&mHal, 0, sizeof(mHal));
 
     mSlots = NULL;
     mTypes = NULL;
@@ -37,48 +38,38 @@
     }
 }
 
-void Script::initSlots() {
-    if (mEnviroment.mFieldCount > 0) {
-        mSlots = new ObjectBaseRef<Allocation>[mEnviroment.mFieldCount];
-        mTypes = new ObjectBaseRef<const Type>[mEnviroment.mFieldCount];
-    }
-}
-
 void Script::setSlot(uint32_t slot, Allocation *a) {
-    if (slot >= mEnviroment.mFieldCount) {
+    //LOGE("setSlot %i %p", slot, a);
+    if (slot >= mHal.info.exportedVariableCount) {
         LOGE("Script::setSlot unable to set allocation, invalid slot index");
         return;
     }
 
     mSlots[slot].set(a);
+    if (a != NULL) {
+        mRSC->mHal.funcs.script.setGlobalBind(mRSC, this, slot, a->getPtr());
+    } else {
+        mRSC->mHal.funcs.script.setGlobalBind(mRSC, this, slot, NULL);
+    }
 }
 
 void Script::setVar(uint32_t slot, const void *val, uint32_t len) {
-    int32_t *destPtr = ((int32_t **)mEnviroment.mFieldAddress)[slot];
-    if (destPtr) {
-        //LOGE("setVar f1  %f", ((const float *)destPtr)[0]);
-        //LOGE("setVar %p %i", destPtr, len);
-        memcpy(destPtr, val, len);
-        //LOGE("setVar f2  %f", ((const float *)destPtr)[0]);
-    } else {
-        //if (rsc->props.mLogScripts) {
-            LOGV("Calling setVar on slot = %i which is null", slot);
-        //}
+    //LOGE("setVar %i %p %i", slot, val, len);
+    if (slot >= mHal.info.exportedVariableCount) {
+        LOGE("Script::setVar unable to set allocation, invalid slot index");
+        return;
     }
+    mRSC->mHal.funcs.script.setGlobalVar(mRSC, this, slot, (void *)val, len);
 }
 
 void Script::setVarObj(uint32_t slot, ObjectBase *val) {
-    ObjectBase **destPtr = ((ObjectBase ***)mEnviroment.mFieldAddress)[slot];
-
-    if (destPtr) {
-        if (val != NULL) {
-            val->incSysRef();
-        }
-        if (*destPtr) {
-            (*destPtr)->decSysRef();
-        }
-        *destPtr = val;
+    //LOGE("setVarObj %i %p", slot, val);
+    if (slot >= mHal.info.exportedVariableCount) {
+        LOGE("Script::setVarObj unable to set allocation, invalid slot index");
+        return;
     }
+    //LOGE("setvarobj  %i %p", slot, val);
+    mRSC->mHal.funcs.script.setGlobalObj(mRSC, this, slot, val);
 }
 
 namespace android {
@@ -96,6 +87,16 @@
     s->mEnviroment.mTimeZone = timeZone;
 }
 
+void rsi_ScriptForEach(Context *rsc, RsScript vs, uint32_t slot,
+                       RsAllocation vain, RsAllocation vaout,
+                       const void *params, uint32_t paramLen) {
+    Script *s = static_cast<Script *>(vs);
+    s->runForEach(rsc,
+                  static_cast<const Allocation *>(vain), static_cast<Allocation *>(vaout),
+                  params, paramLen);
+
+}
+
 void rsi_ScriptInvoke(Context *rsc, RsScript vs, uint32_t slot) {
     Script *s = static_cast<Script *>(vs);
     s->Invoke(rsc, slot, NULL, 0);
@@ -139,7 +140,6 @@
 }
 
 void rsi_ScriptSetVarV(Context *rsc, RsScript vs, uint32_t slot, const void *data, uint32_t len) {
-    const float *fp = (const float *)data;
     Script *s = static_cast<Script *>(vs);
     s->setVar(slot, data, len);
 }
diff --git a/rsScript.h b/rsScript.h
index bad095b..088c8d1 100644
--- a/rsScript.h
+++ b/rsScript.h
@@ -31,6 +31,26 @@
 
 class Script : public ObjectBase {
 public:
+    struct Hal {
+        void * drv;
+
+        struct DriverInfo {
+            int mVersionMajor;
+            int mVersionMinor;
+
+            size_t exportedVariableCount;
+            size_t exportedFunctionCount;
+            size_t exportedPragmaCount;
+            char const **exportedPragmaKeyList;
+            char const **exportedPragmaValueList;
+
+            int (* root)();
+            bool isThreadable;
+        };
+        DriverInfo info;
+    };
+    Hal mHal;
+
     typedef void (* InvokeFunc_t)(void);
 
     Script(Context *);
@@ -45,16 +65,6 @@
         ObjectBaseRef<ProgramFragment> mFragment;
         ObjectBaseRef<ProgramRaster> mRaster;
         ObjectBaseRef<ProgramStore> mFragmentStore;
-
-        uint32_t mInvokeFunctionCount;
-        InvokeFunc_t *mInvokeFunctions;
-        uint32_t mFieldCount;
-        void ** mFieldAddress;
-
-        char * mScriptText;
-        uint32_t mScriptTextLength;
-
-        bool mIsThreadable;
     };
     Enviroment_t mEnviroment;
 
@@ -67,6 +77,7 @@
                             const Allocation * ain,
                             Allocation * aout,
                             const void * usr,
+                            size_t usrBytes,
                             const RsScriptCall *sc = NULL) = 0;
 
     virtual void Invoke(Context *rsc, uint32_t slot, const void *data, uint32_t len) = 0;
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index fc673a2..6d0701d 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -16,16 +16,14 @@
 
 #include "rsContext.h"
 #include "rsScriptC.h"
-#include "rsMatrix.h"
 #include "utils/Timers.h"
 #include "utils/StopWatch.h"
-extern "C" {
-#include "libdex/ZipArchive.h"
-}
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
+#include <bcc/bcc.h>
+
 using namespace android;
 using namespace android::renderscript;
 
@@ -34,94 +32,18 @@
     Context * rsc = tls->mContext; \
     ScriptC * sc = (ScriptC *) tls->mScript
 
-// Input: cacheDir
-// Input: resName
-// Input: extName
-//
-// Note: cacheFile = resName + extName
-//
-// Output: Returns cachePath == cacheDir + cacheFile
-char *genCacheFileName(const char *cacheDir,
-                       const char *resName,
-                       const char *extName) {
-    char cachePath[512];
-    char cacheFile[sizeof(cachePath)];
-    const size_t kBufLen = sizeof(cachePath) - 1;
-
-    cacheFile[0] = '\0';
-    // Note: resName today is usually something like
-    //       "/com.android.fountain:raw/fountain"
-    if (resName[0] != '/') {
-        // Get the absolute path of the raw/***.bc file.
-
-        // Generate the absolute path.  This doesn't do everything it
-        // should, e.g. if resName is "./out/whatever" it doesn't crunch
-        // the leading "./" out because this if-block is not triggered,
-        // but it'll make do.
-        //
-        if (getcwd(cacheFile, kBufLen) == NULL) {
-            LOGE("Can't get CWD while opening raw/***.bc file\n");
-            return NULL;
-        }
-        // Append "/" at the end of cacheFile so far.
-        strncat(cacheFile, "/", kBufLen);
-    }
-
-    // cacheFile = resName + extName
-    //
-    strncat(cacheFile, resName, kBufLen);
-    if (extName != NULL) {
-        // TODO(srhines): strncat() is a bit dangerous
-        strncat(cacheFile, extName, kBufLen);
-    }
-
-    // Turn the path into a flat filename by replacing
-    // any slashes after the first one with '@' characters.
-    char *cp = cacheFile + 1;
-    while (*cp != '\0') {
-        if (*cp == '/') {
-            *cp = '@';
-        }
-        cp++;
-    }
-
-    // Tack on the file name for the actual cache file path.
-    strncpy(cachePath, cacheDir, kBufLen);
-    strncat(cachePath, cacheFile, kBufLen);
-
-    LOGV("Cache file for '%s' '%s' is '%s'\n", resName, extName, cachePath);
-    return strdup(cachePath);
-}
-
 ScriptC::ScriptC(Context *rsc) : Script(rsc) {
-    mBccScript = NULL;
-    memset(&mProgram, 0, sizeof(mProgram));
 }
 
 ScriptC::~ScriptC() {
-    if (mBccScript) {
-        if (mProgram.mObjectSlotList) {
-            for (size_t ct=0; ct < mProgram.mObjectSlotCount; ct++) {
-                setVarObj(mProgram.mObjectSlotList[ct], NULL);
-            }
-            delete [] mProgram.mObjectSlotList;
-            mProgram.mObjectSlotList = NULL;
-            mProgram.mObjectSlotCount = 0;
-        }
-
-
-        LOGD(">>>> ~ScriptC  bccDisposeScript(%p)", mBccScript);
-        bccDisposeScript(mBccScript);
-    }
-    free(mEnviroment.mScriptText);
-    mEnviroment.mScriptText = NULL;
+    mRSC->mHal.funcs.script.destroy(mRSC, this);
 }
 
 void ScriptC::setupScript(Context *rsc) {
     mEnviroment.mStartTimeMillis
                 = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
 
-    for (uint32_t ct=0; ct < mEnviroment.mFieldCount; ct++) {
+    for (uint32_t ct=0; ct < mHal.info.exportedVariableCount; ct++) {
         if (mSlots[ct].get() && !mTypes[ct].get()) {
             mTypes[ct].set(mSlots[ct]->getType());
         }
@@ -132,27 +54,17 @@
         if (mSlots[ct].get()) {
             ptr = mSlots[ct]->getPtr();
         }
-        void **dest = ((void ***)mEnviroment.mFieldAddress)[ct];
 
-        if (rsc->props.mLogScripts) {
-            if (mSlots[ct].get() != NULL) {
-                LOGV("%p ScriptC::setupScript slot=%i  dst=%p  src=%p  type=%p", rsc, ct, dest, ptr, mSlots[ct]->getType());
-            } else {
-                LOGV("%p ScriptC::setupScript slot=%i  dst=%p  src=%p  type=null", rsc, ct, dest, ptr);
-            }
-        }
-
-        if (dest) {
-            *dest = ptr;
-        }
+        rsc->mHal.funcs.script.setGlobalBind(rsc, this, ct, ptr);
     }
 }
 
 const Allocation *ScriptC::ptrToAllocation(const void *ptr) const {
+    //LOGE("ptr to alloc %p", ptr);
     if (!ptr) {
         return NULL;
     }
-    for (uint32_t ct=0; ct < mEnviroment.mFieldCount; ct++) {
+    for (uint32_t ct=0; ct < mHal.info.exportedVariableCount; ct++) {
         if (!mSlots[ct].get())
             continue;
         if (mSlots[ct]->getPtr() == ptr) {
@@ -163,15 +75,6 @@
     return NULL;
 }
 
-Script * ScriptC::setTLS(Script *sc) {
-    Context::ScriptTLSStruct * tls = (Context::ScriptTLSStruct *)
-                                  pthread_getspecific(Context::gThreadTLSKey);
-    rsAssert(tls);
-    Script *old = tls->mScript;
-    tls->mScript = sc;
-    return old;
-}
-
 void ScriptC::setupGLState(Context *rsc) {
     if (mEnviroment.mFragmentStore.get()) {
         rsc->setProgramStore(mEnviroment.mFragmentStore.get());
@@ -188,7 +91,7 @@
 }
 
 uint32_t ScriptC::run(Context *rsc) {
-    if (mProgram.mRoot == NULL) {
+    if (mHal.info.root == NULL) {
         rsc->setError(RS_ERROR_BAD_SCRIPT, "Attempted to run bad script");
         return 0;
     }
@@ -197,235 +100,46 @@
     setupScript(rsc);
 
     uint32_t ret = 0;
-    Script * oldTLS = setTLS(this);
 
     if (rsc->props.mLogScripts) {
-        LOGV("%p ScriptC::run invoking root,  ptr %p", rsc, mProgram.mRoot);
+        LOGV("%p ScriptC::run invoking root,  ptr %p", rsc, mHal.info.root);
     }
 
-    ret = mProgram.mRoot();
+    ret = rsc->mHal.funcs.script.invokeRoot(rsc, this);
 
     if (rsc->props.mLogScripts) {
         LOGV("%p ScriptC::run invoking complete, ret=%i", rsc, ret);
     }
 
-    setTLS(oldTLS);
     return ret;
 }
 
-typedef struct {
-    Context *rsc;
-    ScriptC *script;
-    const Allocation * ain;
-    Allocation * aout;
-    const void * usr;
-
-    uint32_t mSliceSize;
-    volatile int mSliceNum;
-
-    const uint8_t *ptrIn;
-    uint32_t eStrideIn;
-    uint8_t *ptrOut;
-    uint32_t eStrideOut;
-
-    uint32_t xStart;
-    uint32_t xEnd;
-    uint32_t yStart;
-    uint32_t yEnd;
-    uint32_t zStart;
-    uint32_t zEnd;
-    uint32_t arrayStart;
-    uint32_t arrayEnd;
-
-    uint32_t dimX;
-    uint32_t dimY;
-    uint32_t dimZ;
-    uint32_t dimArray;
-} MTLaunchStruct;
-typedef int (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
-
-static void wc_xy(void *usr, uint32_t idx) {
-    MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
-
-    while (1) {
-        uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
-        uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
-        uint32_t yEnd = yStart + mtls->mSliceSize;
-        yEnd = rsMin(yEnd, mtls->yEnd);
-        if (yEnd <= yStart) {
-            return;
-        }
-
-        //LOGE("usr idx %i, x %i,%i  y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
-        //LOGE("usr ptr in %p,  out %p", mtls->ptrIn, mtls->ptrOut);
-        for (uint32_t y = yStart; y < yEnd; y++) {
-            uint32_t offset = mtls->dimX * y;
-            uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * offset);
-            const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * offset);
-
-            for (uint32_t x = mtls->xStart; x < mtls->xEnd; x++) {
-                ((rs_t)mtls->script->mProgram.mRoot) (xPtrIn, xPtrOut, mtls->usr, x, y, 0, 0);
-                xPtrIn += mtls->eStrideIn;
-                xPtrOut += mtls->eStrideOut;
-            }
-        }
-    }
-}
-
-static void wc_x(void *usr, uint32_t idx) {
-    MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
-
-    while (1) {
-        uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
-        uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize;
-        uint32_t xEnd = xStart + mtls->mSliceSize;
-        xEnd = rsMin(xEnd, mtls->xEnd);
-        if (xEnd <= xStart) {
-            return;
-        }
-
-        //LOGE("usr idx %i, x %i,%i  y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
-        //LOGE("usr ptr in %p,  out %p", mtls->ptrIn, mtls->ptrOut);
-        uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * xStart);
-        const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * xStart);
-        for (uint32_t x = xStart; x < xEnd; x++) {
-            ((rs_t)mtls->script->mProgram.mRoot) (xPtrIn, xPtrOut, mtls->usr, x, 0, 0, 0);
-            xPtrIn += mtls->eStrideIn;
-            xPtrOut += mtls->eStrideOut;
-        }
-    }
-}
 
 void ScriptC::runForEach(Context *rsc,
                          const Allocation * ain,
                          Allocation * aout,
                          const void * usr,
+                         size_t usrBytes,
                          const RsScriptCall *sc) {
-    MTLaunchStruct mtls;
-    memset(&mtls, 0, sizeof(mtls));
+
     Context::PushState ps(rsc);
 
-    if (ain) {
-        mtls.dimX = ain->getType()->getDimX();
-        mtls.dimY = ain->getType()->getDimY();
-        mtls.dimZ = ain->getType()->getDimZ();
-        //mtls.dimArray = ain->getType()->getDimArray();
-    } else if (aout) {
-        mtls.dimX = aout->getType()->getDimX();
-        mtls.dimY = aout->getType()->getDimY();
-        mtls.dimZ = aout->getType()->getDimZ();
-        //mtls.dimArray = aout->getType()->getDimArray();
-    } else {
-        rsc->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
-        return;
-    }
-
-    if (!sc || (sc->xEnd == 0)) {
-        mtls.xEnd = mtls.dimX;
-    } else {
-        rsAssert(sc->xStart < mtls.dimX);
-        rsAssert(sc->xEnd <= mtls.dimX);
-        rsAssert(sc->xStart < sc->xEnd);
-        mtls.xStart = rsMin(mtls.dimX, sc->xStart);
-        mtls.xEnd = rsMin(mtls.dimX, sc->xEnd);
-        if (mtls.xStart >= mtls.xEnd) return;
-    }
-
-    if (!sc || (sc->yEnd == 0)) {
-        mtls.yEnd = mtls.dimY;
-    } else {
-        rsAssert(sc->yStart < mtls.dimY);
-        rsAssert(sc->yEnd <= mtls.dimY);
-        rsAssert(sc->yStart < sc->yEnd);
-        mtls.yStart = rsMin(mtls.dimY, sc->yStart);
-        mtls.yEnd = rsMin(mtls.dimY, sc->yEnd);
-        if (mtls.yStart >= mtls.yEnd) return;
-    }
-
-    mtls.xEnd = rsMax((uint32_t)1, mtls.xEnd);
-    mtls.yEnd = rsMax((uint32_t)1, mtls.yEnd);
-    mtls.zEnd = rsMax((uint32_t)1, mtls.zEnd);
-    mtls.arrayEnd = rsMax((uint32_t)1, mtls.arrayEnd);
-
-    rsAssert(ain->getType()->getDimZ() == 0);
-
     setupGLState(rsc);
     setupScript(rsc);
-    Script * oldTLS = setTLS(this);
-
-    mtls.rsc = rsc;
-    mtls.ain = ain;
-    mtls.aout = aout;
-    mtls.script = this;
-    mtls.usr = usr;
-    mtls.mSliceSize = 10;
-    mtls.mSliceNum = 0;
-
-    mtls.ptrIn = NULL;
-    mtls.eStrideIn = 0;
-    if (ain) {
-        mtls.ptrIn = (const uint8_t *)ain->getPtr();
-        mtls.eStrideIn = ain->getType()->getElementSizeBytes();
-    }
-
-    mtls.ptrOut = NULL;
-    mtls.eStrideOut = 0;
-    if (aout) {
-        mtls.ptrOut = (uint8_t *)aout->getPtr();
-        mtls.eStrideOut = aout->getType()->getElementSizeBytes();
-    }
-
-    if ((rsc->getWorkerPoolSize() > 1) && mEnviroment.mIsThreadable) {
-        if (mtls.dimY > 1) {
-            rsc->launchThreads(wc_xy, &mtls);
-        } else {
-            rsc->launchThreads(wc_x, &mtls);
-        }
-
-        //LOGE("launch 1");
-    } else {
-        //LOGE("launch 3");
-        for (uint32_t ar = mtls.arrayStart; ar < mtls.arrayEnd; ar++) {
-            for (uint32_t z = mtls.zStart; z < mtls.zEnd; z++) {
-                for (uint32_t y = mtls.yStart; y < mtls.yEnd; y++) {
-                    uint32_t offset = mtls.dimX * mtls.dimY * mtls.dimZ * ar +
-                                      mtls.dimX * mtls.dimY * z +
-                                      mtls.dimX * y;
-                    uint8_t *xPtrOut = mtls.ptrOut + (mtls.eStrideOut * offset);
-                    const uint8_t *xPtrIn = mtls.ptrIn + (mtls.eStrideIn * offset);
-
-                    for (uint32_t x = mtls.xStart; x < mtls.xEnd; x++) {
-                        ((rs_t)mProgram.mRoot) (xPtrIn, xPtrOut, usr, x, y, z, ar);
-                        xPtrIn += mtls.eStrideIn;
-                        xPtrOut += mtls.eStrideOut;
-                    }
-                }
-            }
-        }
-    }
-
-    setTLS(oldTLS);
+    rsc->mHal.funcs.script.invokeForEach(rsc, this, ain, aout, usr, usrBytes, sc);
 }
 
 void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, uint32_t len) {
-    if ((slot >= mEnviroment.mInvokeFunctionCount) ||
-        (mEnviroment.mInvokeFunctions[slot] == NULL)) {
+    if (slot >= mHal.info.exportedFunctionCount) {
         rsc->setError(RS_ERROR_BAD_SCRIPT, "Calling invoke on bad script");
         return;
     }
     setupScript(rsc);
-    Script * oldTLS = setTLS(this);
 
     if (rsc->props.mLogScripts) {
-        LOGV("%p ScriptC::Invoke invoking slot %i,  ptr %p", rsc, slot, mEnviroment.mInvokeFunctions[slot]);
+        LOGV("%p ScriptC::Invoke invoking slot %i,  ptr %p", rsc, slot, this);
     }
-    ((void (*)(const void *, uint32_t))
-        mEnviroment.mInvokeFunctions[slot])(data, len);
-    if (rsc->props.mLogScripts) {
-        LOGV("%p ScriptC::Invoke complete", rsc);
-    }
-
-    setTLS(oldTLS);
+    rsc->mHal.funcs.script.invokeFunction(rsc, this, slot, data, len);
 }
 
 ScriptCState::ScriptCState() {
@@ -434,13 +148,14 @@
 ScriptCState::~ScriptCState() {
 }
 
+/*
 static void* symbolLookup(void* pContext, char const* name) {
     const ScriptCState::SymbolTable_t *sym;
     ScriptC *s = (ScriptC *)pContext;
     if (!strcmp(name, "__isThreadable")) {
-      return (void*) s->mEnviroment.mIsThreadable;
+      return (void*) s->mHal.info.isThreadable;
     } else if (!strcmp(name, "__clearThreadable")) {
-      s->mEnviroment.mIsThreadable = false;
+      s->mHal.info.isThreadable = false;
       return NULL;
     }
     sym = ScriptCState::lookupSymbol(name);
@@ -451,161 +166,99 @@
         sym = ScriptCState::lookupSymbolGL(name);
     }
     if (sym) {
-        s->mEnviroment.mIsThreadable &= sym->threadable;
+        s->mHal.info.isThreadable &= sym->threadable;
         return sym->mPtr;
     }
     LOGE("ScriptC sym lookup failed for %s", name);
     return NULL;
 }
+*/
 
 #if 0
 extern const char rs_runtime_lib_bc[];
 extern unsigned rs_runtime_lib_bc_size;
 #endif
 
-bool ScriptCState::runCompiler(Context *rsc,
-                               ScriptC *s,
-                               const char *resName,
-                               const char *cacheDir) {
-    s->mBccScript = bccCreateScript();
+bool ScriptC::runCompiler(Context *rsc,
+                          const char *resName,
+                          const char *cacheDir,
+                          const uint8_t *bitcode,
+                          size_t bitcodeLen) {
 
-    s->mEnviroment.mIsThreadable = true;
+    //LOGE("runCompiler %p %p %p %p %p %i", rsc, this, resName, cacheDir, bitcode, bitcodeLen);
 
-    if (bccRegisterSymbolCallback(s->mBccScript, symbolLookup, s) != 0) {
-        LOGE("bcc: FAILS to register symbol callback");
-        return false;
-    }
+    rsc->mHal.funcs.script.init(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0);
 
-    if (bccReadBC(s->mBccScript,
-                  resName,
-                  s->mEnviroment.mScriptText,
-                  s->mEnviroment.mScriptTextLength, 0) != 0) {
-        LOGE("bcc: FAILS to read bitcode");
-        return false;
-    }
+    mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
+    mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
+    mEnviroment.mFragmentStore.set(rsc->getDefaultProgramStore());
+    mEnviroment.mRaster.set(rsc->getDefaultProgramRaster());
 
-#if 1
-    if (bccLinkBC(s->mBccScript,
-                  resName,
-                  NULL /*rs_runtime_lib_bc*/,
-                  1 /*rs_runtime_lib_bc_size*/
-                    /*"1" means skip buffer here, and let libbcc decide*/,
-                  0) != 0) {
-        LOGE("bcc: FAILS to link bitcode");
-        return false;
-    }
-#endif
-    char *cachePath = genCacheFileName(cacheDir, resName, ".oBCC");
+    rsc->mHal.funcs.script.invokeInit(rsc, this);
 
-    if (bccPrepareExecutable(s->mBccScript, cachePath, 0) != 0) {
-        LOGE("bcc: FAILS to prepare executable");
-        return false;
-    }
-
-    free(cachePath);
-
-    s->mProgram.mRoot = reinterpret_cast<int (*)()>(bccGetFuncAddr(s->mBccScript, "root"));
-    s->mProgram.mInit = reinterpret_cast<void (*)()>(bccGetFuncAddr(s->mBccScript, "init"));
-
-    if (s->mProgram.mInit) {
-        s->mProgram.mInit();
-    }
-
-    s->mEnviroment.mInvokeFunctionCount = bccGetExportFuncCount(s->mBccScript);
-    if (s->mEnviroment.mInvokeFunctionCount <= 0)
-        s->mEnviroment.mInvokeFunctions = NULL;
-    else {
-        s->mEnviroment.mInvokeFunctions = (Script::InvokeFunc_t*) calloc(s->mEnviroment.mInvokeFunctionCount, sizeof(Script::InvokeFunc_t));
-        bccGetExportFuncList(s->mBccScript, s->mEnviroment.mInvokeFunctionCount, (void **) s->mEnviroment.mInvokeFunctions);
-    }
-
-    s->mEnviroment.mFieldCount = bccGetExportVarCount(s->mBccScript);
-    if (s->mEnviroment.mFieldCount <= 0)
-        s->mEnviroment.mFieldAddress = NULL;
-    else {
-        s->mEnviroment.mFieldAddress = (void **) calloc(s->mEnviroment.mFieldCount, sizeof(void *));
-        bccGetExportVarList(s->mBccScript, s->mEnviroment.mFieldCount, (void **) s->mEnviroment.mFieldAddress);
-        s->initSlots();
-    }
-
-    s->mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
-    s->mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
-    s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramStore());
-    s->mEnviroment.mRaster.set(rsc->getDefaultProgramRaster());
-
-    const static int pragmaMax = 16;
-    size_t pragmaCount = bccGetPragmaCount(s->mBccScript);
-    char const *keys[pragmaMax];
-    char const *values[pragmaMax];
-    bccGetPragmaList(s->mBccScript, pragmaMax, keys, values);
-
-    for (size_t i=0; i < pragmaCount; ++i) {
+    for (size_t i=0; i < mHal.info.exportedPragmaCount; ++i) {
+        const char * key = mHal.info.exportedPragmaKeyList[i];
+        const char * value = mHal.info.exportedPragmaValueList[i];
         //LOGE("pragma %s %s", keys[i], values[i]);
-        if (!strcmp(keys[i], "version")) {
-            if (!strcmp(values[i], "1")) {
+        if (!strcmp(key, "version")) {
+            if (!strcmp(value, "1")) {
                 continue;
             }
-            LOGE("Invalid version pragma value: %s\n", values[i]);
+            LOGE("Invalid version pragma value: %s\n", value);
             return false;
         }
 
-        if (!strcmp(keys[i], "stateVertex")) {
-            if (!strcmp(values[i], "default")) {
+        if (!strcmp(key, "stateVertex")) {
+            if (!strcmp(value, "default")) {
                 continue;
             }
-            if (!strcmp(values[i], "parent")) {
-                s->mEnviroment.mVertex.clear();
+            if (!strcmp(value, "parent")) {
+                mEnviroment.mVertex.clear();
                 continue;
             }
-            LOGE("Unrecognized value %s passed to stateVertex", values[i]);
+            LOGE("Unrecognized value %s passed to stateVertex", value);
             return false;
         }
 
-        if (!strcmp(keys[i], "stateRaster")) {
-            if (!strcmp(values[i], "default")) {
+        if (!strcmp(key, "stateRaster")) {
+            if (!strcmp(value, "default")) {
                 continue;
             }
-            if (!strcmp(values[i], "parent")) {
-                s->mEnviroment.mRaster.clear();
+            if (!strcmp(value, "parent")) {
+                mEnviroment.mRaster.clear();
                 continue;
             }
-            LOGE("Unrecognized value %s passed to stateRaster", values[i]);
+            LOGE("Unrecognized value %s passed to stateRaster", value);
             return false;
         }
 
-        if (!strcmp(keys[i], "stateFragment")) {
-            if (!strcmp(values[i], "default")) {
+        if (!strcmp(key, "stateFragment")) {
+            if (!strcmp(value, "default")) {
                 continue;
             }
-            if (!strcmp(values[i], "parent")) {
-                s->mEnviroment.mFragment.clear();
+            if (!strcmp(value, "parent")) {
+                mEnviroment.mFragment.clear();
                 continue;
             }
-            LOGE("Unrecognized value %s passed to stateFragment", values[i]);
+            LOGE("Unrecognized value %s passed to stateFragment", value);
             return false;
         }
 
-        if (!strcmp(keys[i], "stateStore")) {
-            if (!strcmp(values[i], "default")) {
+        if (!strcmp(key, "stateStore")) {
+            if (!strcmp(value, "default")) {
                 continue;
             }
-            if (!strcmp(values[i], "parent")) {
-                s->mEnviroment.mFragmentStore.clear();
+            if (!strcmp(value, "parent")) {
+                mEnviroment.mFragmentStore.clear();
                 continue;
             }
-            LOGE("Unrecognized value %s passed to stateStore", values[i]);
+            LOGE("Unrecognized value %s passed to stateStore", value);
             return false;
         }
     }
 
-    size_t objectSlotCount = bccGetObjectSlotCount(s->mBccScript);
-    uint32_t *objectSlots = NULL;
-    if (objectSlotCount) {
-        objectSlots = new uint32_t[objectSlotCount];
-        bccGetObjectSlotList(s->mBccScript, objectSlotCount, objectSlots);
-        s->mProgram.mObjectSlotList = objectSlots;
-        s->mProgram.mObjectSlotCount = objectSlotCount;
-    }
+    mSlots = new ObjectBaseRef<Allocation>[mHal.info.exportedVariableCount];
+    mTypes = new ObjectBaseRef<const Type>[mHal.info.exportedVariableCount];
 
     return true;
 }
@@ -613,39 +266,20 @@
 namespace android {
 namespace renderscript {
 
-void rsi_ScriptCBegin(Context * rsc) {
-}
-
-void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) {
-    ScriptCState *ss = &rsc->mScriptC;
-
-    char *t = (char *)malloc(len + 1);
-    memcpy(t, text, len);
-    t[len] = 0;
-    ss->mScriptText = t;
-    ss->mScriptLen = len;
-}
-
-
 RsScript rsi_ScriptCCreate(Context *rsc,
-                           const char *packageName /* deprecated */,
-                           const char *resName,
-                           const char *cacheDir)
+                           const char *resName, size_t resName_length,
+                           const char *cacheDir, size_t cacheDir_length,
+                           const char *text, uint32_t text_length)
 {
-    ScriptCState *ss = &rsc->mScriptC;
-
     ScriptC *s = new ScriptC(rsc);
-    s->mEnviroment.mScriptText = ss->mScriptText;
-    s->mEnviroment.mScriptTextLength = ss->mScriptLen;
-    ss->mScriptText = NULL;
-    ss->mScriptLen = 0;
-    s->incUserRef();
 
-    if (!ss->runCompiler(rsc, s, resName, cacheDir)) {
+    if (!s->runCompiler(rsc, resName, cacheDir, (uint8_t *)text, text_length)) {
         // Error during compile, destroy s and return null.
         delete s;
         return NULL;
     }
+
+    s->incUserRef();
     return s;
 }
 
diff --git a/rsScriptC.h b/rsScriptC.h
index e794feb..4c85745 100644
--- a/rsScriptC.h
+++ b/rsScriptC.h
@@ -21,7 +21,6 @@
 
 #include "RenderScriptEnv.h"
 
-#include <bcc/bcc.h>
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -36,21 +35,6 @@
     ScriptC(Context *);
     virtual ~ScriptC();
 
-    struct Program_t {
-        int mVersionMajor;
-        int mVersionMinor;
-
-        RunScript_t mRoot;
-        VoidFunc_t mInit;
-
-        uint32_t * mObjectSlotList;
-        uint32_t mObjectSlotCount;
-    };
-
-
-    Program_t mProgram;
-
-    BCCScriptRef mBccScript;
 
     const Allocation *ptrToAllocation(const void *) const;
 
@@ -63,13 +47,17 @@
                             const Allocation * ain,
                             Allocation * aout,
                             const void * usr,
+                            size_t usrBytes,
                             const RsScriptCall *sc = NULL);
 
     virtual void serialize(OStream *stream) const {    }
     virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_SCRIPT_C; }
     static Type *createFromStream(Context *rsc, IStream *stream) { return NULL; }
 
-protected:
+    bool runCompiler(Context *rsc, const char *resName, const char *cacheDir,
+                     const uint8_t *bitcode, size_t bitcodeLen);
+
+//protected:
     void setupScript(Context *);
     void setupGLState(Context *);
     Script * setTLS(Script *);
@@ -83,8 +71,6 @@
     char * mScriptText;
     size_t mScriptLen;
 
-    bool runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir);
-
     struct SymbolTable_t {
         const char * mName;
         void * mPtr;
diff --git a/rsScriptC_Lib.cpp b/rsScriptC_Lib.cpp
index 80da8ae..4ee0a3e 100644
--- a/rsScriptC_Lib.cpp
+++ b/rsScriptC_Lib.cpp
@@ -16,7 +16,9 @@
 
 #include "rsContext.h"
 #include "rsScriptC.h"
-#include "rsMatrix.h"
+#include "rsMatrix4x4.h"
+#include "rsMatrix3x3.h"
+#include "rsMatrix2x2.h"
 
 #include "utils/Timers.h"
 
@@ -25,16 +27,16 @@
 using namespace android;
 using namespace android::renderscript;
 
-#define GET_TLS()  Context::ScriptTLSStruct * tls = \
-    (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
-    Context * rsc = tls->mContext; \
-    ScriptC * sc = (ScriptC *) tls->mScript
+
+namespace android {
+namespace renderscript {
 
 
 //////////////////////////////////////////////////////////////////////////////
 // Math routines
 //////////////////////////////////////////////////////////////////////////////
 
+#if 0
 static float SC_sinf_fast(float x) {
     const float A =   1.0f / (2.0f * M_PI);
     const float B = -16.0f;
@@ -70,43 +72,17 @@
     const float y = B * x * fabsf(x) + C * x;
     return 0.2215f * (y * fabsf(y) - y) + y;
 }
-
-static float SC_randf(float max) {
-    float r = (float)rand();
-    r *= max;
-    return r / RAND_MAX;
-}
-
-static float SC_randf2(float min, float max) {
-    float r = (float)rand();
-    r = r * (max - min) + min;
-    return r / RAND_MAX;
-}
-
-static int SC_randi(int max) {
-    return (int)SC_randf(max);
-}
-
-static int SC_randi2(int min, int max) {
-    return (int)SC_randf2(min, max);
-}
-
-static float SC_frac(float v) {
-    int i = (int)floor(v);
-    return fmin(v - i, 0x1.fffffep-1f);
-}
+#endif
 
 //////////////////////////////////////////////////////////////////////////////
 // Time routines
 //////////////////////////////////////////////////////////////////////////////
 
-static time_t SC_time(time_t *timer) {
-    GET_TLS();
+time_t rsrTime(Context *rsc, Script *sc, time_t *timer) {
     return time(timer);
 }
 
-static tm* SC_localtime(tm *local, time_t *timer) {
-    GET_TLS();
+tm* rsrLocalTime(Context *rsc, Script *sc, tm *local, time_t *timer) {
     if (!local) {
       return NULL;
     }
@@ -120,16 +96,15 @@
     return local;
 }
 
-static int64_t SC_uptimeMillis() {
+int64_t rsrUptimeMillis(Context *rsc, Script *sc) {
     return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
 }
 
-static int64_t SC_uptimeNanos() {
+int64_t rsrUptimeNanos(Context *rsc, Script *sc) {
     return systemTime(SYSTEM_TIME_MONOTONIC);
 }
 
-static float SC_getDt() {
-    GET_TLS();
+float rsrGetDt(Context *rsc, Script *sc) {
     int64_t l = sc->mEnviroment.mLastDtTime;
     sc->mEnviroment.mLastDtTime = systemTime(SYSTEM_TIME_MONOTONIC);
     return ((float)(sc->mEnviroment.mLastDtTime - l)) / 1.0e9;
@@ -139,883 +114,61 @@
 //
 //////////////////////////////////////////////////////////////////////////////
 
-static uint32_t SC_allocGetDimX(RsAllocation va) {
-    const Allocation *a = static_cast<const Allocation *>(va);
-    CHECK_OBJ(a);
-    //LOGE("SC_allocGetDimX a=%p  type=%p", a, a->getType());
-    return a->getType()->getDimX();
-}
-
-static uint32_t SC_allocGetDimY(RsAllocation va) {
-    const Allocation *a = static_cast<const Allocation *>(va);
-    CHECK_OBJ(a);
-    return a->getType()->getDimY();
-}
-
-static uint32_t SC_allocGetDimZ(RsAllocation va) {
-    const Allocation *a = static_cast<const Allocation *>(va);
-    CHECK_OBJ(a);
-    return a->getType()->getDimZ();
-}
-
-static uint32_t SC_allocGetDimLOD(RsAllocation va) {
-    const Allocation *a = static_cast<const Allocation *>(va);
-    CHECK_OBJ(a);
-    return a->getType()->getDimLOD();
-}
-
-static uint32_t SC_allocGetDimFaces(RsAllocation va) {
-    const Allocation *a = static_cast<const Allocation *>(va);
-    CHECK_OBJ(a);
-    return a->getType()->getDimFaces();
-}
-
-static const void * SC_getElementAtX(RsAllocation va, uint32_t x) {
-    const Allocation *a = static_cast<const Allocation *>(va);
-    CHECK_OBJ(a);
-    const Type *t = a->getType();
-    CHECK_OBJ(t);
-    const uint8_t *p = (const uint8_t *)a->getPtr();
-    return &p[t->getElementSizeBytes() * x];
-}
-
-static const void * SC_getElementAtXY(RsAllocation va, uint32_t x, uint32_t y) {
-    const Allocation *a = static_cast<const Allocation *>(va);
-    CHECK_OBJ(a);
-    const Type *t = a->getType();
-    CHECK_OBJ(t);
-    const uint8_t *p = (const uint8_t *)a->getPtr();
-    return &p[t->getElementSizeBytes() * (x + y*t->getDimX())];
-}
-
-static const void * SC_getElementAtXYZ(RsAllocation va, uint32_t x, uint32_t y, uint32_t z) {
-    const Allocation *a = static_cast<const Allocation *>(va);
-    CHECK_OBJ(a);
-    const Type *t = a->getType();
-    CHECK_OBJ(t);
-    const uint8_t *p = (const uint8_t *)a->getPtr();
-    return &p[t->getElementSizeBytes() * (x + y*t->getDimX())];
-}
-
-static void SC_setObject(void **vdst, void * vsrc) {
-    //LOGE("SC_setObject  %p,%p  %p", vdst, *vdst, vsrc);
-    if (vsrc) {
-        CHECK_OBJ(vsrc);
-        static_cast<ObjectBase *>(vsrc)->incSysRef();
+void rsrSetObject(const Context *rsc, const Script *sc, ObjectBase **dst, ObjectBase * src) {
+    //LOGE("rsiSetObject  %p,%p  %p", vdst, *vdst, vsrc);
+    if (src) {
+        CHECK_OBJ(src);
+        src->incSysRef();
     }
-    if (vdst[0]) {
-        CHECK_OBJ(vdst[0]);
-        static_cast<ObjectBase *>(vdst[0])->decSysRef();
+    if (dst[0]) {
+        CHECK_OBJ(dst[0]);
+        dst[0]->decSysRef();
     }
-    *vdst = vsrc;
-    //LOGE("SC_setObject *");
+    *dst = src;
 }
 
-static void SC_clearObject(void **vdst) {
-    //LOGE("SC_clearObject  %p,%p", vdst, *vdst);
-    if (vdst[0]) {
-        CHECK_OBJ(vdst[0]);
-        static_cast<ObjectBase *>(vdst[0])->decSysRef();
+void rsrClearObject(const Context *rsc, const Script *sc, ObjectBase **dst) {
+    //LOGE("rsiClearObject  %p,%p", vdst, *vdst);
+    if (dst[0]) {
+        CHECK_OBJ(dst[0]);
+        dst[0]->decSysRef();
     }
-    *vdst = NULL;
-    //LOGE("SC_clearObject *");
+    *dst = NULL;
 }
 
-static bool SC_isObject(RsAllocation vsrc) {
-    return vsrc != NULL;
+bool rsrIsObject(const Context *rsc, const Script *sc, const ObjectBase *src) {
+    return src != NULL;
 }
 
-static void SC_debugF(const char *s, float f) {
-    LOGD("%s %f, 0x%08x", s, f, *((int *) (&f)));
-}
-static void SC_debugFv2(const char *s, float f1, float f2) {
-    LOGD("%s {%f, %f}", s, f1, f2);
-}
-static void SC_debugFv3(const char *s, float f1, float f2, float f3) {
-    LOGD("%s {%f, %f, %f}", s, f1, f2, f3);
-}
-static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) {
-    LOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
-}
-static void SC_debugD(const char *s, double d) {
-    LOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
-}
-static void SC_debugFM4v4(const char *s, const float *f) {
-    LOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
-    LOGD("%s  %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
-    LOGD("%s  %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
-    LOGD("%s  %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
-}
-static void SC_debugFM3v3(const char *s, const float *f) {
-    LOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
-    LOGD("%s  %f, %f, %f", s, f[1], f[4], f[7]);
-    LOGD("%s  %f, %f, %f}",s, f[2], f[5], f[8]);
-}
-static void SC_debugFM2v2(const char *s, const float *f) {
-    LOGD("%s {%f, %f", s, f[0], f[2]);
-    LOGD("%s  %f, %f}",s, f[1], f[3]);
-}
 
-static void SC_debugI32(const char *s, int32_t i) {
-    LOGD("%s %i  0x%x", s, i, i);
-}
-static void SC_debugU32(const char *s, uint32_t i) {
-    LOGD("%s %u  0x%x", s, i, i);
-}
-static void SC_debugLL64(const char *s, long long ll) {
-    LOGD("%s %lld  0x%llx", s, ll, ll);
-}
-static void SC_debugULL64(const char *s, unsigned long long ll) {
-    LOGD("%s %llu  0x%llx", s, ll, ll);
-}
-
-static void SC_debugP(const char *s, const void *p) {
-    LOGD("%s %p", s, p);
-}
-
-static uint32_t SC_toClient2(int cmdID, void *data, int len) {
-    GET_TLS();
+uint32_t rsrToClient(Context *rsc, Script *sc, int cmdID, void *data, int len) {
     //LOGE("SC_toClient %i %i %i", cmdID, len);
     return rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, cmdID, len, false);
 }
 
-static uint32_t SC_toClient(int cmdID) {
-    GET_TLS();
-    //LOGE("SC_toClient %i", cmdID);
-    return rsc->sendMessageToClient(NULL, RS_MESSAGE_TO_CLIENT_USER, cmdID, 0, false);
-}
-
-static uint32_t SC_toClientBlocking2(int cmdID, void *data, int len) {
-    GET_TLS();
+uint32_t rsrToClientBlocking(Context *rsc, Script *sc, int cmdID, void *data, int len) {
     //LOGE("SC_toClientBlocking %i %i", cmdID, len);
     return rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, cmdID, len, true);
 }
 
-static uint32_t SC_toClientBlocking(int cmdID) {
-    GET_TLS();
-    //LOGE("SC_toClientBlocking %i", cmdID);
-    return rsc->sendMessageToClient(NULL, RS_MESSAGE_TO_CLIENT_USER, cmdID, 0, true);
-}
 
-int SC_divsi3(int a, int b) {
-    return a / b;
-}
-
-int SC_modsi3(int a, int b) {
-    return a % b;
-}
-
-unsigned int SC_udivsi3(unsigned int a, unsigned int b) {
-    return a / b;
-}
-
-unsigned int SC_umodsi3(unsigned int a, unsigned int b) {
-    return a % b;
-}
-
-int SC_getAllocation(const void *ptr) {
-    GET_TLS();
-    const Allocation *alloc = sc->ptrToAllocation(ptr);
-    return (int)alloc;
-}
-
-void SC_allocationMarkDirty(RsAllocation a) {
-    Allocation *alloc = static_cast<Allocation *>(a);
-    alloc->sendDirty();
-}
-
-void SC_ForEach(RsScript vs,
-                RsAllocation vin,
-                RsAllocation vout,
-                const void *usr) {
-    GET_TLS();
-    const Allocation *ain = static_cast<const Allocation *>(vin);
-    Allocation *aout = static_cast<Allocation *>(vout);
-    Script *s = static_cast<Script *>(vs);
-    s->runForEach(rsc, ain, aout, usr);
-}
-
-void SC_ForEach2(RsScript vs,
-                RsAllocation vin,
-                RsAllocation vout,
-                const void *usr,
+void rsrForEach(Context *rsc, Script *sc,
+                Script *target,
+                Allocation *in, Allocation *out,
+                const void *usr, uint32_t usrBytes,
                 const RsScriptCall *call) {
-    GET_TLS();
-    const Allocation *ain = static_cast<const Allocation *>(vin);
-    Allocation *aout = static_cast<Allocation *>(vout);
-    Script *s = static_cast<Script *>(vs);
-    s->runForEach(rsc, ain, aout, usr, call);
+    target->runForEach(rsc, in, out, usr, usrBytes, call);
 }
 
-
-//////////////////////////////////////////////////////////////////////////////
-// Heavy math functions
-//////////////////////////////////////////////////////////////////////////////
-
-typedef struct {
-    float m[16];
-} rs_matrix4x4;
-
-typedef struct {
-    float m[9];
-} rs_matrix3x3;
-
-typedef struct {
-    float m[4];
-} rs_matrix2x2;
-
-static inline void
-rsMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v) {
-    m->m[row * 4 + col] = v;
+void rsrAllocationSyncAll(Context *rsc, Script *sc, Allocation *a, RsAllocationUsageType usage) {
+    a->syncAll(rsc, usage);
 }
 
-static inline float
-rsMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col) {
-    return m->m[row * 4 + col];
+const Allocation * rsrGetAllocation(Context *rsc, Script *s, const void *ptr) {
+    ScriptC *sc = (ScriptC *)s;
+    return sc->ptrToAllocation(ptr);
 }
 
-static inline void
-rsMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v) {
-    m->m[row * 3 + col] = v;
+}
 }
 
-static inline float
-rsMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col) {
-    return m->m[row * 3 + col];
-}
-
-static inline void
-rsMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v) {
-    m->m[row * 2 + col] = v;
-}
-
-static inline float
-rsMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col) {
-    return m->m[row * 2 + col];
-}
-
-
-static void SC_MatrixLoadIdentity_4x4(rs_matrix4x4 *m) {
-    m->m[0] = 1.f;
-    m->m[1] = 0.f;
-    m->m[2] = 0.f;
-    m->m[3] = 0.f;
-    m->m[4] = 0.f;
-    m->m[5] = 1.f;
-    m->m[6] = 0.f;
-    m->m[7] = 0.f;
-    m->m[8] = 0.f;
-    m->m[9] = 0.f;
-    m->m[10] = 1.f;
-    m->m[11] = 0.f;
-    m->m[12] = 0.f;
-    m->m[13] = 0.f;
-    m->m[14] = 0.f;
-    m->m[15] = 1.f;
-}
-
-static void SC_MatrixLoadIdentity_3x3(rs_matrix3x3 *m) {
-    m->m[0] = 1.f;
-    m->m[1] = 0.f;
-    m->m[2] = 0.f;
-    m->m[3] = 0.f;
-    m->m[4] = 1.f;
-    m->m[5] = 0.f;
-    m->m[6] = 0.f;
-    m->m[7] = 0.f;
-    m->m[8] = 1.f;
-}
-
-static void SC_MatrixLoadIdentity_2x2(rs_matrix2x2 *m) {
-    m->m[0] = 1.f;
-    m->m[1] = 0.f;
-    m->m[2] = 0.f;
-    m->m[3] = 1.f;
-}
-
-static void SC_MatrixLoad_4x4_f(rs_matrix4x4 *m, const float *v) {
-    m->m[0] = v[0];
-    m->m[1] = v[1];
-    m->m[2] = v[2];
-    m->m[3] = v[3];
-    m->m[4] = v[4];
-    m->m[5] = v[5];
-    m->m[6] = v[6];
-    m->m[7] = v[7];
-    m->m[8] = v[8];
-    m->m[9] = v[9];
-    m->m[10] = v[10];
-    m->m[11] = v[11];
-    m->m[12] = v[12];
-    m->m[13] = v[13];
-    m->m[14] = v[14];
-    m->m[15] = v[15];
-}
-
-static void SC_MatrixLoad_3x3_f(rs_matrix3x3 *m, const float *v) {
-    m->m[0] = v[0];
-    m->m[1] = v[1];
-    m->m[2] = v[2];
-    m->m[3] = v[3];
-    m->m[4] = v[4];
-    m->m[5] = v[5];
-    m->m[6] = v[6];
-    m->m[7] = v[7];
-    m->m[8] = v[8];
-}
-
-static void SC_MatrixLoad_2x2_f(rs_matrix2x2 *m, const float *v) {
-    m->m[0] = v[0];
-    m->m[1] = v[1];
-    m->m[2] = v[2];
-    m->m[3] = v[3];
-}
-
-static void SC_MatrixLoad_4x4_4x4(rs_matrix4x4 *m, const rs_matrix4x4 *v) {
-    m->m[0] = v->m[0];
-    m->m[1] = v->m[1];
-    m->m[2] = v->m[2];
-    m->m[3] = v->m[3];
-    m->m[4] = v->m[4];
-    m->m[5] = v->m[5];
-    m->m[6] = v->m[6];
-    m->m[7] = v->m[7];
-    m->m[8] = v->m[8];
-    m->m[9] = v->m[9];
-    m->m[10] = v->m[10];
-    m->m[11] = v->m[11];
-    m->m[12] = v->m[12];
-    m->m[13] = v->m[13];
-    m->m[14] = v->m[14];
-    m->m[15] = v->m[15];
-}
-
-static void SC_MatrixLoad_4x4_3x3(rs_matrix4x4 *m, const rs_matrix3x3 *v) {
-    m->m[0] = v->m[0];
-    m->m[1] = v->m[1];
-    m->m[2] = v->m[2];
-    m->m[3] = 0.f;
-    m->m[4] = v->m[3];
-    m->m[5] = v->m[4];
-    m->m[6] = v->m[5];
-    m->m[7] = 0.f;
-    m->m[8] = v->m[6];
-    m->m[9] = v->m[7];
-    m->m[10] = v->m[8];
-    m->m[11] = 0.f;
-    m->m[12] = 0.f;
-    m->m[13] = 0.f;
-    m->m[14] = 0.f;
-    m->m[15] = 1.f;
-}
-
-static void SC_MatrixLoad_4x4_2x2(rs_matrix4x4 *m, const rs_matrix2x2 *v) {
-    m->m[0] = v->m[0];
-    m->m[1] = v->m[1];
-    m->m[2] = 0.f;
-    m->m[3] = 0.f;
-    m->m[4] = v->m[2];
-    m->m[5] = v->m[3];
-    m->m[6] = 0.f;
-    m->m[7] = 0.f;
-    m->m[8] = 0.f;
-    m->m[9] = 0.f;
-    m->m[10] = 1.f;
-    m->m[11] = 0.f;
-    m->m[12] = 0.f;
-    m->m[13] = 0.f;
-    m->m[14] = 0.f;
-    m->m[15] = 1.f;
-}
-
-static void SC_MatrixLoad_3x3_3x3(rs_matrix3x3 *m, const rs_matrix3x3 *v) {
-    m->m[0] = v->m[0];
-    m->m[1] = v->m[1];
-    m->m[2] = v->m[2];
-    m->m[3] = v->m[3];
-    m->m[4] = v->m[4];
-    m->m[5] = v->m[5];
-    m->m[6] = v->m[6];
-    m->m[7] = v->m[7];
-    m->m[8] = v->m[8];
-}
-
-static void SC_MatrixLoad_2x2_2x2(rs_matrix2x2 *m, const rs_matrix2x2 *v) {
-    m->m[0] = v->m[0];
-    m->m[1] = v->m[1];
-    m->m[2] = v->m[2];
-    m->m[3] = v->m[3];
-}
-
-static void SC_MatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) {
-    float c, s;
-    m->m[3] = 0;
-    m->m[7] = 0;
-    m->m[11]= 0;
-    m->m[12]= 0;
-    m->m[13]= 0;
-    m->m[14]= 0;
-    m->m[15]= 1;
-    rot *= (float)(M_PI / 180.0f);
-    c = cos(rot);
-    s = sin(rot);
-
-    const float len = x*x + y*y + z*z;
-    if (len != 1) {
-        const float recipLen = 1.f / sqrt(len);
-        x *= recipLen;
-        y *= recipLen;
-        z *= recipLen;
-    }
-    const float nc = 1.0f - c;
-    const float xy = x * y;
-    const float yz = y * z;
-    const float zx = z * x;
-    const float xs = x * s;
-    const float ys = y * s;
-    const float zs = z * s;
-    m->m[ 0] = x*x*nc +  c;
-    m->m[ 4] =  xy*nc - zs;
-    m->m[ 8] =  zx*nc + ys;
-    m->m[ 1] =  xy*nc + zs;
-    m->m[ 5] = y*y*nc +  c;
-    m->m[ 9] =  yz*nc - xs;
-    m->m[ 2] =  zx*nc - ys;
-    m->m[ 6] =  yz*nc + xs;
-    m->m[10] = z*z*nc +  c;
-}
-
-static void SC_MatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z) {
-    SC_MatrixLoadIdentity_4x4(m);
-    m->m[0] = x;
-    m->m[5] = y;
-    m->m[10] = z;
-}
-
-static void SC_MatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z) {
-    SC_MatrixLoadIdentity_4x4(m);
-    m->m[12] = x;
-    m->m[13] = y;
-    m->m[14] = z;
-}
-
-static void SC_MatrixLoadMultiply_4x4_4x4_4x4(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
-    for (int i=0 ; i<4 ; i++) {
-        float ri0 = 0;
-        float ri1 = 0;
-        float ri2 = 0;
-        float ri3 = 0;
-        for (int j=0 ; j<4 ; j++) {
-            const float rhs_ij = rsMatrixGet(rhs, i,j);
-            ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
-            ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
-            ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij;
-            ri3 += rsMatrixGet(lhs, j, 3) * rhs_ij;
-        }
-        rsMatrixSet(m, i, 0, ri0);
-        rsMatrixSet(m, i, 1, ri1);
-        rsMatrixSet(m, i, 2, ri2);
-        rsMatrixSet(m, i, 3, ri3);
-    }
-}
-
-static void SC_MatrixMultiply_4x4_4x4(rs_matrix4x4 *m, const rs_matrix4x4 *rhs) {
-    rs_matrix4x4 mt;
-    SC_MatrixLoadMultiply_4x4_4x4_4x4(&mt, m, rhs);
-    SC_MatrixLoad_4x4_4x4(m, &mt);
-}
-
-static void SC_MatrixLoadMultiply_3x3_3x3_3x3(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
-    for (int i=0 ; i<3 ; i++) {
-        float ri0 = 0;
-        float ri1 = 0;
-        float ri2 = 0;
-        for (int j=0 ; j<3 ; j++) {
-            const float rhs_ij = rsMatrixGet(rhs, i,j);
-            ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
-            ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
-            ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij;
-        }
-        rsMatrixSet(m, i, 0, ri0);
-        rsMatrixSet(m, i, 1, ri1);
-        rsMatrixSet(m, i, 2, ri2);
-    }
-}
-
-static void SC_MatrixMultiply_3x3_3x3(rs_matrix3x3 *m, const rs_matrix3x3 *rhs) {
-    rs_matrix3x3 mt;
-    SC_MatrixLoadMultiply_3x3_3x3_3x3(&mt, m, rhs);
-    SC_MatrixLoad_3x3_3x3(m, &mt);
-}
-
-static void SC_MatrixLoadMultiply_2x2_2x2_2x2(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
-    for (int i=0 ; i<2 ; i++) {
-        float ri0 = 0;
-        float ri1 = 0;
-        for (int j=0 ; j<2 ; j++) {
-            const float rhs_ij = rsMatrixGet(rhs, i,j);
-            ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
-            ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
-        }
-        rsMatrixSet(m, i, 0, ri0);
-        rsMatrixSet(m, i, 1, ri1);
-    }
-}
-
-static void SC_MatrixMultiply_2x2_2x2(rs_matrix2x2 *m, const rs_matrix2x2 *rhs) {
-    rs_matrix2x2 mt;
-    SC_MatrixLoadMultiply_2x2_2x2_2x2(&mt, m, rhs);
-    SC_MatrixLoad_2x2_2x2(m, &mt);
-}
-
-static void SC_MatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) {
-    rs_matrix4x4 m1;
-    SC_MatrixLoadRotate(&m1, rot, x, y, z);
-    SC_MatrixMultiply_4x4_4x4(m, &m1);
-}
-
-static void SC_MatrixScale(rs_matrix4x4 *m, float x, float y, float z) {
-    rs_matrix4x4 m1;
-    SC_MatrixLoadScale(&m1, x, y, z);
-    SC_MatrixMultiply_4x4_4x4(m, &m1);
-}
-
-static void SC_MatrixTranslate(rs_matrix4x4 *m, float x, float y, float z) {
-    rs_matrix4x4 m1;
-    SC_MatrixLoadTranslate(&m1, x, y, z);
-    SC_MatrixMultiply_4x4_4x4(m, &m1);
-}
-
-static void SC_MatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) {
-    SC_MatrixLoadIdentity_4x4(m);
-    m->m[0] = 2.f / (right - left);
-    m->m[5] = 2.f / (top - bottom);
-    m->m[10]= -2.f / (far - near);
-    m->m[12]= -(right + left) / (right - left);
-    m->m[13]= -(top + bottom) / (top - bottom);
-    m->m[14]= -(far + near) / (far - near);
-}
-
-static void SC_MatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) {
-    SC_MatrixLoadIdentity_4x4(m);
-    m->m[0] = 2.f * near / (right - left);
-    m->m[5] = 2.f * near / (top - bottom);
-    m->m[8] = (right + left) / (right - left);
-    m->m[9] = (top + bottom) / (top - bottom);
-    m->m[10]= -(far + near) / (far - near);
-    m->m[11]= -1.f;
-    m->m[14]= -2.f * far * near / (far - near);
-    m->m[15]= 0.f;
-}
-
-static void SC_MatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far) {
-    float top = near * tan((float) (fovy * M_PI / 360.0f));
-    float bottom = -top;
-    float left = bottom * aspect;
-    float right = top * aspect;
-    SC_MatrixLoadFrustum(m, left, right, bottom, top, near, far);
-}
-
-
-// Returns true if the matrix was successfully inversed
-static bool SC_MatrixInverse_4x4(rs_matrix4x4 *m) {
-    rs_matrix4x4 result;
-
-    int i, j;
-    for (i = 0; i < 4; ++i) {
-        for (j = 0; j < 4; ++j) {
-            // computeCofactor for int i, int j
-            int c0 = (i+1) % 4;
-            int c1 = (i+2) % 4;
-            int c2 = (i+3) % 4;
-            int r0 = (j+1) % 4;
-            int r1 = (j+2) % 4;
-            int r2 = (j+3) % 4;
-
-            float minor = (m->m[c0 + 4*r0] * (m->m[c1 + 4*r1] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r1]))
-                         - (m->m[c0 + 4*r1] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r0]))
-                         + (m->m[c0 + 4*r2] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r1] - m->m[c1 + 4*r1] * m->m[c2 + 4*r0]));
-
-            float cofactor = (i+j) & 1 ? -minor : minor;
-
-            result.m[4*i + j] = cofactor;
-        }
-    }
-
-    // Dot product of 0th column of source and 0th row of result
-    float det = m->m[0]*result.m[0] + m->m[4]*result.m[1] +
-                 m->m[8]*result.m[2] + m->m[12]*result.m[3];
-
-    if (fabs(det) < 1e-6) {
-        return false;
-    }
-
-    det = 1.0f / det;
-    for (i = 0; i < 16; ++i) {
-        m->m[i] = result.m[i] * det;
-    }
-
-    return true;
-}
-
-// Returns true if the matrix was successfully inversed
-static bool SC_MatrixInverseTranspose_4x4(rs_matrix4x4 *m) {
-    rs_matrix4x4 result;
-
-    int i, j;
-    for (i = 0; i < 4; ++i) {
-        for (j = 0; j < 4; ++j) {
-            // computeCofactor for int i, int j
-            int c0 = (i+1) % 4;
-            int c1 = (i+2) % 4;
-            int c2 = (i+3) % 4;
-            int r0 = (j+1) % 4;
-            int r1 = (j+2) % 4;
-            int r2 = (j+3) % 4;
-
-            float minor = (m->m[c0 + 4*r0] * (m->m[c1 + 4*r1] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r1]))
-                         - (m->m[c0 + 4*r1] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r0]))
-                         + (m->m[c0 + 4*r2] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r1] - m->m[c1 + 4*r1] * m->m[c2 + 4*r0]));
-
-            float cofactor = (i+j) & 1 ? -minor : minor;
-
-            result.m[4*j + i] = cofactor;
-        }
-    }
-
-    // Dot product of 0th column of source and 0th column of result
-    float det = m->m[0]*result.m[0] + m->m[4]*result.m[4] +
-                 m->m[8]*result.m[8] + m->m[12]*result.m[12];
-
-    if (fabs(det) < 1e-6) {
-        return false;
-    }
-
-    det = 1.0f / det;
-    for (i = 0; i < 16; ++i) {
-        m->m[i] = result.m[i] * det;
-    }
-
-    return true;
-}
-
-static void SC_MatrixTranspose_4x4(rs_matrix4x4 *m) {
-    int i, j;
-    float temp;
-    for (i = 0; i < 3; ++i) {
-        for (j = i + 1; j < 4; ++j) {
-            temp = m->m[i*4 + j];
-            m->m[i*4 + j] = m->m[j*4 + i];
-            m->m[j*4 + i] = temp;
-        }
-    }
-}
-
-static void SC_MatrixTranspose_3x3(rs_matrix3x3 *m) {
-    int i, j;
-    float temp;
-    for (i = 0; i < 2; ++i) {
-        for (j = i + 1; j < 3; ++j) {
-            temp = m->m[i*3 + j];
-            m->m[i*3 + j] = m->m[j*4 + i];
-            m->m[j*3 + i] = temp;
-        }
-    }
-}
-
-static void SC_MatrixTranspose_2x2(rs_matrix2x2 *m) {
-    float temp = m->m[1];
-    m->m[1] = m->m[2];
-    m->m[2] = temp;
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-// Class implementation
-//////////////////////////////////////////////////////////////////////////////
-
-// llvm name mangling ref
-//  <builtin-type> ::= v  # void
-//                 ::= b  # bool
-//                 ::= c  # char
-//                 ::= a  # signed char
-//                 ::= h  # unsigned char
-//                 ::= s  # short
-//                 ::= t  # unsigned short
-//                 ::= i  # int
-//                 ::= j  # unsigned int
-//                 ::= l  # long
-//                 ::= m  # unsigned long
-//                 ::= x  # long long, __int64
-//                 ::= y  # unsigned long long, __int64
-//                 ::= f  # float
-//                 ::= d  # double
-
-static ScriptCState::SymbolTable_t gSyms[] = {
-    { "__divsi3", (void *)&SC_divsi3, true },
-    { "__modsi3", (void *)&SC_modsi3, true },
-    { "__udivsi3", (void *)&SC_udivsi3, true },
-    { "__umodsi3", (void *)&SC_umodsi3, true },
-    { "memset", (void *)&memset, true },
-    { "memcpy", (void *)&memcpy, true },
-
-    // allocation
-    { "_Z19rsAllocationGetDimX13rs_allocation", (void *)&SC_allocGetDimX, true },
-    { "_Z19rsAllocationGetDimY13rs_allocation", (void *)&SC_allocGetDimY, true },
-    { "_Z19rsAllocationGetDimZ13rs_allocation", (void *)&SC_allocGetDimZ, true },
-    { "_Z21rsAllocationGetDimLOD13rs_allocation", (void *)&SC_allocGetDimLOD, true },
-    { "_Z23rsAllocationGetDimFaces13rs_allocation", (void *)&SC_allocGetDimFaces, true },
-    { "_Z15rsGetAllocationPKv", (void *)&SC_getAllocation, true },
-
-    { "_Z14rsGetElementAt13rs_allocationj", (void *)&SC_getElementAtX, true },
-    { "_Z14rsGetElementAt13rs_allocationjj", (void *)&SC_getElementAtXY, true },
-    { "_Z14rsGetElementAt13rs_allocationjjj", (void *)&SC_getElementAtXYZ, true },
-
-    { "_Z11rsSetObjectP10rs_elementS_", (void *)&SC_setObject, true },
-    { "_Z13rsClearObjectP10rs_element", (void *)&SC_clearObject, true },
-    { "_Z10rsIsObject10rs_element", (void *)&SC_isObject, true },
-
-    { "_Z11rsSetObjectP7rs_typeS_", (void *)&SC_setObject, true },
-    { "_Z13rsClearObjectP7rs_type", (void *)&SC_clearObject, true },
-    { "_Z10rsIsObject7rs_type", (void *)&SC_isObject, true },
-
-    { "_Z11rsSetObjectP13rs_allocationS_", (void *)&SC_setObject, true },
-    { "_Z13rsClearObjectP13rs_allocation", (void *)&SC_clearObject, true },
-    { "_Z10rsIsObject13rs_allocation", (void *)&SC_isObject, true },
-
-    { "_Z11rsSetObjectP10rs_samplerS_", (void *)&SC_setObject, true },
-    { "_Z13rsClearObjectP10rs_sampler", (void *)&SC_clearObject, true },
-    { "_Z10rsIsObject10rs_sampler", (void *)&SC_isObject, true },
-
-    { "_Z11rsSetObjectP9rs_scriptS_", (void *)&SC_setObject, true },
-    { "_Z13rsClearObjectP9rs_script", (void *)&SC_clearObject, true },
-    { "_Z10rsIsObject9rs_script", (void *)&SC_isObject, true },
-
-    { "_Z11rsSetObjectP7rs_meshS_", (void *)&SC_setObject, true },
-    { "_Z13rsClearObjectP7rs_mesh", (void *)&SC_clearObject, true },
-    { "_Z10rsIsObject7rs_mesh", (void *)&SC_isObject, true },
-
-    { "_Z11rsSetObjectP19rs_program_fragmentS_", (void *)&SC_setObject, true },
-    { "_Z13rsClearObjectP19rs_program_fragment", (void *)&SC_clearObject, true },
-    { "_Z10rsIsObject19rs_program_fragment", (void *)&SC_isObject, true },
-
-    { "_Z11rsSetObjectP17rs_program_vertexS_", (void *)&SC_setObject, true },
-    { "_Z13rsClearObjectP17rs_program_vertex", (void *)&SC_clearObject, true },
-    { "_Z10rsIsObject17rs_program_vertex", (void *)&SC_isObject, true },
-
-    { "_Z11rsSetObjectP17rs_program_rasterS_", (void *)&SC_setObject, true },
-    { "_Z13rsClearObjectP17rs_program_raster", (void *)&SC_clearObject, true },
-    { "_Z10rsIsObject17rs_program_raster", (void *)&SC_isObject, true },
-
-    { "_Z11rsSetObjectP16rs_program_storeS_", (void *)&SC_setObject, true },
-    { "_Z13rsClearObjectP16rs_program_store", (void *)&SC_clearObject, true },
-    { "_Z10rsIsObject16rs_program_store", (void *)&SC_isObject, true },
-
-    { "_Z11rsSetObjectP7rs_fontS_", (void *)&SC_setObject, true },
-    { "_Z13rsClearObjectP7rs_font", (void *)&SC_clearObject, true },
-    { "_Z10rsIsObject7rs_font", (void *)&SC_isObject, true },
-
-
-    { "_Z21rsAllocationMarkDirty13rs_allocation", (void *)&SC_allocationMarkDirty, true },
-
-
-    // Debug
-    { "_Z7rsDebugPKcf", (void *)&SC_debugF, true },
-    { "_Z7rsDebugPKcff", (void *)&SC_debugFv2, true },
-    { "_Z7rsDebugPKcfff", (void *)&SC_debugFv3, true },
-    { "_Z7rsDebugPKcffff", (void *)&SC_debugFv4, true },
-    { "_Z7rsDebugPKcd", (void *)&SC_debugD, true },
-    { "_Z7rsDebugPKcPK12rs_matrix4x4", (void *)&SC_debugFM4v4, true },
-    { "_Z7rsDebugPKcPK12rs_matrix3x3", (void *)&SC_debugFM3v3, true },
-    { "_Z7rsDebugPKcPK12rs_matrix2x2", (void *)&SC_debugFM2v2, true },
-    { "_Z7rsDebugPKci", (void *)&SC_debugI32, true },
-    { "_Z7rsDebugPKcj", (void *)&SC_debugU32, true },
-    // Both "long" and "unsigned long" need to be redirected to their
-    // 64-bit counterparts, since we have hacked Slang to use 64-bit
-    // for "long" on Arm (to be similar to Java).
-    { "_Z7rsDebugPKcl", (void *)&SC_debugLL64, true },
-    { "_Z7rsDebugPKcm", (void *)&SC_debugULL64, true },
-    { "_Z7rsDebugPKcx", (void *)&SC_debugLL64, true },
-    { "_Z7rsDebugPKcy", (void *)&SC_debugULL64, true },
-    { "_Z7rsDebugPKcPKv", (void *)&SC_debugP, true },
-
-    // RS Math
-    { "_Z6rsRandi", (void *)&SC_randi, true },
-    { "_Z6rsRandii", (void *)&SC_randi2, true },
-    { "_Z6rsRandf", (void *)&SC_randf, true },
-    { "_Z6rsRandff", (void *)&SC_randf2, true },
-    { "_Z6rsFracf", (void *)&SC_frac, true },
-
-    // time
-    { "_Z6rsTimePi", (void *)&SC_time, true },
-    { "_Z11rsLocaltimeP5rs_tmPKi", (void *)&SC_localtime, true },
-    { "_Z14rsUptimeMillisv", (void*)&SC_uptimeMillis, true },
-    { "_Z13rsUptimeNanosv", (void*)&SC_uptimeNanos, true },
-    { "_Z7rsGetDtv", (void*)&SC_getDt, false },
-
-    { "_Z14rsSendToClienti", (void *)&SC_toClient, false },
-    { "_Z14rsSendToClientiPKvj", (void *)&SC_toClient2, false },
-    { "_Z22rsSendToClientBlockingi", (void *)&SC_toClientBlocking, false },
-    { "_Z22rsSendToClientBlockingiPKvj", (void *)&SC_toClientBlocking2, false },
-
-    // matrix
-    { "_Z20rsMatrixLoadIdentityP12rs_matrix4x4", (void *)&SC_MatrixLoadIdentity_4x4, false },
-    { "_Z20rsMatrixLoadIdentityP12rs_matrix3x3", (void *)&SC_MatrixLoadIdentity_3x3, false },
-    { "_Z20rsMatrixLoadIdentityP12rs_matrix2x2", (void *)&SC_MatrixLoadIdentity_2x2, false },
-
-    { "_Z12rsMatrixLoadP12rs_matrix4x4PKf", (void *)&SC_MatrixLoad_4x4_f, false },
-    { "_Z12rsMatrixLoadP12rs_matrix3x3PKf", (void *)&SC_MatrixLoad_3x3_f, false },
-    { "_Z12rsMatrixLoadP12rs_matrix2x2PKf", (void *)&SC_MatrixLoad_2x2_f, false },
-
-    { "_Z12rsMatrixLoadP12rs_matrix4x4PKS_", (void *)&SC_MatrixLoad_4x4_4x4, false },
-    { "_Z12rsMatrixLoadP12rs_matrix4x4PK12rs_matrix3x3", (void *)&SC_MatrixLoad_4x4_3x3, false },
-    { "_Z12rsMatrixLoadP12rs_matrix4x4PK12rs_matrix2x2", (void *)&SC_MatrixLoad_4x4_2x2, false },
-    { "_Z12rsMatrixLoadP12rs_matrix3x3PKS_", (void *)&SC_MatrixLoad_3x3_3x3, false },
-    { "_Z12rsMatrixLoadP12rs_matrix2x2PKS_", (void *)&SC_MatrixLoad_2x2_2x2, false },
-
-    { "_Z18rsMatrixLoadRotateP12rs_matrix4x4ffff", (void *)&SC_MatrixLoadRotate, false },
-    { "_Z17rsMatrixLoadScaleP12rs_matrix4x4fff", (void *)&SC_MatrixLoadScale, false },
-    { "_Z21rsMatrixLoadTranslateP12rs_matrix4x4fff", (void *)&SC_MatrixLoadTranslate, false },
-    { "_Z14rsMatrixRotateP12rs_matrix4x4ffff", (void *)&SC_MatrixRotate, false },
-    { "_Z13rsMatrixScaleP12rs_matrix4x4fff", (void *)&SC_MatrixScale, false },
-    { "_Z17rsMatrixTranslateP12rs_matrix4x4fff", (void *)&SC_MatrixTranslate, false },
-
-    { "_Z20rsMatrixLoadMultiplyP12rs_matrix4x4PKS_S2_", (void *)&SC_MatrixLoadMultiply_4x4_4x4_4x4, false },
-    { "_Z16rsMatrixMultiplyP12rs_matrix4x4PKS_", (void *)&SC_MatrixMultiply_4x4_4x4, false },
-    { "_Z20rsMatrixLoadMultiplyP12rs_matrix3x3PKS_S2_", (void *)&SC_MatrixLoadMultiply_3x3_3x3_3x3, false },
-    { "_Z16rsMatrixMultiplyP12rs_matrix3x3PKS_", (void *)&SC_MatrixMultiply_3x3_3x3, false },
-    { "_Z20rsMatrixLoadMultiplyP12rs_matrix2x2PKS_S2_", (void *)&SC_MatrixLoadMultiply_2x2_2x2_2x2, false },
-    { "_Z16rsMatrixMultiplyP12rs_matrix2x2PKS_", (void *)&SC_MatrixMultiply_2x2_2x2, false },
-
-    { "_Z17rsMatrixLoadOrthoP12rs_matrix4x4ffffff", (void *)&SC_MatrixLoadOrtho, false },
-    { "_Z19rsMatrixLoadFrustumP12rs_matrix4x4ffffff", (void *)&SC_MatrixLoadFrustum, false },
-    { "_Z23rsMatrixLoadPerspectiveP12rs_matrix4x4ffff", (void *)&SC_MatrixLoadPerspective, false },
-
-    { "_Z15rsMatrixInverseP12rs_matrix4x4", (void *)&SC_MatrixInverse_4x4, false },
-    { "_Z24rsMatrixInverseTransposeP12rs_matrix4x4", (void *)&SC_MatrixInverseTranspose_4x4, false },
-    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_4x4, false },
-    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_3x3, false },
-    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_2x2, false },
-
-    { "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach, false },
-    //{ "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach2, true },
-
-////////////////////////////////////////////////////////////////////
-
-    //{ "sinf_fast", (void *)&SC_sinf_fast, true },
-    //{ "cosf_fast", (void *)&SC_cosf_fast, true },
-
-    { NULL, NULL, false }
-};
-
-const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym) {
-    ScriptCState::SymbolTable_t *syms = gSyms;
-
-    while (syms->mPtr) {
-        if (!strcmp(syms->mName, sym)) {
-            return syms;
-        }
-        syms++;
-    }
-    return NULL;
-}
diff --git a/rsScriptC_LibCL.cpp b/rsScriptC_LibCL.cpp
deleted file mode 100644
index 57855db..0000000
--- a/rsScriptC_LibCL.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * 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.
- */
-
-#include "rsContext.h"
-#include "rsScriptC.h"
-
-// Implements rs_cl.rsh
-
-
-using namespace android;
-using namespace android::renderscript;
-
-
-static float SC_exp10(float v) {
-    return pow(10.f, v);
-}
-
-static float SC_fract(float v, int *iptr) {
-    int i = (int)floor(v);
-    iptr[0] = i;
-    return fmin(v - i, 0x1.fffffep-1f);
-}
-
-static float SC_log2(float v) {
-    return log10(v) / log10(2.f);
-}
-
-static float SC_mad(float v1, float v2, float v3) {
-    return v1 * v2 + v3;
-}
-
-static float SC_pown(float v, int p) {
-    return powf(v, (float)p);
-}
-
-static float SC_powr(float v, float p) {
-    return powf(v, p);
-}
-
-float SC_rootn(float v, int r) {
-    return pow(v, 1.f / r);
-}
-
-float SC_rsqrt(float v) {
-    return 1.f / sqrtf(v);
-}
-
-float SC_sincos(float v, float *cosptr) {
-    *cosptr = cosf(v);
-    return sinf(v);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Integer
-//////////////////////////////////////////////////////////////////////////////
-
-
-static uint32_t SC_abs_i32(int32_t v) {return abs(v);}
-static uint16_t SC_abs_i16(int16_t v) {return (uint16_t)abs(v);}
-static uint8_t SC_abs_i8(int8_t v) {return (uint8_t)abs(v);}
-
-static uint32_t SC_clz_u32(uint32_t v) {return __builtin_clz(v);}
-static uint16_t SC_clz_u16(uint16_t v) {return (uint16_t)__builtin_clz(v);}
-static uint8_t SC_clz_u8(uint8_t v) {return (uint8_t)__builtin_clz(v);}
-static int32_t SC_clz_i32(int32_t v) {return (int32_t)__builtin_clz((uint32_t)v);}
-static int16_t SC_clz_i16(int16_t v) {return (int16_t)__builtin_clz(v);}
-static int8_t SC_clz_i8(int8_t v) {return (int8_t)__builtin_clz(v);}
-
-static uint32_t SC_max_u32(uint32_t v, uint32_t v2) {return rsMax(v, v2);}
-static uint16_t SC_max_u16(uint16_t v, uint16_t v2) {return rsMax(v, v2);}
-static uint8_t SC_max_u8(uint8_t v, uint8_t v2) {return rsMax(v, v2);}
-static int32_t SC_max_i32(int32_t v, int32_t v2) {return rsMax(v, v2);}
-static int16_t SC_max_i16(int16_t v, int16_t v2) {return rsMax(v, v2);}
-static int8_t SC_max_i8(int8_t v, int8_t v2) {return rsMax(v, v2);}
-
-static uint32_t SC_min_u32(uint32_t v, uint32_t v2) {return rsMin(v, v2);}
-static uint16_t SC_min_u16(uint16_t v, uint16_t v2) {return rsMin(v, v2);}
-static uint8_t SC_min_u8(uint8_t v, uint8_t v2) {return rsMin(v, v2);}
-static int32_t SC_min_i32(int32_t v, int32_t v2) {return rsMin(v, v2);}
-static int16_t SC_min_i16(int16_t v, int16_t v2) {return rsMin(v, v2);}
-static int8_t SC_min_i8(int8_t v, int8_t v2) {return rsMin(v, v2);}
-
-//////////////////////////////////////////////////////////////////////////////
-// Float util
-//////////////////////////////////////////////////////////////////////////////
-
-static float SC_clamp_f32(float amount, float low, float high) {
-    return amount < low ? low : (amount > high ? high : amount);
-}
-
-static float SC_degrees(float radians) {
-    return radians * (180.f / M_PI);
-}
-
-static float SC_max_f32(float v, float v2) {
-    return rsMax(v, v2);
-}
-
-static float SC_min_f32(float v, float v2) {
-    return rsMin(v, v2);
-}
-
-static float SC_mix_f32(float start, float stop, float amount) {
-    //LOGE("lerpf %f  %f  %f", start, stop, amount);
-    return start + (stop - start) * amount;
-}
-
-static float SC_radians(float degrees) {
-    return degrees * (M_PI / 180.f);
-}
-
-static float SC_step_f32(float edge, float v) {
-    if (v < edge) return 0.f;
-    return 1.f;
-}
-
-static float SC_sign_f32(float value) {
-    if (value > 0) return 1.f;
-    if (value < 0) return -1.f;
-    return value;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Class implementation
-//////////////////////////////////////////////////////////////////////////////
-
-// llvm name mangling ref
-//  <builtin-type> ::= v  # void
-//                 ::= b  # bool
-//                 ::= c  # char
-//                 ::= a  # signed char
-//                 ::= h  # unsigned char
-//                 ::= s  # short
-//                 ::= t  # unsigned short
-//                 ::= i  # int
-//                 ::= j  # unsigned int
-//                 ::= l  # long
-//                 ::= m  # unsigned long
-//                 ::= x  # long long, __int64
-//                 ::= y  # unsigned long long, __int64
-//                 ::= f  # float
-//                 ::= d  # double
-
-static ScriptCState::SymbolTable_t gSyms[] = {
-    // OpenCL math
-    { "_Z4acosf", (void *)&acosf, true },
-    { "_Z5acoshf", (void *)&acoshf, true },
-    { "_Z4asinf", (void *)&asinf, true },
-    { "_Z5asinhf", (void *)&asinhf, true },
-    { "_Z4atanf", (void *)&atanf, true },
-    { "_Z5atan2ff", (void *)&atan2f, true },
-    { "_Z5atanhf", (void *)&atanhf, true },
-    { "_Z4cbrtf", (void *)&cbrtf, true },
-    { "_Z4ceilf", (void *)&ceilf, true },
-    { "_Z8copysignff", (void *)&copysignf, true },
-    { "_Z3cosf", (void *)&cosf, true },
-    { "_Z4coshf", (void *)&coshf, true },
-    { "_Z4erfcf", (void *)&erfcf, true },
-    { "_Z3erff", (void *)&erff, true },
-    { "_Z3expf", (void *)&expf, true },
-    { "_Z4exp2f", (void *)&exp2f, true },
-    { "_Z5exp10f", (void *)&SC_exp10, true },
-    { "_Z5expm1f", (void *)&expm1f, true },
-    { "_Z4fabsf", (void *)&fabsf, true },
-    { "_Z4fdimff", (void *)&fdimf, true },
-    { "_Z5floorf", (void *)&floorf, true },
-    { "_Z3fmafff", (void *)&fmaf, true },
-    { "_Z4fmaxff", (void *)&fmaxf, true },
-    { "_Z4fminff", (void *)&fminf, true },  // float fmin(float, float)
-    { "_Z4fmodff", (void *)&fmodf, true },
-    { "_Z5fractfPf", (void *)&SC_fract, true },
-    { "_Z5frexpfPi", (void *)&frexpf, true },
-    { "_Z5hypotff", (void *)&hypotf, true },
-    { "_Z5ilogbf", (void *)&ilogbf, true },
-    { "_Z5ldexpfi", (void *)&ldexpf, true },
-    { "_Z6lgammaf", (void *)&lgammaf, true },
-    { "_Z6lgammafPi", (void *)&lgammaf_r, true },
-    { "_Z3logf", (void *)&logf, true },
-    { "_Z4log2f", (void *)&SC_log2, true },
-    { "_Z5log10f", (void *)&log10f, true },
-    { "_Z5log1pf", (void *)&log1pf, true },
-    { "_Z4logbf", (void *)&logbf, true },
-    { "_Z3madfff", (void *)&SC_mad, true },
-    { "_Z4modffPf", (void *)&modff, true },
-    //{ "_Z3nanj", (void *)&SC_nan, true },
-    { "_Z9nextafterff", (void *)&nextafterf, true },
-    { "_Z3powff", (void *)&powf, true },
-    { "_Z9remainderff", (void *)&remainderf, true },
-    { "_Z6remquoffPi", (void *)&remquof, true },
-    { "_Z4rintf", (void *)&rintf, true },
-    { "_Z5rootnfi", (void *)&SC_rootn, true },
-    { "_Z5roundf", (void *)&roundf, true },
-    { "_Z5rsqrtf", (void *)&SC_rsqrt, true },
-    { "_Z3sinf", (void *)&sinf, true },
-    { "_Z6sincosfPf", (void *)&SC_sincos, true },
-    { "_Z4sinhf", (void *)&sinhf, true },
-    { "_Z4sqrtf", (void *)&sqrtf, true },
-    { "_Z3tanf", (void *)&tanf, true },
-    { "_Z4tanhf", (void *)&tanhf, true },
-    { "_Z6tgammaf", (void *)&tgammaf, true },
-    { "_Z5truncf", (void *)&truncf, true },
-
-    // OpenCL Int
-    { "_Z3absi", (void *)&SC_abs_i32, true },
-    { "_Z3abss", (void *)&SC_abs_i16, true },
-    { "_Z3absc", (void *)&SC_abs_i8, true },
-    { "_Z3clzj", (void *)&SC_clz_u32, true },
-    { "_Z3clzt", (void *)&SC_clz_u16, true },
-    { "_Z3clzh", (void *)&SC_clz_u8, true },
-    { "_Z3clzi", (void *)&SC_clz_i32, true },
-    { "_Z3clzs", (void *)&SC_clz_i16, true },
-    { "_Z3clzc", (void *)&SC_clz_i8, true },
-    { "_Z3maxjj", (void *)&SC_max_u32, true },
-    { "_Z3maxtt", (void *)&SC_max_u16, true },
-    { "_Z3maxhh", (void *)&SC_max_u8, true },
-    { "_Z3maxii", (void *)&SC_max_i32, true },
-    { "_Z3maxss", (void *)&SC_max_i16, true },
-    { "_Z3maxcc", (void *)&SC_max_i8, true },
-    { "_Z3minjj", (void *)&SC_min_u32, true },
-    { "_Z3mintt", (void *)&SC_min_u16, true },
-    { "_Z3minhh", (void *)&SC_min_u8, true },
-    { "_Z3minii", (void *)&SC_min_i32, true },
-    { "_Z3minss", (void *)&SC_min_i16, true },
-    { "_Z3mincc", (void *)&SC_min_i8, true },
-
-    // OpenCL 6.11.4
-    { "_Z5clampfff", (void *)&SC_clamp_f32, true },
-    { "_Z7degreesf", (void *)&SC_degrees, true },
-    { "_Z3maxff", (void *)&SC_max_f32, true },
-    { "_Z3minff", (void *)&SC_min_f32, true },
-    { "_Z3mixfff", (void *)&SC_mix_f32, true },
-    { "_Z7radiansf", (void *)&SC_radians, true },
-    { "_Z4stepff", (void *)&SC_step_f32, true },
-    //{ "smoothstep", (void *)&, true },
-    { "_Z4signf", (void *)&SC_sign_f32, true },
-
-    { NULL, NULL, false }
-};
-
-const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolCL(const char *sym) {
-    ScriptCState::SymbolTable_t *syms = gSyms;
-
-    while (syms->mPtr) {
-        if (!strcmp(syms->mName, sym)) {
-            return syms;
-        }
-        syms++;
-    }
-    return NULL;
-}
-
diff --git a/rsScriptC_LibGL.cpp b/rsScriptC_LibGL.cpp
index 48a0969..3259cb4 100644
--- a/rsScriptC_LibGL.cpp
+++ b/rsScriptC_LibGL.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -16,9 +16,14 @@
 
 #include "rsContext.h"
 #include "rsScriptC.h"
-#include "rsMatrix.h"
+#include "rsMatrix4x4.h"
+#include "rsMatrix3x3.h"
+#include "rsMatrix2x2.h"
 
 #include "utils/Timers.h"
+#include "driver/rsdVertexArray.h"
+#include "driver/rsdShaderCache.h"
+#include "driver/rsdCore.h"
 
 #define GL_GLEXT_PROTOTYPES
 
@@ -32,88 +37,90 @@
 using namespace android;
 using namespace android::renderscript;
 
-#define GET_TLS()  Context::ScriptTLSStruct * tls = \
-    (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
-    Context * rsc = tls->mContext; \
-    ScriptC * sc = (ScriptC *) tls->mScript
-
+namespace android {
+namespace renderscript {
 
 //////////////////////////////////////////////////////////////////////////////
 // Context
 //////////////////////////////////////////////////////////////////////////////
 
-static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va) {
-    CHECK_OBJ_OR_NULL(va);
-    CHECK_OBJ(vpf);
-    GET_TLS();
-    rsi_ProgramBindTexture(rsc,
-                           static_cast<ProgramFragment *>(vpf),
-                           slot,
-                           static_cast<Allocation *>(va));
+void rsrBindTexture(Context *rsc, Script *sc, ProgramFragment *pf, uint32_t slot, Allocation *a) {
+    CHECK_OBJ_OR_NULL(a);
+    CHECK_OBJ(pf);
+    pf->bindTexture(rsc, slot, a);
 }
 
-static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs) {
+void rsrBindSampler(Context *rsc, Script *sc, ProgramFragment *pf, uint32_t slot, Sampler *s) {
     CHECK_OBJ_OR_NULL(vs);
     CHECK_OBJ(vpf);
-    GET_TLS();
-    rsi_ProgramBindSampler(rsc,
-                           static_cast<ProgramFragment *>(vpf),
-                           slot,
-                           static_cast<Sampler *>(vs));
+    pf->bindSampler(rsc, slot, s);
 }
 
-static void SC_bindProgramStore(RsProgramStore pfs) {
-    CHECK_OBJ_OR_NULL(pfs);
-    GET_TLS();
-    rsi_ContextBindProgramStore(rsc, pfs);
+void rsrBindProgramStore(Context *rsc, Script *sc, ProgramStore *ps) {
+    CHECK_OBJ_OR_NULL(ps);
+    rsc->setProgramStore(ps);
 }
 
-static void SC_bindProgramFragment(RsProgramFragment pf) {
+void rsrBindProgramFragment(Context *rsc, Script *sc, ProgramFragment *pf) {
     CHECK_OBJ_OR_NULL(pf);
-    GET_TLS();
-    rsi_ContextBindProgramFragment(rsc, pf);
+    rsc->setProgramFragment(pf);
 }
 
-static void SC_bindProgramVertex(RsProgramVertex pv) {
+void rsrBindProgramVertex(Context *rsc, Script *sc, ProgramVertex *pv) {
     CHECK_OBJ_OR_NULL(pv);
-    GET_TLS();
-    rsi_ContextBindProgramVertex(rsc, pv);
+    rsc->setProgramVertex(pv);
 }
 
-static void SC_bindProgramRaster(RsProgramRaster pv) {
-    CHECK_OBJ_OR_NULL(pv);
-    GET_TLS();
-    rsi_ContextBindProgramRaster(rsc, pv);
+void rsrBindProgramRaster(Context *rsc, Script *sc, ProgramRaster *pr) {
+    CHECK_OBJ_OR_NULL(pr);
+    rsc->setProgramRaster(pr);
+}
+
+void rsrBindFrameBufferObjectColorTarget(Context *rsc, Script *sc, Allocation *a, uint32_t slot) {
+    CHECK_OBJ(va);
+    rsc->mFBOCache.bindColorTarget(rsc, a, slot);
+}
+
+void rsrBindFrameBufferObjectDepthTarget(Context *rsc, Script *sc, Allocation *a) {
+    CHECK_OBJ(va);
+    rsc->mFBOCache.bindDepthTarget(rsc, a);
+}
+
+void rsrClearFrameBufferObjectColorTarget(Context *rsc, Script *sc, uint32_t slot) {
+    rsc->mFBOCache.bindColorTarget(rsc, NULL, slot);
+}
+
+void rsrClearFrameBufferObjectDepthTarget(Context *rsc, Script *sc) {
+    rsc->mFBOCache.bindDepthTarget(rsc, NULL);
+}
+
+void rsrClearFrameBufferObjectTargets(Context *rsc, Script *sc) {
+    rsc->mFBOCache.resetAll(rsc);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 // VP
 //////////////////////////////////////////////////////////////////////////////
 
-static void SC_vpLoadProjectionMatrix(const rsc_Matrix *m) {
-    GET_TLS();
+void rsrVpLoadProjectionMatrix(Context *rsc, Script *sc, const rsc_Matrix *m) {
     rsc->getProgramVertex()->setProjectionMatrix(rsc, m);
 }
 
-static void SC_vpLoadModelMatrix(const rsc_Matrix *m) {
-    GET_TLS();
+void rsrVpLoadModelMatrix(Context *rsc, Script *sc, const rsc_Matrix *m) {
     rsc->getProgramVertex()->setModelviewMatrix(rsc, m);
 }
 
-static void SC_vpLoadTextureMatrix(const rsc_Matrix *m) {
-    GET_TLS();
+void rsrVpLoadTextureMatrix(Context *rsc, Script *sc, const rsc_Matrix *m) {
     rsc->getProgramVertex()->setTextureMatrix(rsc, m);
 }
 
-static void SC_pfConstantColor(RsProgramFragment vpf, float r, float g, float b, float a) {
-    GET_TLS();
-    CHECK_OBJ(vpf);
-    ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
+void rsrPfConstantColor(Context *rsc, Script *sc, ProgramFragment *pf,
+                        float r, float g, float b, float a) {
+    CHECK_OBJ(pf);
     pf->setConstantColor(rsc, r, g, b, a);
 }
 
-static void SC_vpGetProjectionMatrix(rsc_Matrix *m) {
-    GET_TLS();
+void rsrVpGetProjectionMatrix(Context *rsc, Script *sc, rsc_Matrix *m) {
     rsc->getProgramVertex()->getProjectionMatrix(rsc, m);
 }
 
@@ -121,19 +128,20 @@
 // Drawing
 //////////////////////////////////////////////////////////////////////////////
 
-static void SC_drawQuadTexCoords(float x1, float y1, float z1,
-                                 float u1, float v1,
-                                 float x2, float y2, float z2,
-                                 float u2, float v2,
-                                 float x3, float y3, float z3,
-                                 float u3, float v3,
-                                 float x4, float y4, float z4,
-                                 float u4, float v4) {
-    GET_TLS();
+void rsrDrawQuadTexCoords(Context *rsc, Script *sc,
+                          float x1, float y1, float z1, float u1, float v1,
+                          float x2, float y2, float z2, float u2, float v2,
+                          float x3, float y3, float z3, float u3, float v3,
+                          float x4, float y4, float z4, float u4, float v4) {
     if (!rsc->setupCheck()) {
         return;
     }
 
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+    if (!dc->gl.shaderCache->setup(rsc)) {
+        return;
+    }
+
     //LOGE("Quad");
     //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
     //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
@@ -143,28 +151,29 @@
     float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
     const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
 
-    VertexArray::Attrib attribs[2];
+    RsdVertexArray::Attrib attribs[2];
     attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
     attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
 
-    VertexArray va(attribs, 2);
-    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
+    RsdVertexArray va(attribs, 2);
+    va.setup(rsc);
 
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 }
 
-static void SC_drawQuad(float x1, float y1, float z1,
-                        float x2, float y2, float z2,
-                        float x3, float y3, float z3,
-                        float x4, float y4, float z4) {
-    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
-                         x2, y2, z2, 1, 1,
-                         x3, y3, z3, 1, 0,
-                         x4, y4, z4, 0, 0);
+void rsrDrawQuad(Context *rsc, Script *sc,
+                 float x1, float y1, float z1,
+                 float x2, float y2, float z2,
+                 float x3, float y3, float z3,
+                 float x4, float y4, float z4) {
+    rsrDrawQuadTexCoords(rsc, sc, x1, y1, z1, 0, 1,
+                                  x2, y2, z2, 1, 1,
+                                  x3, y3, z3, 1, 0,
+                                  x4, y4, z4, 0, 0);
 }
 
-static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h) {
-    GET_TLS();
+void rsrDrawSpriteScreenspace(Context *rsc, Script *sc,
+                              float x, float y, float z, float w, float h) {
     ObjectBaseRef<const ProgramVertex> tmp(rsc->getProgramVertex());
     rsc->setProgramVertex(rsc->getDefaultProgramVertex());
     //rsc->setupCheck();
@@ -173,87 +182,48 @@
 
     float sh = rsc->getHeight();
 
-    SC_drawQuad(x,   sh - y,     z,
+    rsrDrawQuad(rsc, sc,
+                x,   sh - y,     z,
                 x+w, sh - y,     z,
                 x+w, sh - (y+h), z,
                 x,   sh - (y+h), z);
     rsc->setProgramVertex((ProgramVertex *)tmp.get());
 }
-/*
-static void SC_drawSprite(float x, float y, float z, float w, float h)
-{
-    GET_TLS();
-    float vin[3] = {x, y, z};
-    float vout[4];
 
-    //LOGE("ds  in %f %f %f", x, y, z);
-    rsc->getVertex()->transformToScreen(rsc, vout, vin);
-    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
-    vout[0] /= vout[3];
-    vout[1] /= vout[3];
-    vout[2] /= vout[3];
-
-    vout[0] *= rsc->getWidth() / 2;
-    vout[1] *= rsc->getHeight() / 2;
-    vout[0] += rsc->getWidth() / 2;
-    vout[1] += rsc->getHeight() / 2;
-
-    vout[0] -= w/2;
-    vout[1] -= h/2;
-
-    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
-
-    // U, V, W, H
-    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
-    //rsc->setupCheck();
-}
-*/
-
-static void SC_drawRect(float x1, float y1,
-                        float x2, float y2, float z) {
+void rsrDrawRect(Context *rsc, Script *sc, float x1, float y1, float x2, float y2, float z) {
     //LOGE("SC_drawRect %f,%f  %f,%f  %f", x1, y1, x2, y2, z);
-    SC_drawQuad(x1, y2, z,
-                x2, y2, z,
-                x2, y1, z,
-                x1, y1, z);
+    rsrDrawQuad(rsc, sc, x1, y2, z, x2, y2, z, x2, y1, z, x1, y1, z);
 }
 
-static void SC_drawMesh(RsMesh vsm) {
-    CHECK_OBJ(vsm);
-    GET_TLS();
-    Mesh *sm = static_cast<Mesh *>(vsm);
+void rsrDrawMesh(Context *rsc, Script *sc, Mesh *sm) {
+    CHECK_OBJ(sm);
     if (!rsc->setupCheck()) {
         return;
     }
     sm->render(rsc);
 }
 
-static void SC_drawMeshPrimitive(RsMesh vsm, uint32_t primIndex) {
-    CHECK_OBJ(vsm);
-    GET_TLS();
-    Mesh *sm = static_cast<Mesh *>(vsm);
+void rsrDrawMeshPrimitive(Context *rsc, Script *sc, Mesh *sm, uint32_t primIndex) {
+    CHECK_OBJ(sm);
     if (!rsc->setupCheck()) {
         return;
     }
     sm->renderPrimitive(rsc, primIndex);
 }
 
-static void SC_drawMeshPrimitiveRange(RsMesh vsm, uint32_t primIndex, uint32_t start, uint32_t len) {
-    CHECK_OBJ(vsm);
-    GET_TLS();
-    Mesh *sm = static_cast<Mesh *>(vsm);
+void rsrDrawMeshPrimitiveRange(Context *rsc, Script *sc, Mesh *sm, uint32_t primIndex,
+                               uint32_t start, uint32_t len) {
+    CHECK_OBJ(sm);
     if (!rsc->setupCheck()) {
         return;
     }
     sm->renderPrimitiveRange(rsc, primIndex, start, len);
 }
 
-static void SC_meshComputeBoundingBox(RsMesh vsm,
-                                      float *minX, float *minY, float *minZ,
-                                      float *maxX, float *maxY, float *maxZ) {
-    CHECK_OBJ(vsm);
-    GET_TLS();
-    Mesh *sm = static_cast<Mesh *>(vsm);
+void rsrMeshComputeBoundingBox(Context *rsc, Script *sc, Mesh *sm,
+                               float *minX, float *minY, float *minZ,
+                               float *maxX, float *maxY, float *maxZ) {
+    CHECK_OBJ(sm);
     sm->computeBBox();
     *minX = sm->mBBoxMin[0];
     *minY = sm->mBBoxMin[1];
@@ -269,68 +239,53 @@
 //////////////////////////////////////////////////////////////////////////////
 
 
-static void SC_color(float r, float g, float b, float a) {
-    GET_TLS();
-    ProgramFragment *pf = (ProgramFragment *)rsc->getProgramFragment();
+void rsrColor(Context *rsc, Script *sc, float r, float g, float b, float a) {
+    ProgramFragment *pf = rsc->getProgramFragment();
     pf->setConstantColor(rsc, r, g, b, a);
 }
 
-static void SC_allocationSyncAll(RsAllocation va) {
-    CHECK_OBJ(va);
-    GET_TLS();
-    static_cast<Allocation *>(va)->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
+void rsrFinish(Context *rsc, Script *sc) {
+    glFinish();
 }
 
-static void SC_allocationSyncAll2(RsAllocation va, RsAllocationUsageType source) {
-    CHECK_OBJ(va);
-    GET_TLS();
-    static_cast<Allocation *>(va)->syncAll(rsc, source);
-}
 
-static void SC_ClearColor(float r, float g, float b, float a) {
-    GET_TLS();
+void rsrClearColor(Context *rsc, Script *sc, float r, float g, float b, float a) {
+    rsc->mFBOCache.setup(rsc);
     rsc->setupProgramStore();
 
     glClearColor(r, g, b, a);
     glClear(GL_COLOR_BUFFER_BIT);
 }
 
-static void SC_ClearDepth(float v) {
-    GET_TLS();
+void rsrClearDepth(Context *rsc, Script *sc, float v) {
+    rsc->mFBOCache.setup(rsc);
     rsc->setupProgramStore();
 
     glClearDepthf(v);
     glClear(GL_DEPTH_BUFFER_BIT);
 }
 
-static uint32_t SC_getWidth() {
-    GET_TLS();
+uint32_t rsrGetWidth(Context *rsc, Script *sc) {
     return rsc->getWidth();
 }
 
-static uint32_t SC_getHeight() {
-    GET_TLS();
+uint32_t rsrGetHeight(Context *rsc, Script *sc) {
     return rsc->getHeight();
 }
 
-static void SC_DrawTextAlloc(RsAllocation va, int x, int y) {
-    CHECK_OBJ(va);
-    GET_TLS();
-    Allocation *alloc = static_cast<Allocation *>(va);
-    const char *text = (const char *)alloc->getPtr();
-    size_t allocSize = alloc->getType()->getSizeBytes();
+void rsrDrawTextAlloc(Context *rsc, Script *sc, Allocation *a, int x, int y) {
+    const char *text = (const char *)a->getPtr();
+    size_t allocSize = a->getType()->getSizeBytes();
     rsc->mStateFont.renderText(text, allocSize, x, y);
 }
 
-static void SC_DrawText(const char *text, int x, int y) {
-    GET_TLS();
+void rsrDrawText(Context *rsc, Script *sc, const char *text, int x, int y) {
     size_t textLen = strlen(text);
     rsc->mStateFont.renderText(text, textLen, x, y);
 }
 
-static void SC_setMetrics(Font::Rect *metrics,
-                          int32_t *left, int32_t *right,
-                          int32_t *top, int32_t *bottom) {
+static void SetMetrics(Font::Rect *metrics,
+                       int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
     if (left) {
         *left = metrics->left;
     }
@@ -345,118 +300,32 @@
     }
 }
 
-static void SC_MeasureTextAlloc(RsAllocation va,
-                                int32_t *left, int32_t *right,
-                                int32_t *top, int32_t *bottom) {
-    CHECK_OBJ(va);
-    GET_TLS();
-    Allocation *alloc = static_cast<Allocation *>(va);
-    const char *text = (const char *)alloc->getPtr();
-    size_t textLen = alloc->getType()->getSizeBytes();
+void rsrMeasureTextAlloc(Context *rsc, Script *sc, Allocation *a,
+                         int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
+    CHECK_OBJ(a);
+    const char *text = (const char *)a->getPtr();
+    size_t textLen = a->getType()->getSizeBytes();
     Font::Rect metrics;
     rsc->mStateFont.measureText(text, textLen, &metrics);
-    SC_setMetrics(&metrics, left, right, top, bottom);
+    SetMetrics(&metrics, left, right, top, bottom);
 }
 
-static void SC_MeasureText(const char *text,
-                           int32_t *left, int32_t *right,
-                           int32_t *top, int32_t *bottom) {
-    GET_TLS();
+void rsrMeasureText(Context *rsc, Script *sc, const char *text,
+                    int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
     size_t textLen = strlen(text);
     Font::Rect metrics;
     rsc->mStateFont.measureText(text, textLen, &metrics);
-    SC_setMetrics(&metrics, left, right, top, bottom);
+    SetMetrics(&metrics, left, right, top, bottom);
 }
 
-static void SC_BindFont(RsFont font) {
+void rsrBindFont(Context *rsc, Script *sc, Font *font) {
     CHECK_OBJ(font);
-    GET_TLS();
     rsi_ContextBindFont(rsc, font);
 }
 
-static void SC_FontColor(float r, float g, float b, float a) {
-    GET_TLS();
+void rsrFontColor(Context *rsc, Script *sc, float r, float g, float b, float a) {
     rsc->mStateFont.setFontColor(r, g, b, a);
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// Class implementation
-//////////////////////////////////////////////////////////////////////////////
-
-// llvm name mangling ref
-//  <builtin-type> ::= v  # void
-//                 ::= b  # bool
-//                 ::= c  # char
-//                 ::= a  # signed char
-//                 ::= h  # unsigned char
-//                 ::= s  # short
-//                 ::= t  # unsigned short
-//                 ::= i  # int
-//                 ::= j  # unsigned int
-//                 ::= l  # long
-//                 ::= m  # unsigned long
-//                 ::= x  # long long, __int64
-//                 ::= y  # unsigned long long, __int64
-//                 ::= f  # float
-//                 ::= d  # double
-
-static ScriptCState::SymbolTable_t gSyms[] = {
-    { "_Z22rsgBindProgramFragment19rs_program_fragment", (void *)&SC_bindProgramFragment, false },
-    { "_Z19rsgBindProgramStore16rs_program_store", (void *)&SC_bindProgramStore, false },
-    { "_Z20rsgBindProgramVertex17rs_program_vertex", (void *)&SC_bindProgramVertex, false },
-    { "_Z20rsgBindProgramRaster17rs_program_raster", (void *)&SC_bindProgramRaster, false },
-    { "_Z14rsgBindSampler19rs_program_fragmentj10rs_sampler", (void *)&SC_bindSampler, false },
-    { "_Z14rsgBindTexture19rs_program_fragmentj13rs_allocation", (void *)&SC_bindTexture, false },
-
-    { "_Z36rsgProgramVertexLoadProjectionMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadProjectionMatrix, false },
-    { "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadModelMatrix, false },
-    { "_Z33rsgProgramVertexLoadTextureMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadTextureMatrix, false },
-
-    { "_Z35rsgProgramVertexGetProjectionMatrixP12rs_matrix4x4", (void *)&SC_vpGetProjectionMatrix, false },
-
-    { "_Z31rsgProgramFragmentConstantColor19rs_program_fragmentffff", (void *)&SC_pfConstantColor, false },
-
-    { "_Z11rsgGetWidthv", (void *)&SC_getWidth, false },
-    { "_Z12rsgGetHeightv", (void *)&SC_getHeight, false },
-
-    { "_Z20rsgAllocationSyncAll13rs_allocation", (void *)&SC_allocationSyncAll, false },
-
-    { "_Z11rsgDrawRectfffff", (void *)&SC_drawRect, false },
-    { "_Z11rsgDrawQuadffffffffffff", (void *)&SC_drawQuad, false },
-    { "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff", (void *)&SC_drawQuadTexCoords, false },
-    { "_Z24rsgDrawSpriteScreenspacefffff", (void *)&SC_drawSpriteScreenspace, false },
-
-    { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_drawMesh, false },
-    { "_Z11rsgDrawMesh7rs_meshj", (void *)&SC_drawMeshPrimitive, false },
-    { "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_drawMeshPrimitiveRange, false },
-    { "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_meshComputeBoundingBox, false },
-
-    { "_Z13rsgClearColorffff", (void *)&SC_ClearColor, false },
-    { "_Z13rsgClearDepthf", (void *)&SC_ClearDepth, false },
-
-    { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText, false },
-    { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc, false },
-    { "_Z14rsgMeasureTextPKcPiS1_S1_S1_", (void *)&SC_MeasureText, false },
-    { "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_", (void *)&SC_MeasureTextAlloc, false },
-
-    { "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont, false },
-    { "_Z12rsgFontColorffff", (void *)&SC_FontColor, false },
-
-    // misc
-    { "_Z5colorffff", (void *)&SC_color, false },
-
-    { NULL, NULL, false }
-};
-
-const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym) {
-    ScriptCState::SymbolTable_t *syms = gSyms;
-
-    while (syms->mPtr) {
-        if (!strcmp(syms->mName, sym)) {
-            return syms;
-        }
-        syms++;
-    }
-    return NULL;
 }
-
+}
diff --git a/rsStream.cpp b/rsStream.cpp
index 49ed567..b9df0cc 100644
--- a/rsStream.cpp
+++ b/rsStream.cpp
@@ -15,12 +15,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#else
-#include "rsContextHostStub.h"
-#endif
-
 #include "rsStream.h"
 
 using namespace android;
diff --git a/rsThreadIO.cpp b/rsThreadIO.cpp
index 6cf07de..4429556 100644
--- a/rsThreadIO.cpp
+++ b/rsThreadIO.cpp
@@ -23,16 +23,96 @@
 
 ThreadIO::ThreadIO() {
     mToCore.init(16 * 1024);
-    mToClient.init(1024);
 }
 
 ThreadIO::~ThreadIO() {
 }
 
-void ThreadIO::shutdown() {
-    mToCore.shutdown();
+void ThreadIO::init(bool useSocket) {
+    mUsingSocket = useSocket;
+
+    if (mUsingSocket) {
+        mToClientSocket.init();
+        mToCoreSocket.init();
+    } else {
+        mToClient.init(1024);
+    }
 }
 
+void ThreadIO::shutdown() {
+    //LOGE("shutdown 1");
+    mToCore.shutdown();
+    //LOGE("shutdown 2");
+}
+
+void ThreadIO::coreFlush() {
+    //LOGE("coreFlush 1");
+    if (mUsingSocket) {
+    } else {
+        mToCore.flush();
+    }
+    //LOGE("coreFlush 2");
+}
+
+void * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) {
+    //LOGE("coreHeader %i %i", cmdID, dataLen);
+    if (mUsingSocket) {
+        CoreCmdHeader hdr;
+        hdr.bytes = dataLen;
+        hdr.cmdID = cmdID;
+        mToCoreSocket.writeAsync(&hdr, sizeof(hdr));
+    } else {
+        mCoreCommandSize = dataLen;
+        mCoreCommandID = cmdID;
+        mCoreDataPtr = (uint8_t *)mToCore.reserve(dataLen);
+        mCoreDataBasePtr = mCoreDataPtr;
+    }
+    //LOGE("coreHeader ret %p", mCoreDataPtr);
+    return mCoreDataPtr;
+}
+
+void ThreadIO::coreData(const void *data, size_t dataLen) {
+    //LOGE("coreData %p %i", data, dataLen);
+    mToCoreSocket.writeAsync(data, dataLen);
+    //LOGE("coreData ret %p", mCoreDataPtr);
+}
+
+void ThreadIO::coreCommit() {
+    //LOGE("coreCommit %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize);
+    if (mUsingSocket) {
+    } else {
+        rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize);
+        mToCore.commit(mCoreCommandID, mCoreCommandSize);
+    }
+    //LOGE("coreCommit ret");
+}
+
+void ThreadIO::coreCommitSync() {
+    //LOGE("coreCommitSync %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize);
+    if (mUsingSocket) {
+    } else {
+        rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize);
+        mToCore.commitSync(mCoreCommandID, mCoreCommandSize);
+    }
+    //LOGE("coreCommitSync ret");
+}
+
+void ThreadIO::clientShutdown() {
+    //LOGE("coreShutdown 1");
+    mToClient.shutdown();
+    //LOGE("coreShutdown 2");
+}
+
+void ThreadIO::coreSetReturn(const void *data, size_t dataLen) {
+    rsAssert(dataLen <= sizeof(mToCoreRet));
+    memcpy(&mToCoreRet, data, dataLen);
+}
+
+void ThreadIO::coreGetReturn(void *data, size_t dataLen) {
+    memcpy(data, &mToCoreRet, dataLen);
+}
+
+
 bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) {
     bool ret = false;
     while (!mToCore.isEmpty() || waitForCommand) {
@@ -58,10 +138,88 @@
             LOGE("playCoreCommands error con %p, cmd %i", con, cmdID);
             mToCore.printDebugData();
         }
-        gPlaybackFuncs[cmdID](con, data);
+        gPlaybackFuncs[cmdID](con, data, cmdSize << 2);
         mToCore.next();
     }
     return ret;
 }
 
+RsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) {
+    if (mUsingSocket) {
+        mToClientSocket.read(&mLastClientHeader, sizeof(mLastClientHeader));
+    } else {
+        size_t bytesData = 0;
+        const uint32_t *d = (const uint32_t *)mToClient.get(&mLastClientHeader.cmdID, &bytesData);
+        if (bytesData >= sizeof(uint32_t)) {
+            mLastClientHeader.userID = d[0];
+            mLastClientHeader.bytes = bytesData - sizeof(uint32_t);
+        } else {
+            mLastClientHeader.userID = 0;
+            mLastClientHeader.bytes = 0;
+        }
+    }
+    receiveLen[0] = mLastClientHeader.bytes;
+    usrID[0] = mLastClientHeader.userID;
+    return (RsMessageToClientType)mLastClientHeader.cmdID;
+}
+
+RsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen,
+                                uint32_t *usrID, size_t bufferLen) {
+    receiveLen[0] = mLastClientHeader.bytes;
+    usrID[0] = mLastClientHeader.userID;
+    if (bufferLen < mLastClientHeader.bytes) {
+        return RS_MESSAGE_TO_CLIENT_RESIZE;
+    }
+    if (mUsingSocket) {
+        if (receiveLen[0]) {
+            mToClientSocket.read(data, receiveLen[0]);
+        }
+        return (RsMessageToClientType)mLastClientHeader.cmdID;
+    } else {
+        uint32_t bytesData = 0;
+        uint32_t commandID = 0;
+        const uint32_t *d = (const uint32_t *)mToClient.get(&commandID, &bytesData);
+        //LOGE("getMessageToClient 3    %i  %i", commandID, bytesData);
+        //LOGE("getMessageToClient  %i %i", commandID, *subID);
+        if (bufferLen >= receiveLen[0]) {
+            memcpy(data, d+1, receiveLen[0]);
+            mToClient.next();
+            return (RsMessageToClientType)commandID;
+        }
+    }
+    return RS_MESSAGE_TO_CLIENT_RESIZE;
+}
+
+bool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data,
+                            size_t dataLen, bool waitForSpace) {
+    ClientCmdHeader hdr;
+    hdr.bytes = dataLen;
+    hdr.cmdID = cmdID;
+    hdr.userID = usrID;
+    if (mUsingSocket) {
+        mToClientSocket.writeAsync(&hdr, sizeof(hdr));
+        if (dataLen) {
+            mToClientSocket.writeAsync(data, dataLen);
+        }
+        return true;
+    } else {
+        if (!waitForSpace) {
+            if (!mToClient.makeSpaceNonBlocking(dataLen + sizeof(hdr))) {
+                // Not enough room, and not waiting.
+                return false;
+            }
+        }
+
+        //LOGE("sendMessageToClient 2");
+        uint32_t *p = (uint32_t *)mToClient.reserve(dataLen + sizeof(usrID));
+        p[0] = usrID;
+        if (dataLen > 0) {
+            memcpy(p+1, data, dataLen);
+        }
+        mToClient.commit(cmdID, dataLen + sizeof(usrID));
+        //LOGE("sendMessageToClient 3");
+        return true;
+    }
+    return false;
+}
 
diff --git a/rsThreadIO.h b/rsThreadIO.h
index f9d0de7..cad7318 100644
--- a/rsThreadIO.h
+++ b/rsThreadIO.h
@@ -19,6 +19,7 @@
 
 #include "rsUtils.h"
 #include "rsLocklessFifo.h"
+#include "rsFifoSocket.h"
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -31,17 +32,58 @@
     ThreadIO();
     ~ThreadIO();
 
+    void init(bool useSocket = false);
     void shutdown();
 
     // Plays back commands from the client.
     // Returns true if any commands were processed.
     bool playCoreCommands(Context *con, bool waitForCommand);
 
+    //LocklessCommandFifo mToCore;
 
-    LocklessCommandFifo mToCore;
+
+
+    void coreFlush();
+    void * coreHeader(uint32_t, size_t dataLen);
+    void coreData(const void *data, size_t dataLen);
+    void coreCommit();
+    void coreCommitSync();
+    void coreSetReturn(const void *data, size_t dataLen);
+    void coreGetReturn(void *data, size_t dataLen);
+
+
+    RsMessageToClientType getClientHeader(size_t *receiveLen, uint32_t *usrID);
+    RsMessageToClientType getClientPayload(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen);
+    bool sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data, size_t dataLen, bool waitForSpace);
+    void clientShutdown();
+
+
+protected:
+    typedef struct CoreCmdHeaderRec {
+        uint32_t cmdID;
+        uint32_t bytes;
+    } CoreCmdHeader;
+    typedef struct ClientCmdHeaderRec {
+        uint32_t cmdID;
+        uint32_t bytes;
+        uint32_t userID;
+    } ClientCmdHeader;
+    ClientCmdHeader mLastClientHeader;
+
+    size_t mCoreCommandSize;
+    uint32_t mCoreCommandID;
+    uint8_t * mCoreDataPtr;
+    uint8_t * mCoreDataBasePtr;
+
+    bool mUsingSocket;
     LocklessCommandFifo mToClient;
+    LocklessCommandFifo mToCore;
+
+    FifoSocket mToClientSocket;
+    FifoSocket mToCoreSocket;
 
     intptr_t mToCoreRet;
+
 };
 
 
diff --git a/rsType.cpp b/rsType.cpp
index d7b5f12..10e3182 100644
--- a/rsType.cpp
+++ b/rsType.cpp
@@ -14,13 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
 #include "rsContext.h"
-#include <GLES/gl.h>
-#else
-#include "rsContextHostStub.h"
-#include <OpenGL/gl.h>
-#endif
 
 using namespace android;
 using namespace android::renderscript;
@@ -146,7 +140,7 @@
 void Type::dumpLOGV(const char *prefix) const {
     char buf[1024];
     ObjectBase::dumpLOGV(prefix);
-    LOGV("%s   Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
+    LOGV("%s   Type: x=%zu y=%zu z=%zu mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
     snprintf(buf, sizeof(buf), "%s element: ", prefix);
     mElement->dumpLOGV(buf);
 }
@@ -280,17 +274,16 @@
 namespace android {
 namespace renderscript {
 
-}
-}
-
-RsType rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimX,
+RsType rsi_TypeCreate(Context *rsc, RsElement _e, uint32_t dimX,
                      uint32_t dimY, uint32_t dimZ, bool mips, bool faces) {
-    Context *rsc = static_cast<Context *>(con);
     Element *e = static_cast<Element *>(_e);
 
     return Type::getType(rsc, e, dimX, dimY, dimZ, mips, faces);
 }
 
+}
+}
+
 void rsaTypeGetNativeData(RsContext con, RsType type, uint32_t *typeData, uint32_t typeDataSize) {
     rsAssert(typeDataSize == 6);
     // Pack the data in the follofing way mDimX; mDimY; mDimZ;
diff --git a/rsType.h b/rsType.h
index 90ae039..086db33 100644
--- a/rsType.h
+++ b/rsType.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -18,7 +18,6 @@
 #define ANDROID_STRUCTURED_TYPE_H
 
 #include "rsElement.h"
-#include "rsVertexArray.h"
 
 // ---------------------------------------------------------------------------
 namespace android {
diff --git a/rsUtils.h b/rsUtils.h
index 0699b57..3a6c85a 100644
--- a/rsUtils.h
+++ b/rsUtils.h
@@ -32,10 +32,6 @@
 #include <time.h>
 #include <cutils/atomic.h>
 
-#ifndef ANDROID_RS_BUILD_FOR_HOST
-#include <EGL/egl.h>
-#endif
-
 #include <math.h>
 
 #include "RenderScript.h"
diff --git a/rs_hal.h b/rs_hal.h
new file mode 100644
index 0000000..9d8c906
--- /dev/null
+++ b/rs_hal.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RS_HAL_H
+#define RS_HAL_H
+
+#include <RenderScriptDefines.h>
+#include <ui/egl/android_natives.h>
+
+namespace android {
+namespace renderscript {
+
+class Context;
+class ObjectBase;
+class Element;
+class Type;
+class Allocation;
+class Script;
+class ScriptC;
+class Program;
+class ProgramStore;
+class ProgramRaster;
+class ProgramVertex;
+class ProgramFragment;
+class Mesh;
+class Sampler;
+class FBOCache;
+
+typedef void *(*RsHalSymbolLookupFunc)(void *usrptr, char const *symbolName);
+
+/**
+ * Script management functions
+ */
+typedef struct {
+    bool (*initGraphics)(const Context *);
+    void (*shutdownGraphics)(const Context *);
+    bool (*setSurface)(const Context *, uint32_t w, uint32_t h, RsNativeWindow);
+    void (*swap)(const Context *);
+
+    void (*shutdownDriver)(Context *);
+    void (*getVersion)(unsigned int *major, unsigned int *minor);
+    void (*setPriority)(const Context *, int32_t priority);
+
+
+
+    struct {
+        bool (*init)(const Context *rsc, ScriptC *s,
+                     char const *resName,
+                     char const *cacheDir,
+                     uint8_t const *bitcode,
+                     size_t bitcodeSize,
+                     uint32_t flags);
+
+        void (*invokeFunction)(const Context *rsc, Script *s,
+                               uint32_t slot,
+                               const void *params,
+                               size_t paramLength);
+        int (*invokeRoot)(const Context *rsc, Script *s);
+        void (*invokeForEach)(const Context *rsc,
+                              Script *s,
+                              const Allocation * ain,
+                              Allocation * aout,
+                              const void * usr,
+                              uint32_t usrLen,
+                              const RsScriptCall *sc);
+        void (*invokeInit)(const Context *rsc, Script *s);
+
+        void (*setGlobalVar)(const Context *rsc, const Script *s,
+                             uint32_t slot,
+                             void *data,
+                             size_t dataLength);
+        void (*setGlobalBind)(const Context *rsc, const Script *s,
+                              uint32_t slot,
+                              void *data);
+        void (*setGlobalObj)(const Context *rsc, const Script *s,
+                             uint32_t slot,
+                             ObjectBase *data);
+
+        void (*destroy)(const Context *rsc, Script *s);
+    } script;
+
+    struct {
+        bool (*init)(const Context *rsc, const ProgramStore *ps);
+        void (*setActive)(const Context *rsc, const ProgramStore *ps);
+        void (*destroy)(const Context *rsc, const ProgramStore *ps);
+    } store;
+
+    struct {
+        bool (*init)(const Context *rsc, const ProgramRaster *ps);
+        void (*setActive)(const Context *rsc, const ProgramRaster *ps);
+        void (*destroy)(const Context *rsc, const ProgramRaster *ps);
+    } raster;
+
+    struct {
+        bool (*init)(const Context *rsc, const ProgramVertex *pv,
+                     const char* shader, uint32_t shaderLen);
+        void (*setActive)(const Context *rsc, const ProgramVertex *pv);
+        void (*destroy)(const Context *rsc, const ProgramVertex *pv);
+    } vertex;
+
+    struct {
+        bool (*init)(const Context *rsc, const ProgramFragment *pf,
+                     const char* shader, uint32_t shaderLen);
+        void (*setActive)(const Context *rsc, const ProgramFragment *pf);
+        void (*destroy)(const Context *rsc, const ProgramFragment *pf);
+    } fragment;
+
+    struct {
+        bool (*init)(const Context *rsc, const Mesh *m);
+        void (*draw)(const Context *rsc, const Mesh *m, uint32_t primIndex, uint32_t start, uint32_t len);
+        void (*destroy)(const Context *rsc, const Mesh *m);
+    } mesh;
+
+    struct {
+        bool (*init)(const Context *rsc, const Sampler *m);
+        void (*destroy)(const Context *rsc, const Sampler *m);
+    } sampler;
+
+    struct {
+        bool (*init)(const Context *rsc, const FBOCache *fb);
+        void (*setActive)(const Context *rsc, const FBOCache *fb);
+        void (*destroy)(const Context *rsc, const FBOCache *fb);
+    } framebuffer;
+
+} RsdHalFunctions;
+
+
+}
+}
+
+
+bool rsdHalInit(android::renderscript::Context *, uint32_t version_major, uint32_t version_minor);
+
+#endif
+
diff --git a/rsg_generator.c b/rsg_generator.c
index 4ac5b7f..b3f6c55 100644
--- a/rsg_generator.c
+++ b/rsg_generator.c
@@ -4,7 +4,7 @@
 
 void printFileHeader(FILE *f) {
     fprintf(f, "/*\n");
-    fprintf(f, " * Copyright (C) 2010 The Android Open Source Project\n");
+    fprintf(f, " * Copyright (C) 2011 The Android Open Source Project\n");
     fprintf(f, " *\n");
     fprintf(f, " * Licensed under the Apache License, Version 2.0 (the \"License\");\n");
     fprintf(f, " * you may not use this file except in compliance with the License.\n");
@@ -53,6 +53,10 @@
             fprintf(f, "*");
         }
     }
+}
+
+void printVarTypeAndName(FILE *f, const VarType *vt) {
+    printVarType(f, vt);
 
     if (vt->name[0]) {
         fprintf(f, " %s", vt->name);
@@ -65,7 +69,7 @@
         if (ct || assumePrevious) {
             fprintf(f, ", ");
         }
-        printVarType(f, &api->params[ct]);
+        printVarTypeAndName(f, &api->params[ct]);
     }
 }
 
@@ -86,41 +90,96 @@
 
         for (ct2=0; ct2 < api->paramCount; ct2++) {
             fprintf(f, "    ");
-            printVarType(f, &api->params[ct2]);
+            printVarTypeAndName(f, &api->params[ct2]);
             fprintf(f, ";\n");
         }
         fprintf(f, "};\n\n");
     }
 }
 
-void printFuncDecl(FILE *f, const ApiEntry *api, const char *prefix, int addContext) {
-    printVarType(f, &api->ret);
-    fprintf(f, " %s%s (", prefix, api->name);
-    if (addContext) {
-        fprintf(f, "Context *");
+void printFuncDecl(FILE *f, const ApiEntry *api, const char *prefix, int addContext, int isFnPtr) {
+    printVarTypeAndName(f, &api->ret);
+    if (isFnPtr) {
+        char t[1024];
+        strcpy(t, api->name);
+        if (strlen(prefix) == 0) {
+            if (t[0] > 'A' && t[0] < 'Z') {
+                t[0] -= 'A' - 'a';
+            }
+        }
+        fprintf(f, " (* %s%s) (", prefix, api->name);
     } else {
-        fprintf(f, "RsContext rsc");
+        fprintf(f, " %s%s (", prefix, api->name);
     }
-    printArgList(f, api, 1);
+    if (!api->nocontext) {
+        if (addContext) {
+            fprintf(f, "Context *");
+        } else {
+            fprintf(f, "RsContext rsc");
+        }
+    }
+    printArgList(f, api, !api->nocontext);
     fprintf(f, ")");
 }
 
 void printFuncDecls(FILE *f, const char *prefix, int addContext) {
     int ct;
     for (ct=0; ct < apiCount; ct++) {
-        printFuncDecl(f, &apis[ct], prefix, addContext);
+        printFuncDecl(f, &apis[ct], prefix, addContext, 0);
         fprintf(f, ";\n");
     }
     fprintf(f, "\n\n");
 }
 
+void printFuncPointers(FILE *f, int addContext) {
+    fprintf(f, "\n");
+    fprintf(f, "typedef struct RsApiEntrypoints {\n");
+    int ct;
+    for (ct=0; ct < apiCount; ct++) {
+        fprintf(f, "    ");
+        printFuncDecl(f, &apis[ct], "", addContext, 1);
+        fprintf(f, ";\n");
+    }
+    fprintf(f, "} RsApiEntrypoints_t;\n\n");
+}
+
 void printPlaybackFuncs(FILE *f, const char *prefix) {
     int ct;
     for (ct=0; ct < apiCount; ct++) {
+        if (apis[ct].direct) {
+            continue;
+        }
+
         fprintf(f, "void %s%s (Context *, const void *);\n", prefix, apis[ct].name);
     }
 }
 
+static int hasInlineDataPointers(const ApiEntry * api) {
+    int ret = 0;
+    int ct;
+    if (api->sync || api->ret.typeName[0]) {
+        return 0;
+    }
+    for (ct=0; ct < api->paramCount; ct++) {
+        const VarType *vt = &api->params[ct];
+
+        if (!vt->isConst && vt->ptrLevel) {
+            // Non-const pointers cannot be inlined.
+            return 0;
+        }
+        if (vt->ptrLevel > 1) {
+            // not handled yet.
+            return 0;
+        }
+
+        if (vt->isConst && vt->ptrLevel) {
+            // Non-const pointers cannot be inlined.
+            ret = 1;
+        }
+    }
+    return ret;
+}
+
 void printApiCpp(FILE *f) {
     int ct;
     int ct2;
@@ -130,54 +189,233 @@
     fprintf(f, "#include \"rsThreadIO.h\"\n");
     //fprintf(f, "#include \"rsgApiStructs.h\"\n");
     fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
+    fprintf(f, "#include \"rsFifo.h\"\n");
     fprintf(f, "\n");
     fprintf(f, "using namespace android;\n");
     fprintf(f, "using namespace android::renderscript;\n");
-    fprintf(f, "#include \"rsHandcode.h\"\n");
     fprintf(f, "\n");
 
+    printFuncPointers(f, 0);
+
+    // Generate RS funcs for local fifo
     for (ct=0; ct < apiCount; ct++) {
         int needFlush = 0;
         const ApiEntry * api = &apis[ct];
 
-        printFuncDecl(f, api, "rs", 0);
+        fprintf(f, "static ");
+        printFuncDecl(f, api, "LF_", 0, 0);
         fprintf(f, "\n{\n");
-        if (api->handcodeApi) {
-            fprintf(f, "    rsHCAPI_%s(rsc", api->name);
+        if (api->direct) {
+            fprintf(f, "    ");
+            if (api->ret.typeName[0]) {
+                fprintf(f, "return ");
+            }
+            fprintf(f, "rsi_%s(", api->name);
+            if (!api->nocontext) {
+                fprintf(f, "(Context *)rsc");
+            }
             for (ct2=0; ct2 < api->paramCount; ct2++) {
                 const VarType *vt = &api->params[ct2];
-                fprintf(f, ", %s", vt->name);
+                if (ct2 > 0 || !api->nocontext) {
+                    fprintf(f, ", ");
+                }
+                fprintf(f, "%s", vt->name);
             }
             fprintf(f, ");\n");
         } else {
             fprintf(f, "    ThreadIO *io = &((Context *)rsc)->mIO;\n");
+            fprintf(f, "    const uint32_t size = sizeof(RS_CMD_%s);\n", api->name);
+            if (hasInlineDataPointers(api)) {
+                fprintf(f, "    uint32_t dataSize = 0;\n");
+                for (ct2=0; ct2 < api->paramCount; ct2++) {
+                    const VarType *vt = &api->params[ct2];
+                    if (vt->isConst && vt->ptrLevel) {
+                        fprintf(f, "    dataSize += %s_length;\n", vt->name);
+                    }
+                }
+            }
+
             //fprintf(f, "    LOGE(\"add command %s\\n\");\n", api->name);
-            fprintf(f, "    RS_CMD_%s *cmd = static_cast<RS_CMD_%s *>(io->mToCore.reserve(sizeof(RS_CMD_%s)));\n", api->name, api->name, api->name);
-            fprintf(f, "    uint32_t size = sizeof(RS_CMD_%s);\n", api->name);
+            if (hasInlineDataPointers(api)) {
+                fprintf(f, "    RS_CMD_%s *cmd = NULL;\n", api->name);
+                fprintf(f, "    if (dataSize < 1024) {;\n");
+                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, dataSize + size));\n", api->name, api->name);
+                fprintf(f, "    } else {\n");
+                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, size));\n", api->name, api->name);
+                fprintf(f, "    }\n");
+                fprintf(f, "    uint8_t *payload = (uint8_t *)&cmd[1];\n");
+            } else {
+                fprintf(f, "    RS_CMD_%s *cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, size));\n", api->name, api->name, api->name);
+            }
 
             for (ct2=0; ct2 < api->paramCount; ct2++) {
                 const VarType *vt = &api->params[ct2];
                 needFlush += vt->ptrLevel;
-                fprintf(f, "    cmd->%s = %s;\n", vt->name, vt->name);
+                if (vt->ptrLevel && hasInlineDataPointers(api)) {
+                    fprintf(f, "    if (dataSize < 1024) {\n");
+                    fprintf(f, "        memcpy(payload, %s, %s_length);\n", vt->name, vt->name);
+                    fprintf(f, "        cmd->%s = (", vt->name);
+                    printVarType(f, vt);
+                    fprintf(f, ")payload;\n");
+                    fprintf(f, "        payload += %s_length;\n", vt->name);
+                    fprintf(f, "    } else {\n");
+                    fprintf(f, "        cmd->%s = %s;\n", vt->name, vt->name);
+                    fprintf(f, "    }\n");
+
+                } else {
+                    fprintf(f, "    cmd->%s = %s;\n", vt->name, vt->name);
+                }
             }
-            if (api->ret.typeName[0]) {
+            if (api->ret.typeName[0] || api->sync) {
                 needFlush = 1;
             }
 
-            fprintf(f, "    io->mToCore.commit");
-            if (needFlush) {
-                fprintf(f, "Sync");
+            if (hasInlineDataPointers(api)) {
+                fprintf(f, "    if (dataSize < 1024) {\n");
+                fprintf(f, "        io->coreCommit();\n");
+                fprintf(f, "    } else {\n");
+                fprintf(f, "        io->coreCommitSync();\n");
+                fprintf(f, "    }\n");
+            } else {
+                fprintf(f, "    io->coreCommit");
+                if (needFlush) {
+                    fprintf(f, "Sync");
+                }
+                fprintf(f, "();\n");
             }
-            fprintf(f, "(RS_CMD_ID_%s, size);\n", api->name);
 
             if (api->ret.typeName[0]) {
-                fprintf(f, "    return reinterpret_cast<");
+                fprintf(f, "\n    ");
                 printVarType(f, &api->ret);
-                fprintf(f, ">(io->mToCoreRet);\n");
+                fprintf(f, " ret;\n");
+                fprintf(f, "    io->coreGetReturn(&ret, sizeof(ret));\n");
+                fprintf(f, "    return ret;\n");
             }
         }
         fprintf(f, "};\n\n");
+
+
+        fprintf(f, "static ");
+        printFuncDecl(f, api, "RF_", 0, 0);
+        fprintf(f, "\n{\n");
+        fprintf(f, "    Fifo *f = NULL;\n");
+        fprintf(f, "    RS_CMD_%s cmd;\n", api->name);
+        fprintf(f, "    const uint32_t cmdSize = sizeof(cmd);\n");
+        fprintf(f, "    const uint32_t cmdID = RS_CMD_ID_%s;\n", api->name);
+        fprintf(f, "    f->writeAsync(&cmdID, sizeof(cmdID));\n");
+        fprintf(f, "    intptr_t offset = cmdSize;\n");
+        fprintf(f, "    uint32_t dataSize = 0;\n");
+        for (ct2=0; ct2 < api->paramCount; ct2++) {
+            const VarType *vt = &api->params[ct2];
+            if (vt->isConst && vt->ptrLevel) {
+                switch(vt->ptrLevel) {
+                case 1:
+                    fprintf(f, "    dataSize += %s_length;\n", vt->name);
+                    break;
+                case 2:
+                    fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
+                    fprintf(f, "        dataSize += %s_length[ct];\n", vt->name);
+                    fprintf(f, "    }\n");
+                    break;
+                default:
+                    printf("pointer level not handled!!");
+                }
+            }
+        }
+        fprintf(f, "\n");
+
+        for (ct2=0; ct2 < api->paramCount; ct2++) {
+            const VarType *vt = &api->params[ct2];
+            switch(vt->ptrLevel) {
+            case 0:
+                fprintf(f, "    cmd.%s = %s;\n", vt->name, vt->name);
+                break;
+            case 1:
+                fprintf(f, "    cmd.%s = (", vt->name);
+                printVarType(f, vt);
+                fprintf(f, ")offset;\n");
+                fprintf(f, "    offset += %s_length;\n", vt->name);
+                break;
+            case 2:
+                fprintf(f, "    cmd.%s = (", vt->name);
+                printVarType(f, vt);
+                fprintf(f, ")offset;\n");
+                fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
+                fprintf(f, "        offset += %s_length[ct];\n", vt->name);
+                fprintf(f, "    }\n");
+                break;
+            default:
+                fprintf(stderr, "pointer level not handled!!");
+            }
+        }
+        fprintf(f, "\n");
+
+        fprintf(f, "    f->writeAsync(&cmd, cmdSize);\n");
+        for (ct2=0; ct2 < api->paramCount; ct2++) {
+            const VarType *vt = &api->params[ct2];
+            if (vt->ptrLevel == 1) {
+                fprintf(f, "    f->writeAsync(%s, %s_length);\n", vt->name, vt->name);
+            }
+            if (vt->ptrLevel == 2) {
+                fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
+                fprintf(f, "        f->writeAsync(%s, %s_length[ct]);\n", vt->name, vt->name);
+                fprintf(f, "        offset += %s_length[ct];\n", vt->name);
+                fprintf(f, "    }\n");
+            }
+        }
+
+        if (api->ret.typeName[0]) {
+            fprintf(f, "    ");
+            printVarType(f, &api->ret);
+            fprintf(f, " retValue;\n");
+            fprintf(f, "    f->writeWaitReturn(&retValue, sizeof(retValue));\n");
+            fprintf(f, "    return retValue;\n");
+        }
+        fprintf(f, "}\n\n");
     }
+
+    fprintf(f, "\n");
+    fprintf(f, "static RsApiEntrypoints_t s_LocalTable = {\n");
+    for (ct=0; ct < apiCount; ct++) {
+        fprintf(f, "    LF_%s,\n", apis[ct].name);
+    }
+    fprintf(f, "};\n");
+
+    fprintf(f, "\n");
+    fprintf(f, "static RsApiEntrypoints_t s_RemoteTable = {\n");
+    for (ct=0; ct < apiCount; ct++) {
+        fprintf(f, "    RF_%s,\n", apis[ct].name);
+    }
+    fprintf(f, "};\n");
+
+    fprintf(f, "static RsApiEntrypoints_t *s_CurrentTable = &s_LocalTable;\n\n");
+    for (ct=0; ct < apiCount; ct++) {
+        int needFlush = 0;
+        const ApiEntry * api = &apis[ct];
+
+        printFuncDecl(f, api, "rs", 0, 0);
+        fprintf(f, "\n{\n");
+        fprintf(f, "    ");
+        if (api->ret.typeName[0]) {
+            fprintf(f, "return ");
+        }
+        fprintf(f, "s_CurrentTable->%s(", api->name);
+
+        if (!api->nocontext) {
+            fprintf(f, "(Context *)rsc");
+        }
+
+        for (ct2=0; ct2 < api->paramCount; ct2++) {
+            const VarType *vt = &api->params[ct2];
+            if (ct2 > 0 || !api->nocontext) {
+                fprintf(f, ", ");
+            }
+            fprintf(f, "%s", vt->name);
+        }
+        fprintf(f, ");\n");
+        fprintf(f, "}\n\n");
+    }
+
 }
 
 void printPlaybackCpp(FILE *f) {
@@ -192,37 +430,111 @@
     fprintf(f, "\n");
     fprintf(f, "namespace android {\n");
     fprintf(f, "namespace renderscript {\n");
-    fprintf(f, "#include \"rsHandcode.h\"\n");
     fprintf(f, "\n");
 
     for (ct=0; ct < apiCount; ct++) {
         const ApiEntry * api = &apis[ct];
 
-        fprintf(f, "void rsp_%s(Context *con, const void *vp)\n", api->name);
-        fprintf(f, "{\n");
-        if (api->handcodePlay) {
-            fprintf(f, "    rsHCPLAY_%s(con, vp);\n", api->name);
-        } else {
-            //fprintf(f, "    LOGE(\"play command %s\\n\");\n", api->name);
-            fprintf(f, "    const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
-            fprintf(f, "    ");
-            if (api->ret.typeName[0]) {
-                fprintf(f, "con->mIO.mToCoreRet = (intptr_t)");
-            }
-            fprintf(f, "rsi_%s(con", api->name);
-            for (ct2=0; ct2 < api->paramCount; ct2++) {
-                const VarType *vt = &api->params[ct2];
-                fprintf(f, ",\n           cmd->%s", vt->name);
-            }
-            fprintf(f, ");\n");
+        if (api->direct) {
+            continue;
         }
+
+        fprintf(f, "void rsp_%s(Context *con, const void *vp, size_t cmdSizeBytes) {\n", api->name);
+
+        //fprintf(f, "    LOGE(\"play command %s\\n\");\n", api->name);
+        fprintf(f, "    const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
+
+        fprintf(f, "    ");
+        if (api->ret.typeName[0]) {
+            fprintf(f, "\n    ");
+            printVarType(f, &api->ret);
+            fprintf(f, " ret = ");
+        }
+        fprintf(f, "rsi_%s(con", api->name);
+        for (ct2=0; ct2 < api->paramCount; ct2++) {
+            const VarType *vt = &api->params[ct2];
+            fprintf(f, ",\n           cmd->%s", vt->name);
+        }
+        fprintf(f, ");\n");
+
+        if (api->ret.typeName[0]) {
+            fprintf(f, "    con->mIO.coreSetReturn(&ret, sizeof(ret));\n");
+        }
+
         fprintf(f, "};\n\n");
     }
 
-    fprintf(f, "RsPlaybackFunc gPlaybackFuncs[%i] = {\n", apiCount + 1);
+    for (ct=0; ct < apiCount; ct++) {
+        const ApiEntry * api = &apis[ct];
+
+        fprintf(f, "void rspr_%s(Context *con, Fifo *f, uint8_t *scratch, size_t scratchSize) {\n", api->name);
+
+        //fprintf(f, "    LOGE(\"play command %s\\n\");\n", api->name);
+        fprintf(f, "    RS_CMD_%s cmd;\n", api->name);
+        fprintf(f, "    f->read(&cmd, sizeof(cmd));\n");
+
+        for (ct2=0; ct2 < api->paramCount; ct2++) {
+            const VarType *vt = &api->params[ct2];
+            if (vt->ptrLevel == 1) {
+                fprintf(f, "    cmd.%s = (", vt->name);
+                printVarType(f, vt);
+                fprintf(f, ")scratch;\n");
+                fprintf(f, "    f->read(scratch, cmd.%s_length);\n", vt->name);
+                fprintf(f, "    scratch += cmd.%s_length;\n", vt->name);
+            }
+            if (vt->ptrLevel == 2) {
+                fprintf(f, "    size_t sum_%s = 0;\n", vt->name);
+                fprintf(f, "    for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
+                fprintf(f, "        ((size_t *)scratch)[ct] = cmd.%s_length[ct];\n", vt->name);
+                fprintf(f, "        sum_%s += cmd.%s_length[ct];\n", vt->name, vt->name);
+                fprintf(f, "    }\n");
+                fprintf(f, "    f->read(scratch, sum_%s);\n", vt->name);
+                fprintf(f, "    scratch += sum_%s;\n", vt->name);
+            }
+        }
+        fprintf(f, "\n");
+
+        if (api->ret.typeName[0]) {
+            fprintf(f, "    ");
+            printVarType(f, &api->ret);
+            fprintf(f, " ret =\n");
+        }
+
+        fprintf(f, "    rsi_%s(", api->name);
+        if (!api->nocontext) {
+            fprintf(f, "con");
+        }
+        for (ct2=0; ct2 < api->paramCount; ct2++) {
+            const VarType *vt = &api->params[ct2];
+            if (ct2 > 0 || !api->nocontext) {
+                fprintf(f, ",\n");
+            }
+            fprintf(f, "           cmd.%s", vt->name);
+        }
+        fprintf(f, ");\n");
+
+        if (api->ret.typeName[0]) {
+            fprintf(f, "    f->readReturn(&ret, sizeof(ret));\n");
+        }
+
+        fprintf(f, "};\n\n");
+    }
+
+    fprintf(f, "RsPlaybackLocalFunc gPlaybackFuncs[%i] = {\n", apiCount + 1);
     fprintf(f, "    NULL,\n");
     for (ct=0; ct < apiCount; ct++) {
-        fprintf(f, "    %s%s,\n", "rsp_", apis[ct].name);
+        if (apis[ct].direct) {
+            fprintf(f, "    NULL,\n");
+        } else {
+            fprintf(f, "    %s%s,\n", "rsp_", apis[ct].name);
+        }
+    }
+    fprintf(f, "};\n");
+
+    fprintf(f, "RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i] = {\n", apiCount + 1);
+    fprintf(f, "    NULL,\n");
+    for (ct=0; ct < apiCount; ct++) {
+        fprintf(f, "    %s%s,\n", "rspr_", apis[ct].name);
     }
     fprintf(f, "};\n");
 
@@ -230,6 +542,8 @@
     fprintf(f, "};\n");
 }
 
+void yylex();
+
 int main(int argc, char **argv) {
     if (argc != 3) {
         fprintf(stderr, "usage: %s commandFile outFile\n", argv[0]);
@@ -258,14 +572,21 @@
         {
             fprintf(f, "\n");
             fprintf(f, "#include \"rsContext.h\"\n");
+            fprintf(f, "#include \"rsFifo.h\"\n");
             fprintf(f, "\n");
             fprintf(f, "namespace android {\n");
             fprintf(f, "namespace renderscript {\n");
             printStructures(f);
             printFuncDecls(f, "rsi_", 1);
             printPlaybackFuncs(f, "rsp_");
-            fprintf(f, "\n\ntypedef void (*RsPlaybackFunc)(Context *, const void *);\n");
-            fprintf(f, "extern RsPlaybackFunc gPlaybackFuncs[%i];\n", apiCount + 1);
+            fprintf(f, "\n\ntypedef struct RsPlaybackRemoteHeaderRec {\n");
+            fprintf(f, "    uint32_t command;\n");
+            fprintf(f, "    uint32_t size;\n");
+            fprintf(f, "} RsPlaybackRemoteHeader;\n\n");
+            fprintf(f, "typedef void (*RsPlaybackLocalFunc)(Context *, const void *, size_t sizeBytes);\n");
+            fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, Fifo *, uint8_t *scratch, size_t scratchSize);\n");
+            fprintf(f, "extern RsPlaybackLocalFunc gPlaybackFuncs[%i];\n", apiCount + 1);
+            fprintf(f, "extern RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i];\n", apiCount + 1);
 
             fprintf(f, "}\n");
             fprintf(f, "}\n");
@@ -290,6 +611,19 @@
             printPlaybackCpp(f);
         }
         break;
+
+        case '4': // rsgApiStream.cpp
+        {
+            printFileHeader(f);
+            printPlaybackCpp(f);
+        }
+
+        case '5': // rsgApiStreamReplay.cpp
+        {
+            printFileHeader(f);
+            printPlaybackCpp(f);
+        }
+        break;
     }
     fclose(f);
     return 0;
diff --git a/scriptc/rs_core.rsh b/scriptc/rs_core.rsh
index 464e1d9..4768bbe 100644
--- a/scriptc/rs_core.rsh
+++ b/scriptc/rs_core.rsh
@@ -295,6 +295,256 @@
 extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix2x2 *m);
 
 /////////////////////////////////////////////////////
+// quaternion ops
+/////////////////////////////////////////////////////
+
+static void __attribute__((overloadable))
+rsQuaternionSet(rs_quaternion *q, float w, float x, float y, float z) {
+    q->w = w;
+    q->x = x;
+    q->y = y;
+    q->z = z;
+}
+
+static void __attribute__((overloadable))
+rsQuaternionSet(rs_quaternion *q, const rs_quaternion *rhs) {
+    q->w = rhs->w;
+    q->x = rhs->x;
+    q->y = rhs->y;
+    q->z = rhs->z;
+}
+
+static void __attribute__((overloadable))
+rsQuaternionMultiply(rs_quaternion *q, float s) {
+    q->w *= s;
+    q->x *= s;
+    q->y *= s;
+    q->z *= s;
+}
+
+static void __attribute__((overloadable))
+rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) {
+    q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w;
+    q->x =  q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x;
+    q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->x + q->w*rhs->y;
+    q->z =  q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z;
+}
+
+static void
+rsQuaternionAdd(rs_quaternion *q, const rs_quaternion *rhs) {
+    q->w *= rhs->w;
+    q->x *= rhs->x;
+    q->y *= rhs->y;
+    q->z *= rhs->z;
+}
+
+static void
+rsQuaternionLoadRotateUnit(rs_quaternion *q, float rot, float x, float y, float z) {
+    rot *= (float)(M_PI / 180.0f) * 0.5f;
+    float c = cos(rot);
+    float s = sin(rot);
+
+    q->w = c;
+    q->x = x * s;
+    q->y = y * s;
+    q->z = z * s;
+}
+
+static void
+rsQuaternionLoadRotate(rs_quaternion *q, float rot, float x, float y, float z) {
+    const float len = x*x + y*y + z*z;
+    if (len != 1) {
+        const float recipLen = 1.f / sqrt(len);
+        x *= recipLen;
+        y *= recipLen;
+        z *= recipLen;
+    }
+    rsQuaternionLoadRotateUnit(q, rot, x, y, z);
+}
+
+static void
+rsQuaternionConjugate(rs_quaternion *q) {
+    q->x = -q->x;
+    q->y = -q->y;
+    q->z = -q->z;
+}
+
+static float
+rsQuaternionDot(const rs_quaternion *q0, const rs_quaternion *q1) {
+    return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
+}
+
+static void
+rsQuaternionNormalize(rs_quaternion *q) {
+    const float len = rsQuaternionDot(q, q);
+    if (len != 1) {
+        const float recipLen = 1.f / sqrt(len);
+        rsQuaternionMultiply(q, recipLen);
+    }
+}
+
+static void
+rsQuaternionSlerp(rs_quaternion *q, const rs_quaternion *q0, const rs_quaternion *q1, float t) {
+    if (t <= 0.0f) {
+        rsQuaternionSet(q, q0);
+        return;
+    }
+    if (t >= 1.0f) {
+        rsQuaternionSet(q, q1);
+        return;
+    }
+
+    rs_quaternion tempq0, tempq1;
+    rsQuaternionSet(&tempq0, q0);
+    rsQuaternionSet(&tempq1, q1);
+
+    float angle = rsQuaternionDot(q0, q1);
+    if (angle < 0) {
+        rsQuaternionMultiply(&tempq0, -1.0f);
+        angle *= -1.0f;
+    }
+
+    float scale, invScale;
+    if (angle + 1.0f > 0.05f) {
+        if (1.0f - angle >= 0.05f) {
+            float theta = acos(angle);
+            float invSinTheta = 1.0f / sin(theta);
+            scale = sin(theta * (1.0f - t)) * invSinTheta;
+            invScale = sin(theta * t) * invSinTheta;
+        } else {
+            scale = 1.0f - t;
+            invScale = t;
+        }
+    } else {
+        rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w);
+        scale = sin(M_PI * (0.5f - t));
+        invScale = sin(M_PI * t);
+    }
+
+    rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale,
+                        tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale);
+}
+
+static void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) {
+    float x2 = 2.0f * q->x * q->x;
+    float y2 = 2.0f * q->y * q->y;
+    float z2 = 2.0f * q->z * q->z;
+    float xy = 2.0f * q->x * q->y;
+    float wz = 2.0f * q->w * q->z;
+    float xz = 2.0f * q->x * q->z;
+    float wy = 2.0f * q->w * q->y;
+    float wx = 2.0f * q->w * q->x;
+    float yz = 2.0f * q->y * q->z;
+
+    m->m[0] = 1.0f - y2 - z2;
+    m->m[1] = xy - wz;
+    m->m[2] = xz + wy;
+    m->m[3] = 0.0f;
+
+    m->m[4] = xy + wz;
+    m->m[5] = 1.0f - x2 - z2;
+    m->m[6] = yz - wx;
+    m->m[7] = 0.0f;
+
+    m->m[8] = xz - wy;
+    m->m[9] = yz - wx;
+    m->m[10] = 1.0f - x2 - y2;
+    m->m[11] = 0.0f;
+
+    m->m[12] = 0.0f;
+    m->m[13] = 0.0f;
+    m->m[14] = 0.0f;
+    m->m[15] = 1.0f;
+}
+
+/////////////////////////////////////////////////////
+// utility funcs
+/////////////////////////////////////////////////////
+__inline__ static void __attribute__((overloadable, always_inline))
+rsExtractFrustumPlanes(const rs_matrix4x4 *modelViewProj,
+                         float4 *left, float4 *right,
+                         float4 *top, float4 *bottom,
+                         float4 *near, float4 *far) {
+    // x y z w = a b c d in the plane equation
+    left->x = modelViewProj->m[3] + modelViewProj->m[0];
+    left->y = modelViewProj->m[7] + modelViewProj->m[4];
+    left->z = modelViewProj->m[11] + modelViewProj->m[8];
+    left->w = modelViewProj->m[15] + modelViewProj->m[12];
+
+    right->x = modelViewProj->m[3] - modelViewProj->m[0];
+    right->y = modelViewProj->m[7] - modelViewProj->m[4];
+    right->z = modelViewProj->m[11] - modelViewProj->m[8];
+    right->w = modelViewProj->m[15] - modelViewProj->m[12];
+
+    top->x = modelViewProj->m[3] - modelViewProj->m[1];
+    top->y = modelViewProj->m[7] - modelViewProj->m[5];
+    top->z = modelViewProj->m[11] - modelViewProj->m[9];
+    top->w = modelViewProj->m[15] - modelViewProj->m[13];
+
+    bottom->x = modelViewProj->m[3] + modelViewProj->m[1];
+    bottom->y = modelViewProj->m[7] + modelViewProj->m[5];
+    bottom->z = modelViewProj->m[11] + modelViewProj->m[9];
+    bottom->w = modelViewProj->m[15] + modelViewProj->m[13];
+
+    near->x = modelViewProj->m[3] + modelViewProj->m[2];
+    near->y = modelViewProj->m[7] + modelViewProj->m[6];
+    near->z = modelViewProj->m[11] + modelViewProj->m[10];
+    near->w = modelViewProj->m[15] + modelViewProj->m[14];
+
+    far->x = modelViewProj->m[3] - modelViewProj->m[2];
+    far->y = modelViewProj->m[7] - modelViewProj->m[6];
+    far->z = modelViewProj->m[11] - modelViewProj->m[10];
+    far->w = modelViewProj->m[15] - modelViewProj->m[14];
+
+    float len = length(left->xyz);
+    *left /= len;
+    len = length(right->xyz);
+    *right /= len;
+    len = length(top->xyz);
+    *top /= len;
+    len = length(bottom->xyz);
+    *bottom /= len;
+    len = length(near->xyz);
+    *near /= len;
+    len = length(far->xyz);
+    *far /= len;
+}
+
+__inline__ static bool __attribute__((overloadable, always_inline))
+rsIsSphereInFrustum(float4 *sphere,
+                      float4 *left, float4 *right,
+                      float4 *top, float4 *bottom,
+                      float4 *near, float4 *far) {
+
+    float distToCenter = dot(left->xyz, sphere->xyz) + left->w;
+    if (distToCenter < -sphere->w) {
+        return false;
+    }
+    distToCenter = dot(right->xyz, sphere->xyz) + right->w;
+    if (distToCenter < -sphere->w) {
+        return false;
+    }
+    distToCenter = dot(top->xyz, sphere->xyz) + top->w;
+    if (distToCenter < -sphere->w) {
+        return false;
+    }
+    distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w;
+    if (distToCenter < -sphere->w) {
+        return false;
+    }
+    distToCenter = dot(near->xyz, sphere->xyz) + near->w;
+    if (distToCenter < -sphere->w) {
+        return false;
+    }
+    distToCenter = dot(far->xyz, sphere->xyz) + far->w;
+    if (distToCenter < -sphere->w) {
+        return false;
+    }
+    return true;
+}
+
+
+/////////////////////////////////////////////////////
 // int ops
 /////////////////////////////////////////////////////
 
diff --git a/scriptc/rs_graphics.rsh b/scriptc/rs_graphics.rsh
index 142e21a..d53bc95 100644
--- a/scriptc/rs_graphics.rsh
+++ b/scriptc/rs_graphics.rsh
@@ -1,6 +1,46 @@
 #ifndef __RS_GRAPHICS_RSH__
 #define __RS_GRAPHICS_RSH__
 
+/**
+ * Set the color target used for all subsequent rendering calls
+ * @param colorTarget
+ * @param slot
+ */
+extern void __attribute__((overloadable))
+    rsgBindColorTarget(rs_allocation colorTarget, uint slot);
+
+/**
+ * Clear the previously set color target
+ * @param slot
+ */
+extern void __attribute__((overloadable))
+    rsgClearColorTarget(uint slot);
+
+/**
+ * Set the depth target used for all subsequent rendering calls
+ * @param depthTarget
+ */
+extern void __attribute__((overloadable))
+    rsgBindDepthTarget(rs_allocation depthTarget);
+
+/**
+ * Clear the previously set depth target
+ */
+extern void __attribute__((overloadable))
+    rsgClearDepthTarget(void);
+
+/**
+ * Clear all color and depth targets and resume rendering into
+ * the framebuffer
+ */
+extern void __attribute__((overloadable))
+    rsgClearAllRenderTargets(void);
+
+/**
+ * Force RenderScript to finish all rendering commands
+ */
+extern uint __attribute__((overloadable))
+    rsgFinish(void);
 
 /**
  * Bind a new ProgramFragment to the rendering context.
@@ -248,13 +288,5 @@
     bBoxMax->z = z2;
 }
 
-
-/**
- * @hide
- * Deprecated, do not use.
- *
- */
-extern void __attribute__((overloadable)) color(float, float, float, float);
-
 #endif
 
diff --git a/scriptc/rs_math.rsh b/scriptc/rs_math.rsh
index e2719e0..6e3cfdb 100644
--- a/scriptc/rs_math.rsh
+++ b/scriptc/rs_math.rsh
@@ -97,13 +97,6 @@
     rsGetAllocation(const void *);
 
 /**
- * Mark the contents of an allocation as dirty.  This forces any other scripts
- * using the allocation to receive the updated
- */
-extern void __attribute__((overloadable))
-    rsAllocationMarkDirty(rs_allocation);
-
-/**
  * Query the dimension of an allocation.
  *
  * @return uint32_t The X dimension of the allocation.
diff --git a/scriptc/rs_types.rsh b/scriptc/rs_types.rsh
index 367af46..d9f4b4b 100644
--- a/scriptc/rs_types.rsh
+++ b/scriptc/rs_types.rsh
@@ -36,6 +36,10 @@
 typedef float float3 __attribute__((ext_vector_type(3)));
 typedef float float4 __attribute__((ext_vector_type(4)));
 
+typedef double double2 __attribute__((ext_vector_type(2)));
+typedef double double3 __attribute__((ext_vector_type(3)));
+typedef double double4 __attribute__((ext_vector_type(4)));
+
 typedef uchar uchar2 __attribute__((ext_vector_type(2)));
 typedef uchar uchar3 __attribute__((ext_vector_type(3)));
 typedef uchar uchar4 __attribute__((ext_vector_type(4)));
@@ -48,6 +52,10 @@
 typedef uint uint3 __attribute__((ext_vector_type(3)));
 typedef uint uint4 __attribute__((ext_vector_type(4)));
 
+typedef ulong ulong2 __attribute__((ext_vector_type(2)));
+typedef ulong ulong3 __attribute__((ext_vector_type(3)));
+typedef ulong ulong4 __attribute__((ext_vector_type(4)));
+
 typedef char char2 __attribute__((ext_vector_type(2)));
 typedef char char3 __attribute__((ext_vector_type(3)));
 typedef char char4 __attribute__((ext_vector_type(4)));
@@ -60,6 +68,9 @@
 typedef int int3 __attribute__((ext_vector_type(3)));
 typedef int int4 __attribute__((ext_vector_type(4)));
 
+typedef long long2 __attribute__((ext_vector_type(2)));
+typedef long long3 __attribute__((ext_vector_type(3)));
+typedef long long4 __attribute__((ext_vector_type(4)));
 
 typedef struct {
     float m[16];
@@ -73,6 +84,8 @@
     float m[4];
 } rs_matrix2x2;
 
+typedef float4 rs_quaternion;
+
 #define RS_PACKED __attribute__((packed, aligned(4)))
 
 #endif
diff --git a/spec.h b/spec.h
index 82650a7..ecc5cc7 100644
--- a/spec.h
+++ b/spec.h
@@ -25,7 +25,8 @@
   char name[256];
   int sync;
   int handcodeApi;
-  int handcodePlay;
+  int direct;
+  int nocontext;
   int paramCount;
   VarType ret;
   VarType params[16];
diff --git a/spec.l b/spec.l
index 6a9010f..a24bfd3 100644
--- a/spec.l
+++ b/spec.l
@@ -20,6 +20,30 @@
 
    int typeNextState;
 
+   void checkPointerType() {
+       VarType *baseType = currType;
+       int curPtrLevel = 0;
+       while (curPtrLevel < baseType->ptrLevel) {
+           currType = &apis[apiCount].params[apis[apiCount].paramCount];
+           currType->type = 4;
+           currType->ptrLevel = curPtrLevel;
+           if (currType->ptrLevel > 0) {
+              currType->isConst = 1;
+           }
+           sprintf(currType->typeName, "%s", "size_t");
+           switch(baseType->ptrLevel - curPtrLevel) {
+           case 1:
+              sprintf(currType->name, "%s_length", baseType->name);
+              break;
+           case 2:
+              sprintf(currType->name, "%s_length_length", baseType->name);
+              break;
+           }
+           apis[apiCount].paramCount++;
+           curPtrLevel ++;
+       }
+   }
+
    extern "C" int yylex();
 
 %%
@@ -31,6 +55,7 @@
 <comment>"*"+"/"        BEGIN(INITIAL);
 
 <*>" "   //printf("found ' '\n");
+<*>"\t"   //printf("found ' '\n");
 <*>"\n"  ++num_lines; //printf("found lf \n");
 
 {ID} {
@@ -51,8 +76,12 @@
     apis[apiCount].handcodeApi = 1;
     }
 
-<api_entry2>"handcodePlay" {
-    apis[apiCount].handcodePlay = 1;
+<api_entry2>"direct" {
+    apis[apiCount].direct = 1;
+    }
+
+<api_entry2>"nocontext" {
+    apis[apiCount].nocontext = 1;
     }
 
 <api_entry2>"ret" {
@@ -145,6 +174,7 @@
 
 <api_entry_param>{ID} {
     memcpy(currType->name, yytext, yyleng);
+    checkPointerType();
     BEGIN(api_entry2);
     }