Add the Renderscript library. (Not in the build by default yet.)

This library can be used to create animated 3D User Interfaces.

This library is currently under heavy development, so it's not part of
the build by default.

In order to build this library, you must define

   BUILD_RENDERSCRIPT=true

in your build environment.

You will also have to manually edit

 build/core/prelink-linux-arm.map

And add libRS and libRS_jni at the end like this (exact address may change.)

libRS.so                0x9A100000
libRS_jni.so            0x9A000000
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..73c1eea
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,132 @@
+# Only build if BUILD_RENDERSCRIPT is defined to true in the environment.
+ifeq ($(BUILD_RENDERSCRIPT),true)
+
+TOP_LOCAL_PATH:=$(call my-dir)
+LOCAL_PATH:= $(TOP_LOCAL_PATH)
+
+
+# Build rsg-generator
+
+LOCAL_MODULE := rsg-generator
+
+# These symbols are normally defined by BUILD_XXX, but we need to define them
+# here so that local-intermediates-dir works.
+
+LOCAL_IS_HOST_MODULE := true
+LOCAL_MODULE_CLASS := EXECUTABLES
+intermediates:= $(local-intermediates-dir)
+
+GEN := $(addprefix $(intermediates)/, \
+            lex.yy.c \
+        )
+$(GEN):	PRIVATE_CUSTOM_TOOL = flex -o $@ $<
+
+$(intermediates)/lex.yy.c : $(LOCAL_PATH)/spec.lex
+	$(transform-generated-source)
+
+$(LOCAL_PATH)/rsg_generator.c : $(intermediates)/lex.yy.c
+
+LOCAL_SRC_FILES:= \
+    rsg_generator.c
+	
+include $(BUILD_HOST_EXECUTABLE)
+
+RSG_GENERATOR:=$(LOCAL_BUILT_MODULE)
+
+# Build render script lib
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libRS
+
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+intermediates:= $(local-intermediates-dir)
+
+RS_GENERATED_INCLUDE_DIR:=$(intermediates)
+
+# Generate custom headers
+
+GEN := $(addprefix $(intermediates)/, \
+            rsgApiStructs.h \
+            rsgApiFuncDecl.h \
+        )
+
+$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(LOCAL_PATH)/rs.spec
+$(GEN) : $(RSG_GENERATOR) $(LOCAL_PATH)/rs.spec
+$(GEN): $(intermediates)/%.h : $(LOCAL_PATH)/%.h.rsg
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+# Generate custom source files
+
+GEN := $(addprefix $(intermediates)/, \
+            rsgApi.cpp \
+            rsgApiReplay.cpp \
+        )
+        
+$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(LOCAL_PATH)/rs.spec
+$(GEN) : $(RSG_GENERATOR) $(LOCAL_PATH)/rs.spec
+$(GEN): $(intermediates)/%.cpp : $(LOCAL_PATH)/%.cpp.rsg
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+LOCAL_SRC_FILES:= \
+	rsAdapter.cpp \
+	rsAllocation.cpp \
+	rsComponent.cpp \
+	rsContext.cpp \
+	rsDevice.cpp \
+	rsElement.cpp \
+	rsLocklessFifo.cpp \
+	rsObjectBase.cpp \
+	rsMatrix.cpp \
+	rsProgram.cpp \
+	rsProgramFragment.cpp \
+	rsProgramFragmentStore.cpp \
+	rsProgramVertex.cpp \
+	rsSampler.cpp \
+	rsScript.cpp \
+	rsScriptC.cpp \
+	rsThreadIO.cpp \
+	rsType.cpp \
+	rsTriangleMesh.cpp
+
+LOCAL_SHARED_LIBRARIES += libcutils libutils libEGL libGLESv1_CM libui 
+LOCAL_LDLIBS := -lpthread -ldl
+LOCAL_MODULE:= libRS
+
+#LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SHARED_LIBRARY)
+
+# Build JNI library
+
+LOCAL_PATH:= $(TOP_LOCAL_PATH)/jni
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	RenderScript_jni.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libandroid_runtime \
+	libnativehelper \
+	libRS \
+	libcutils \
+	libutils \
+	libui
+
+LOCAL_STATIC_LIBRARIES :=
+
+LOCAL_C_INCLUDES += \
+	$(JNI_H_INCLUDE) \
+	$(RS_GENERATED_INCLUDE_DIR) \
+	$(call include-path-for, corecg graphics)
+
+LOCAL_CFLAGS +=
+
+LOCAL_LDLIBS := -lpthread
+
+LOCAL_MODULE:= libRS_jni
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif # BUILD_RENDERSCRIPT
\ No newline at end of file
diff --git a/RenderScript.h b/RenderScript.h
new file mode 100644
index 0000000..e1a4b6d
--- /dev/null
+++ b/RenderScript.h
@@ -0,0 +1,185 @@
+/*
+ * 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_H
+#define RENDER_SCRIPT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//////////////////////////////////////////////////////
+// 
+
+typedef void * RsAdapter1D;
+typedef void * RsAdapter2D;
+typedef void * RsAllocation;
+typedef void * RsContext;
+typedef void * RsDevice;
+typedef void * RsElement;
+typedef void * RsSampler;
+typedef void * RsScript;
+typedef void * RsScriptBasicTemp;
+typedef void * RsTriangleMesh;
+typedef void * RsType;
+
+typedef void * RsProgramVertex;
+typedef void * RsProgramFragment;
+typedef void * RsProgramFragmentStore;
+
+RsDevice rsDeviceCreate();
+void rsDeviceDestroy(RsDevice);
+
+RsContext rsContextCreate(RsDevice, void *, uint32_t version);
+void rsContextDestroy(RsContext);
+
+enum RsDataType {
+    RS_TYPE_FLOAT,
+    RS_TYPE_UNSIGNED,
+    RS_TYPE_SIGNED
+};
+
+enum RsDataKind {
+    RS_KIND_USER,
+    RS_KIND_RED, 
+    RS_KIND_GREEN, 
+    RS_KIND_BLUE, 
+    RS_KIND_ALPHA, 
+    RS_KIND_LUMINANCE, 
+    RS_KIND_INTENSITY,
+    RS_KIND_X, 
+    RS_KIND_Y, 
+    RS_KIND_Z, 
+    RS_KIND_W,
+    RS_KIND_S, 
+    RS_KIND_T, 
+    RS_KIND_Q, 
+    RS_KIND_R,
+    RS_KIND_NX, 
+    RS_KIND_NY, 
+    RS_KIND_NZ,
+    RS_KIND_INDEX
+};
+
+enum RsElementPredefined {
+    RS_ELEMENT_USER_U8,
+    RS_ELEMENT_USER_I8,
+    RS_ELEMENT_USER_U16,
+    RS_ELEMENT_USER_I16,
+    RS_ELEMENT_USER_U32,
+    RS_ELEMENT_USER_I32,
+    RS_ELEMENT_USER_FLOAT, 
+
+    RS_ELEMENT_RGB_565, 
+    RS_ELEMENT_RGBA_5551, 
+    RS_ELEMENT_RGBA_4444, 
+    RS_ELEMENT_RGB_888, 
+    RS_ELEMENT_RGBA_8888, 
+
+    RS_ELEMENT_INDEX_16, 
+    RS_ELEMENT_INDEX_32, 
+    RS_ELEMENT_XY_F32, 
+    RS_ELEMENT_XYZ_F32, 
+    RS_ELEMENT_ST_XY_F32, 
+    RS_ELEMENT_ST_XYZ_F32, 
+    RS_ELEMENT_NORM_XYZ_F32,
+    RS_ELEMENT_NORM_ST_XYZ_F32,
+};  
+
+enum RsSamplerParam {
+    RS_SAMPLER_MIN_FILTER,
+    RS_SAMPLER_MAG_FILTER,
+    RS_SAMPLER_WRAP_S,
+    RS_SAMPLER_WRAP_T,
+    RS_SAMPLER_WRAP_R
+};  
+
+enum RsSamplerValue {
+    RS_SAMPLER_NEAREST,
+    RS_SAMPLER_LINEAR,
+    RS_SAMPLER_LINEAR_MIP_LINEAR,
+    RS_SAMPLER_WRAP,
+    RS_SAMPLER_CLAMP
+};  
+
+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, 
+    RS_BLEND_SRC_ONE, 
+    RS_BLEND_SRC_DST_COLOR, 
+    RS_BLEND_SRC_ONE_MINUS_DST_COLOR, 
+    RS_BLEND_SRC_SRC_ALPHA, 
+    RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA, 
+    RS_BLEND_SRC_DST_ALPHA, 
+    RS_BLEND_SRC_ONE_MINUS_DST_ALPHA, 
+    RS_BLEND_SRC_SRC_ALPHA_SATURATE
+};
+
+enum RsBlendDstFunc {
+    RS_BLEND_DST_ZERO, 
+    RS_BLEND_DST_ONE, 
+    RS_BLEND_DST_SRC_COLOR, 
+    RS_BLEND_DST_ONE_MINUS_SRC_COLOR, 
+    RS_BLEND_DST_SRC_ALPHA, 
+    RS_BLEND_DST_ONE_MINUS_SRC_ALPHA, 
+    RS_BLEND_DST_DST_ALPHA, 
+    RS_BLEND_DST_ONE_MINUS_DST_ALPHA
+};
+
+enum RsTexEnvMode {
+    RS_TEX_ENV_MODE_REPLACE,
+    RS_TEX_ENV_MODE_MODULATE,
+    RS_TEX_ENV_MODE_DECAL
+};
+
+
+
+#include "rsgApiFuncDecl.h"
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // RENDER_SCRIPT_H
+
+
+
diff --git a/RenderScriptEnv.h b/RenderScriptEnv.h
new file mode 100644
index 0000000..9ba1a00
--- /dev/null
+++ b/RenderScriptEnv.h
@@ -0,0 +1,93 @@
+#include <stdint.h>
+
+
+typedef void * RsAdapter1D;
+typedef void * RsAdapter2D;
+typedef void * RsAllocation;
+typedef void * RsContext;
+typedef void * RsDevice;
+typedef void * RsElement;
+typedef void * RsSampler;
+typedef void * RsScript;
+typedef void * RsScriptBasicTemp;
+typedef void * RsTriangleMesh;
+typedef void * RsType;
+typedef void * RsProgramFragment;
+typedef void * RsProgramFragmentStore;
+
+
+typedef struct {
+    float m[16];
+} rsc_Matrix;
+
+
+typedef struct {
+    float v[4];
+} rsc_Vector4;
+
+#define RS_PROGRAM_VERTEX_MODELVIEW_OFFSET 0
+#define RS_PROGRAM_VERTEX_PROJECTION_OFFSET 16
+#define RS_PROGRAM_VERTEX_TEXTURE_OFFSET 32
+
+typedef struct {
+    const void * (*loadEnvVp)(void *con, uint32_t bank, uint32_t offset);
+
+    float (*loadEnvF)(void *con, uint32_t bank, uint32_t offset);
+    int32_t (*loadEnvI32)(void *con, uint32_t bank, uint32_t offset);
+    uint32_t (*loadEnvU32)(void *con, uint32_t bank, uint32_t offset);
+    void (*loadEnvVec4)(void *con, uint32_t bank, uint32_t offset, rsc_Vector4 *);
+    void (*loadEnvMatrix)(void *con, uint32_t bank, uint32_t offset, rsc_Matrix *);
+
+    void (*storeEnvF)(void *con, uint32_t bank, uint32_t offset, float);
+    void (*storeEnvI32)(void *con, uint32_t bank, uint32_t offset, int32_t);
+    void (*storeEnvU32)(void *con, uint32_t bank, uint32_t offset, uint32_t);
+    void (*storeEnvVec4)(void *con, uint32_t bank, uint32_t offset, const rsc_Vector4 *);
+    void (*storeEnvMatrix)(void *con, uint32_t bank, uint32_t offset, const rsc_Matrix *);
+
+    void (*matrixLoadIdentity)(void *con, rsc_Matrix *);
+    void (*matrixLoadFloat)(void *con, rsc_Matrix *, const float *);
+    void (*matrixLoadMat)(void *con, rsc_Matrix *, const rsc_Matrix *);
+    void (*matrixLoadRotate)(void *con, rsc_Matrix *, float rot, float x, float y, float z);
+    void (*matrixLoadScale)(void *con, rsc_Matrix *, float x, float y, float z);
+    void (*matrixLoadTranslate)(void *con, rsc_Matrix *, float x, float y, float z);
+    void (*matrixLoadMultiply)(void *con, rsc_Matrix *, const rsc_Matrix *lhs, const rsc_Matrix *rhs);
+    void (*matrixMultiply)(void *con, rsc_Matrix *, const rsc_Matrix *rhs);
+    void (*matrixRotate)(void *con, rsc_Matrix *, float rot, float x, float y, float z);
+    void (*matrixScale)(void *con, rsc_Matrix *, float x, float y, float z);
+    void (*matrixTranslate)(void *con, rsc_Matrix *, float x, float y, float z);
+
+    void (*color)(void *con, float r, float g, float b, float a);
+
+    void (*renderTriangleMesh)(void *con, RsTriangleMesh);
+    void (*renderTriangleMeshRange)(void *con, RsTriangleMesh, uint32_t start, uint32_t count);
+
+    void (*programFragmentBindTexture)(void *con, RsProgramFragment, uint32_t slot, RsAllocation);
+    void (*programFragmentBindSampler)(void *con, RsProgramFragment, uint32_t slot, RsAllocation);
+    
+    void (*materialDiffuse)(void *con, float r, float g, float b, float a);
+    void (*materialSpecular)(void *con, float r, float g, float b, float a);
+    void (*lightPosition)(void *con, float x, float y, float z, float w);
+    void (*materialShininess)(void *con, float s);
+
+    void (*uploadToTexture)(void *con, RsAllocation va, uint32_t baseMipLevel);
+
+    void (*enable)(void *con, uint32_t);
+    void (*disable)(void *con, uint32_t);
+
+    uint32_t (*rand)(void *con, uint32_t max);
+
+    // Assumes (GL_FIXED) x,y,z (GL_UNSIGNED_BYTE)r,g,b,a
+    void (*drawTriangleArray)(void *con, RsAllocation alloc, uint32_t count);
+
+    void (*contextBindProgramFragment)(void *con, RsProgramFragment pf);
+    void (*contextBindProgramFragmentStore)(void *con, RsProgramFragmentStore pfs);
+} rsc_FunctionTable;
+
+typedef void (*rsc_RunScript)(void *con, const rsc_FunctionTable *, uint32_t launchID);
+
+
+/* EnableCap */
+#define GL_LIGHTING                       0x0B50
+
+/* LightName */
+#define GL_LIGHT0                         0x4000
diff --git a/jni/RenderScript_jni.cpp b/jni/RenderScript_jni.cpp
new file mode 100644
index 0000000..5b226a5
--- /dev/null
+++ b/jni/RenderScript_jni.cpp
@@ -0,0 +1,897 @@
+/*
+ * Copyright (C) 2006 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 <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <math.h>
+
+#include <utils/misc.h>
+#include <utils/Log.h>
+
+#include <ui/EGLNativeWindowSurface.h>
+#include <ui/Surface.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include "../RenderScript.h"
+#include "../RenderScriptEnv.h"
+
+//#define LOG_API LOGE
+#define LOG_API(...)
+
+using namespace android;
+
+extern "C" void test_script(void *con, const rsc_FunctionTable *ft, uint32_t launchID);
+
+void test_script(void *con, const rsc_FunctionTable *ft, uint32_t launchID)
+{
+    int count = ft->loadEnvI32(con, 0, 1);
+    int touch = ft->loadEnvI32(con, 0, 2);
+    int x = ft->loadEnvI32(con, 0, 3);
+    int y = 480 - ft->loadEnvI32(con, 0, 4);
+
+    int rate = 4;
+    int maxLife = (count / rate) - 1;
+    int lifeShift = 0;
+    {
+        int life = maxLife;
+        while (life > 255) {
+            life >>= 1;
+            lifeShift ++;
+        }
+    }
+
+    if (touch) {
+        int newPart = ft->loadEnvI32(con, 2, 0);
+        for (int ct2=0; ct2<rate; ct2++) {
+            int dx = ft->rand(con, 0x10000) - 0x8000;
+            int dy = ft->rand(con, 0x10000) - 0x8000;
+
+            int idx = newPart * 5 + 1;
+            ft->storeEnvI32(con, 2, idx, dx);
+            ft->storeEnvI32(con, 2, idx + 1, dy);
+            ft->storeEnvI32(con, 2, idx + 2, maxLife);
+            ft->storeEnvI32(con, 2, idx + 3, x << 16);
+            ft->storeEnvI32(con, 2, idx + 4, y << 16);
+
+            newPart++;
+            if (newPart >= count) {
+                newPart = 0;
+            }
+        }
+        ft->storeEnvI32(con, 2, 0, newPart);
+    }
+
+    // Emulate intrinsic perf...
+    int32_t * partPtr = (int32_t *)ft->loadEnvVp(con, 2, 4);
+    int32_t * vertPtr = (int32_t *)ft->loadEnvVp(con, 1, 0);
+
+    int drawCount = 0;
+    for (int ct=0; ct < count; ct++) {
+        //int srcIdx = ct * 5 + 1;
+        //int dstIdx = ct * 3 * 3;
+
+        int dx = partPtr[0]; //ft->loadEnvI32(con, 2, srcIdx);
+        int dy = partPtr[1]; //ft->loadEnvI32(con, 2, srcIdx + 1);
+        int life = partPtr[2]; //ft->loadEnvI32(con, 2, srcIdx + 2);
+        int posx = partPtr[3]; //ft->loadEnvI32(con, 2, srcIdx + 3);
+        int posy = partPtr[4]; //ft->loadEnvI32(con, 2, srcIdx + 4);
+
+        if (life) {
+            if (posy > 0) {
+                uint32_t c = 0xffafcf | ((life >> lifeShift) << 24);
+
+                ((uint32_t *)vertPtr)[0] = c; //ft->storeEnvU32(con, 1, dstIdx, c);
+                vertPtr[1] = posx; //ft->storeEnvI32(con, 1, dstIdx + 1, posx);
+                vertPtr[2] = posy; //ft->storeEnvI32(con, 1, dstIdx + 2, posy);
+
+                ((uint32_t *)vertPtr)[3] = c; //ft->storeEnvU32(con, 1, dstIdx + 3, c);
+                vertPtr[4] = posx + 0x10000; //ft->storeEnvI32(con, 1, dstIdx + 4, posx + 0x10000);
+                vertPtr[5] = posy + dy * 4; //ft->storeEnvI32(con, 1, dstIdx + 5, posy);
+
+                ((uint32_t *)vertPtr)[6] = c; //ft->storeEnvU32(con, 1, dstIdx + 6, c);
+                vertPtr[7] = posx - 0x10000; //ft->storeEnvI32(con, 1, dstIdx + 7, posx + 0x0800);
+                vertPtr[8] = posy + dy * 4; //ft->storeEnvI32(con, 1, dstIdx + 8, posy + 0x10000);
+
+                vertPtr += 9;
+                drawCount ++;
+            } else {
+                if (dy < 0) {
+                    dy = (-dy) >> 1;
+                }
+            }
+
+            posx += dx;
+            posy += dy;
+            dy -= 0x400;
+            life --;
+
+            partPtr[0] = dx; //ft->storeEnvI32(con, 2, srcIdx, dx);
+            partPtr[1] = dy; //ft->storeEnvI32(con, 2, srcIdx + 1, dy);
+            partPtr[2] = life; //ft->storeEnvI32(con, 2, srcIdx + 2, life);
+            partPtr[3] = posx; //ft->storeEnvI32(con, 2, srcIdx + 3, posx);
+            partPtr[4] = posy; //ft->storeEnvI32(con, 2, srcIdx + 4, posy);
+        }
+
+        partPtr += 5;
+    }
+
+    ft->drawTriangleArray(con, (RsAllocation)ft->loadEnvI32(con, 0, 5), drawCount);
+}
+
+
+// ---------------------------------------------------------------------------
+
+static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
+{
+    jclass npeClazz = env->FindClass(exc);
+    env->ThrowNew(npeClazz, msg);
+}
+
+static jfieldID gContextId;
+
+static void _nInit(JNIEnv *_env, jclass _this)
+{
+    LOGE("_nInit");
+    gContextId             = _env->GetFieldID(_this, "mContext", "I");
+}
+
+
+// ---------------------------------------------------------------------------
+
+static jint
+nDeviceCreate(JNIEnv *_env, jobject _this)
+{
+    LOG_API("nDeviceCreate");
+    return (jint)rsDeviceCreate();
+}
+
+static void
+nDeviceDestroy(JNIEnv *_env, jobject _this, jint dev)
+{
+    LOG_API("nDeviceDestroy");
+    return rsDeviceDestroy((RsDevice)dev);
+}
+
+static jint
+nContextCreate(JNIEnv *_env, jobject _this, jint dev, jobject wnd, jint ver)
+{
+    LOG_API("nContextCreate");
+
+    if (wnd == NULL) {
+        not_valid_surface:
+        doThrow(_env, "java/lang/IllegalArgumentException",
+                "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface");
+        return 0;
+    }
+    jclass surface_class = _env->FindClass("android/view/Surface");
+    jfieldID surfaceFieldID = _env->GetFieldID(surface_class, "mSurface", "I");
+    Surface * window = (Surface*)_env->GetIntField(wnd, surfaceFieldID);
+    if (window == NULL)
+        goto not_valid_surface;
+
+    LOGE("nContextCreate 5");
+    return (jint)rsContextCreate((RsDevice)dev, window, ver);
+}
+
+static void
+nContextDestroy(JNIEnv *_env, jobject _this, jint con)
+{
+    LOG_API("nContextDestroy, con(%p)", (RsContext)con);
+    return rsContextDestroy((RsContext)con);
+}
+
+
+static void
+nElementBegin(JNIEnv *_env, jobject _this)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nElementBegin, con(%p)", con);
+    rsElementBegin();
+}
+
+static void
+nElementAddPredefined(JNIEnv *_env, jobject _this, jint predef)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nElementAddPredefined, con(%p), predef(%i)", con, predef);
+    rsElementAddPredefined((RsElementPredefined)predef);
+}
+
+static void
+nElementAdd(JNIEnv *_env, jobject _this, jint kind, jint type, jint norm, jint bits)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nElementAdd, con(%p), kind(%i), type(%i), norm(%i), bits(%i)", con, kind, type, norm, bits);
+    rsElementAdd((RsDataKind)kind, (RsDataType)type, norm != 0, (size_t)bits);
+}
+
+static jint
+nElementCreate(JNIEnv *_env, jobject _this)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nElementCreate, con(%p)", con);
+    return (jint)rsElementCreate();
+}
+
+static jint
+nElementGetPredefined(JNIEnv *_env, jobject _this, jint predef)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nElementGetPredefined, con(%p) predef(%i)", con, predef);
+    return (jint)rsElementGetPredefined((RsElementPredefined)predef);
+}
+
+static void
+nElementDestroy(JNIEnv *_env, jobject _this, jint e)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nElementDestroy, con(%p) e(%p)", con, (RsElement)e);
+    rsElementDestroy((RsElement)e);
+}
+
+// -----------------------------------
+
+static void
+nTypeBegin(JNIEnv *_env, jobject _this, jint eID)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTypeBegin, con(%p) e(%p)", con, (RsElement)eID);
+    rsTypeBegin((RsElement)eID);
+}
+
+static void
+nTypeAdd(JNIEnv *_env, jobject _this, jint dim, jint val)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTypeAdd, con(%p) dim(%i), val(%i)", con, dim, val);
+    rsTypeAdd((RsDimension)dim, val);
+}
+
+static jint
+nTypeCreate(JNIEnv *_env, jobject _this)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTypeCreate, con(%p)", con);
+    return (jint)rsTypeCreate();
+}
+
+static void
+nTypeDestroy(JNIEnv *_env, jobject _this, jint eID)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTypeDestroy, con(%p), t(%p)", con, (RsType)eID);
+    rsTypeDestroy((RsType)eID);
+}
+
+// -----------------------------------
+
+static jint
+nAllocationCreateTyped(JNIEnv *_env, jobject _this, jint e)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAllocationCreateTyped, con(%p), e(%p)", con, (RsElement)e);
+    return (jint) rsAllocationCreateTyped((RsElement)e);
+}
+
+static jint
+nAllocationCreatePredefSized(JNIEnv *_env, jobject _this, jint predef, jint count)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAllocationCreatePredefSized, con(%p), predef(%i), count(%i)", con, predef, count);
+    return (jint) rsAllocationCreatePredefSized((RsElementPredefined)predef, count);
+}
+
+static jint
+nAllocationCreateSized(JNIEnv *_env, jobject _this, jint e, jint count)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAllocationCreateSized, con(%p), e(%p), count(%i)", con, (RsElement)e, count);
+    return (jint) rsAllocationCreateSized((RsElement)e, count);
+}
+
+static void
+nAllocationUploadToTexture(JNIEnv *_env, jobject _this, jint a, jint mip)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAllocationUploadToTexture, con(%p), a(%p), mip(%i)", con, (RsAllocation)a, mip);
+    rsAllocationUploadToTexture((RsAllocation)a, mip);
+}
+
+static void
+nAllocationDestroy(JNIEnv *_env, jobject _this, jint a)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAllocationDestroy, con(%p), a(%p)", con, (RsAllocation)a);
+    rsAllocationDestroy((RsAllocation)a);
+}
+
+static void
+nAllocationData_i(JNIEnv *_env, jobject _this, jint alloc, jintArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
+    jint *ptr = _env->GetIntArrayElements(data, NULL);
+    rsAllocationData((RsAllocation)alloc, ptr);
+    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
+nAllocationData_f(JNIEnv *_env, jobject _this, jint alloc, jfloatArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
+    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
+    rsAllocationData((RsAllocation)alloc, ptr);
+    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
+nAllocationSubData1D_i(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jintArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len);
+    jint *ptr = _env->GetIntArrayElements(data, NULL);
+    rsAllocation1DSubData((RsAllocation)alloc, offset, count, ptr);
+    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
+nAllocationSubData1D_f(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jfloatArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len);
+    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
+    rsAllocation1DSubData((RsAllocation)alloc, offset, count, ptr);
+    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
+nAllocationSubData2D_i(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jintArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocation2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
+    jint *ptr = _env->GetIntArrayElements(data, NULL);
+    rsAllocation2DSubData((RsAllocation)alloc, xoff, yoff, w, h, ptr);
+    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
+nAllocationSubData2D_f(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jfloatArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocation2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
+    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
+    rsAllocation2DSubData((RsAllocation)alloc, xoff, yoff, w, h, ptr);
+    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
+}
+
+
+
+// -----------------------------------
+
+static void
+nTriangleMeshDestroy(JNIEnv *_env, jobject _this, jint tm)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTriangleMeshDestroy, con(%p), tm(%p)", con, (RsAllocation)tm);
+    rsTriangleMeshDestroy((RsTriangleMesh)tm);
+}
+
+static void
+nTriangleMeshBegin(JNIEnv *_env, jobject _this, jint v, jint i)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTriangleMeshBegin, con(%p), vertex(%p), index(%p)", con, (RsElement)v, (RsElement)i);
+    rsTriangleMeshBegin((RsElement)v, (RsElement)i);
+}
+
+static void
+nTriangleMeshAddVertex_XY(JNIEnv *_env, jobject _this, jfloat x, jfloat y)
+{
+    float v[] = {x, y};
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTriangleMeshAddVertex_XY, con(%p), x(%f), y(%f)", con, x, y);
+    rsTriangleMeshAddVertex(v);
+}
+
+static void
+nTriangleMeshAddVertex_XYZ(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z)
+{
+    float v[] = {x, y, z};
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTriangleMeshAddVertex_XYZ, con(%p), x(%f), y(%f), z(%f)", con, x, y, z);
+    rsTriangleMeshAddVertex(v);
+}
+
+static void
+nTriangleMeshAddVertex_XY_ST(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat s, jfloat t)
+{
+    float v[] = {s, t, x, y};
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTriangleMeshAddVertex_XY_ST, con(%p), x(%f), y(%f), s(%f), t(%f)", con, x, y, s, t);
+    rsTriangleMeshAddVertex(v);
+}
+
+static void
+nTriangleMeshAddVertex_XYZ_ST(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z, jfloat s, jfloat t)
+{
+    float v[] = {s, t, x, y, z};
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t);
+    rsTriangleMeshAddVertex(v);
+}
+
+static void
+nTriangleMeshAddTriangle(JNIEnv *_env, jobject _this, jint i1, jint i2, jint i3)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTriangleMeshAddTriangle, con(%p), i1(%i), i2(%i), i3(%i)", con, i1, i2, i3);
+    rsTriangleMeshAddTriangle(i1, i2, i3);
+}
+
+static jint
+nTriangleMeshCreate(JNIEnv *_env, jobject _this)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTriangleMeshCreate, con(%p)", con);
+    return (jint) rsTriangleMeshCreate();
+}
+
+// -----------------------------------
+
+static void
+nAdapter1DDestroy(JNIEnv *_env, jobject _this, jint adapter)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAdapter1DDestroy, con(%p), adapter(%p)", con, (RsAdapter1D)adapter);
+    rsAdapter1DDestroy((RsAdapter1D)adapter);
+}
+
+static void
+nAdapter1DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAdapter1DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter1D)adapter, (RsAllocation)alloc);
+    rsAdapter1DBindAllocation((RsAdapter1D)adapter, (RsAllocation)alloc);
+}
+
+static void
+nAdapter1DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAdapter1DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter1D)adapter, dim, value);
+    rsAdapter1DSetConstraint((RsAdapter1D)adapter, (RsDimension)dim, value);
+}
+
+static void
+nAdapter1DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAdapter1DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len);
+    jint *ptr = _env->GetIntArrayElements(data, NULL);
+    rsAdapter1DData((RsAdapter1D)adapter, ptr);
+    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
+}
+
+static void
+nAdapter1DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jintArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAdapter1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len);
+    jint *ptr = _env->GetIntArrayElements(data, NULL);
+    rsAdapter1DSubData((RsAdapter1D)adapter, offset, count, ptr);
+    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
+}
+
+static void
+nAdapter1DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAdapter1DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len);
+    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
+    rsAdapter1DData((RsAdapter1D)adapter, ptr);
+    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
+}
+
+static void
+nAdapter1DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jfloatArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAdapter1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len);
+    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
+    rsAdapter1DSubData((RsAdapter1D)adapter, offset, count, ptr);
+    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
+}
+
+static jint
+nAdapter1DCreate(JNIEnv *_env, jobject _this)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAdapter1DCreate, con(%p)", con);
+    return (jint)rsAdapter1DCreate();
+}
+
+// -----------------------------------
+
+static void
+nScriptDestroy(JNIEnv *_env, jobject _this, jint script)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptDestroy, con(%p), script(%p)", con, (RsScript)script);
+    rsScriptDestroy((RsScript)script);
+}
+
+static void
+nScriptBindAllocation(JNIEnv *_env, jobject _this, jint script, jint alloc, jint slot)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot);
+    rsScriptBindAllocation((RsScript)script, (RsAllocation)alloc, slot);
+}
+
+static void
+nScriptCBegin(JNIEnv *_env, jobject _this)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptCBegin, con(%p)", con);
+    rsScriptCBegin();
+}
+
+static void
+nScriptCSetClearColor(JNIEnv *_env, jobject _this, jfloat r, jfloat g, jfloat b, jfloat a)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptCSetClearColor, con(%p), r(%f), g(%f), b(%f), a(%f)", con, r, g, b, a);
+    rsScriptCSetClearColor(r, g, b, a);
+}
+
+static void
+nScriptCSetClearDepth(JNIEnv *_env, jobject _this, jfloat d)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptCSetClearColor, con(%p), depth(%f)", con, d);
+    rsScriptCSetClearDepth(d);
+}
+
+static void
+nScriptCSetClearStencil(JNIEnv *_env, jobject _this, jint stencil)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptCSetClearStencil, con(%p), stencil(%i)", con, stencil);
+    rsScriptCSetClearStencil(stencil);
+}
+
+static void
+nScriptCAddType(JNIEnv *_env, jobject _this, jint type)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptCAddType, con(%p), type(%p)", con, (RsType)type);
+    rsScriptCAddType((RsType)type);
+}
+
+static void
+nScriptCSetRoot(JNIEnv *_env, jobject _this, jboolean isRoot)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptCSetRoot, con(%p), isRoot(%i)", con, isRoot);
+    rsScriptCSetRoot(isRoot);
+}
+
+static void
+nScriptCSetScript(JNIEnv *_env, jobject _this, jboolean isRoot)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("!!! nScriptCSetScript, con(%p)", con);
+    //nScriptCSetScript(isRoot);
+    rsScriptCSetScript((void *)test_script);
+}
+
+static jint
+nScriptCCreate(JNIEnv *_env, jobject _this)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptCCreate, con(%p)", con);
+    return (jint)rsScriptCCreate();
+}
+
+// ---------------------------------------------------------------------------
+
+static void
+nProgramFragmentStoreBegin(JNIEnv *_env, jobject _this, jint in, jint out)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
+    rsProgramFragmentStoreBegin((RsElement)in, (RsElement)out);
+}
+
+static void
+nProgramFragmentStoreDepthFunc(JNIEnv *_env, jobject _this, jint func)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentStoreDepthFunc, con(%p), func(%i)", con, func);
+    rsProgramFragmentStoreDepthFunc((RsDepthFunc)func);
+}
+
+static void
+nProgramFragmentStoreDepthMask(JNIEnv *_env, jobject _this, jboolean enable)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentStoreDepthMask, con(%p), enable(%i)", con, enable);
+    rsProgramFragmentStoreDepthMask(enable);
+}
+
+static void
+nProgramFragmentStoreColorMask(JNIEnv *_env, jobject _this, jboolean r, jboolean g, jboolean b, jboolean a)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a);
+    rsProgramFragmentStoreColorMask(r, g, b, a);
+}
+
+static void
+nProgramFragmentStoreBlendFunc(JNIEnv *_env, jobject _this, int src, int dst)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst);
+    rsProgramFragmentStoreBlendFunc((RsBlendSrcFunc)src, (RsBlendDstFunc)dst);
+}
+
+static void
+nProgramFragmentStoreDither(JNIEnv *_env, jobject _this, jboolean enable)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentStoreDither, con(%p), enable(%i)", con, enable);
+    rsProgramFragmentStoreDither(enable);
+}
+
+static jint
+nProgramFragmentStoreCreate(JNIEnv *_env, jobject _this)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentStoreCreate, con(%p)", con);
+    return (jint)rsProgramFragmentStoreCreate();
+}
+
+// ---------------------------------------------------------------------------
+
+static void
+nProgramFragmentBegin(JNIEnv *_env, jobject _this, jint in, jint out)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
+    rsProgramFragmentBegin((RsElement)in, (RsElement)out);
+}
+
+static void
+nProgramFragmentBindTexture(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
+    rsProgramFragmentBindTexture((RsProgramFragment)vpf, slot, (RsAllocation)a);
+}
+
+static void
+nProgramFragmentBindSampler(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a);
+    rsProgramFragmentBindSampler((RsProgramFragment)vpf, slot, (RsSampler)a);
+}
+
+static void
+nProgramFragmentSetType(JNIEnv *_env, jobject _this, jint slot, jint vt)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentSetType, con(%p), slot(%i), vt(%p)", con, slot, (RsType)vt);
+    rsProgramFragmentSetType(slot, (RsType)vt);
+}
+
+static void
+nProgramFragmentSetEnvMode(JNIEnv *_env, jobject _this, jint slot, jint env)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentSetEnvMode, con(%p), slot(%i), vt(%i)", con, slot, env);
+    rsProgramFragmentSetEnvMode(slot, (RsTexEnvMode)env);
+}
+
+static void
+nProgramFragmentSetTexEnable(JNIEnv *_env, jobject _this, jint slot, jboolean enable)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentSetTexEnable, con(%p), slot(%i), enable(%i)", con, slot, enable);
+    rsProgramFragmentSetTexEnable(slot, enable);
+}
+
+static jint
+nProgramFragmentCreate(JNIEnv *_env, jobject _this, jint slot, jboolean enable)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramFragmentCreate, con(%p)", con);
+    return (jint)rsProgramFragmentCreate();
+}
+
+
+// ---------------------------------------------------------------------------
+
+static void
+nContextBindRootScript(JNIEnv *_env, jobject _this, jint script)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script);
+    rsContextBindRootScript((RsScript)script);
+}
+
+static void
+nContextBindSampler(JNIEnv *_env, jobject _this, jint sampler, jint slot)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nContextBindSampler, con(%p), sampler(%p), slot(%i)", con, (RsSampler)sampler, slot);
+    rsContextBindSampler(slot, (RsSampler)sampler);
+}
+
+static void
+nContextBindProgramFragmentStore(JNIEnv *_env, jobject _this, jint pfs)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nContextBindProgramFragmentStore, con(%p), pfs(%p)", con, (RsProgramFragmentStore)pfs);
+    rsContextBindProgramFragmentStore((RsProgramFragmentStore)pfs);
+}
+
+static void
+nContextBindProgramFragment(JNIEnv *_env, jobject _this, jint pf)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf);
+    rsContextBindProgramFragment((RsProgramFragment)pf);
+}
+
+
+// ---------------------------------------------------------------------------
+
+
+static const char *classPathName = "com/android/calc/RenderScript";
+
+static JNINativeMethod methods[] = {
+{"_nInit",                         "()V",                                  (void*)_nInit },
+{"nDeviceCreate",                  "()I",                                  (void*)nDeviceCreate },
+{"nDeviceDestroy",                 "(I)V",                                 (void*)nDeviceDestroy },
+{"nContextCreate",                 "(ILandroid/view/Surface;I)I",          (void*)nContextCreate },
+{"nContextDestroy",                "(I)V",                                 (void*)nContextDestroy },
+
+{"nElementBegin",                  "()V",                                  (void*)nElementBegin },
+{"nElementAddPredefined",          "(I)V",                                 (void*)nElementAddPredefined },
+{"nElementAdd",                    "(IIII)V",                              (void*)nElementAdd },
+{"nElementCreate",                 "()I",                                  (void*)nElementCreate },
+{"nElementGetPredefined",          "(I)I",                                 (void*)nElementGetPredefined },
+{"nElementDestroy",                "(I)V",                                 (void*)nElementDestroy },
+
+{"nTypeBegin",                     "(I)V",                                 (void*)nTypeBegin },
+{"nTypeAdd",                       "(II)V",                                (void*)nTypeAdd },
+{"nTypeCreate",                    "()I",                                  (void*)nTypeCreate },
+{"nTypeDestroy",                   "(I)V",                                 (void*)nTypeDestroy },
+
+{"nAllocationCreateTyped",         "(I)I",                                 (void*)nAllocationCreateTyped },
+{"nAllocationCreatePredefSized",   "(II)I",                                (void*)nAllocationCreatePredefSized },
+{"nAllocationCreateSized",         "(II)I",                                (void*)nAllocationCreateSized },
+//{"nAllocationCreateFromBitmap",    "(I)V",                                 (void*)nAllocationCreateFromBitmap },
+{"nAllocationUploadToTexture",     "(II)V",                                (void*)nAllocationUploadToTexture },
+{"nAllocationDestroy",             "(I)V",                                 (void*)nAllocationDestroy },
+{"nAllocationData",                "(I[I)V",                               (void*)nAllocationData_i },
+{"nAllocationData",                "(I[F)V",                               (void*)nAllocationData_f },
+{"nAllocationSubData1D",           "(III[I)V",                             (void*)nAllocationSubData1D_i },
+{"nAllocationSubData1D",           "(III[F)V",                             (void*)nAllocationSubData1D_f },
+{"nAllocationSubData2D",           "(IIIII[I)V",                           (void*)nAllocationSubData2D_i },
+{"nAllocationSubData2D",           "(IIIII[F)V",                           (void*)nAllocationSubData2D_f },
+
+{"nTriangleMeshDestroy",           "(I)V",                                 (void*)nTriangleMeshDestroy },
+{"nTriangleMeshBegin",             "(II)V",                                (void*)nTriangleMeshBegin },
+{"nTriangleMeshAddVertex_XY",      "(FF)V",                                (void*)nTriangleMeshAddVertex_XY },
+{"nTriangleMeshAddVertex_XYZ",     "(FFF)V",                               (void*)nTriangleMeshAddVertex_XYZ },
+{"nTriangleMeshAddVertex_XY_ST",   "(FFFF)V",                              (void*)nTriangleMeshAddVertex_XY_ST },
+{"nTriangleMeshAddVertex_XYZ_ST",  "(FFFFF)V",                             (void*)nTriangleMeshAddVertex_XYZ_ST },
+{"nTriangleMeshAddTriangle",       "(III)V",                               (void*)nTriangleMeshAddTriangle },
+{"nTriangleMeshCreate",            "()I",                                  (void*)nTriangleMeshCreate },
+
+{"nAdapter1DDestroy",              "(I)V",                                 (void*)nAdapter1DDestroy },
+{"nAdapter1DBindAllocation",       "(II)V",                                (void*)nAdapter1DBindAllocation },
+{"nAdapter1DSetConstraint",        "(III)V",                               (void*)nAdapter1DSetConstraint },
+{"nAdapter1DData",                 "(I[I)V",                               (void*)nAdapter1DData_i },
+{"nAdapter1DSubData",              "(III[I)V",                             (void*)nAdapter1DSubData_i },
+{"nAdapter1DData",                 "(I[F)V",                               (void*)nAdapter1DData_f },
+{"nAdapter1DSubData",              "(III[F)V",                             (void*)nAdapter1DSubData_f },
+{"nAdapter1DCreate",               "()I",                                  (void*)nAdapter1DCreate },
+
+{"nScriptDestroy",                 "(I)V",                                 (void*)nScriptDestroy },
+{"nScriptBindAllocation",          "(III)V",                               (void*)nScriptBindAllocation },
+{"nScriptCBegin",                  "()V",                                  (void*)nScriptCBegin },
+{"nScriptCSetClearColor",          "(FFFF)V",                              (void*)nScriptCSetClearColor },
+{"nScriptCSetClearDepth",          "(F)V",                                 (void*)nScriptCSetClearDepth },
+{"nScriptCSetClearStencil",        "(I)V",                                 (void*)nScriptCSetClearStencil },
+{"nScriptCAddType",                "(I)V",                                 (void*)nScriptCAddType },
+{"nScriptCSetRoot",                "(Z)V",                                 (void*)nScriptCSetRoot },
+{"nScriptCSetScript",              "(Ljava/lang/String;)V",                (void*)nScriptCSetScript },
+{"nScriptCCreate",                 "()I",                                  (void*)nScriptCCreate },
+
+{"nProgramFragmentStoreBegin",     "(II)V",                                (void*)nProgramFragmentStoreBegin },
+{"nProgramFragmentStoreDepthFunc", "(I)V",                                 (void*)nProgramFragmentStoreDepthFunc },
+{"nProgramFragmentStoreDepthMask", "(Z)V",                                 (void*)nProgramFragmentStoreDepthMask },
+{"nProgramFragmentStoreColorMask", "(ZZZZ)V",                              (void*)nProgramFragmentStoreColorMask },
+{"nProgramFragmentStoreBlendFunc", "(II)V",                                (void*)nProgramFragmentStoreBlendFunc },
+{"nProgramFragmentStoreDither",    "(Z)V",                                 (void*)nProgramFragmentStoreDither },
+{"nProgramFragmentStoreCreate",    "()I",                                  (void*)nProgramFragmentStoreCreate },
+
+{"nProgramFragmentBegin",          "(II)V",                                (void*)nProgramFragmentBegin },
+{"nProgramFragmentBindTexture",    "(III)V",                               (void*)nProgramFragmentBindTexture },
+{"nProgramFragmentBindSampler",    "(III)V",                               (void*)nProgramFragmentBindSampler },
+{"nProgramFragmentSetType",        "(II)V",                                (void*)nProgramFragmentSetType },
+{"nProgramFragmentSetEnvMode",     "(II)V",                                (void*)nProgramFragmentSetEnvMode },
+{"nProgramFragmentSetTexEnable",   "(IZ)V",                                (void*)nProgramFragmentSetTexEnable },
+{"nProgramFragmentCreate",         "()I",                                  (void*)nProgramFragmentCreate },
+
+{"nContextBindRootScript",         "(I)V",                                 (void*)nContextBindRootScript },
+//{"nContextBindSampler",          "(II)V",                                (void*)nContextBindSampler },
+{"nContextBindProgramFragmentStore","(I)V",                                (void*)nContextBindProgramFragmentStore },
+{"nContextBindProgramFragment",    "(I)V",                                 (void*)nContextBindProgramFragment },
+
+};
+
+static int registerFuncs(JNIEnv *_env)
+{
+    return android::AndroidRuntime::registerNativeMethods(
+            _env, classPathName, methods, NELEM(methods));
+}
+
+// ---------------------------------------------------------------------------
+
+jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+    JNIEnv* env = NULL;
+    jint result = -1;
+
+    LOGE("****************************************************\n");
+
+    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        LOGE("ERROR: GetEnv failed\n");
+        goto bail;
+    }
+    assert(env != NULL);
+
+    if (registerFuncs(env) < 0) {
+        LOGE("ERROR: MediaPlayer native registration failed\n");
+        goto bail;
+    }
+
+    /* success -- return valid version number */
+    result = JNI_VERSION_1_4;
+
+bail:
+    return result;
+}
diff --git a/rs.spec b/rs.spec
new file mode 100644
index 0000000..6168bd7
--- /dev/null
+++ b/rs.spec
@@ -0,0 +1,392 @@
+
+
+ContextBindSampler {
+	param uint32_t slot
+	param RsSampler sampler
+	}
+
+ContextBindRootScript {
+	param RsScript sampler
+	}
+
+ContextBindProgramFragmentStore {
+	param RsProgramFragmentStore pgm
+	}
+
+ContextBindProgramFragment {
+	param RsProgramFragment pgm
+	}
+
+ContextBindProgramVertex {
+	param RsProgramVertex pgm
+	}
+
+
+ElementBegin {
+}
+
+ElementAddPredefined {
+	param RsElementPredefined predef
+	}
+
+ElementAdd {
+	param RsDataKind dataKind
+	param RsDataType dataType
+	param bool isNormalized
+	param size_t bits
+	}
+
+ElementCreate {
+	ret RsElement
+	}
+
+ElementGetPredefined {
+	param RsElementPredefined predef
+	ret RsElement
+	}
+
+ElementDestroy {
+	param RsElement ve
+	}
+
+TypeBegin {
+	param RsElement type
+	}
+
+TypeAdd {
+	param RsDimension dim
+	param size_t value
+	}
+
+TypeCreate {
+	ret RsType
+	}
+
+TypeDestroy {
+	param RsType p
+	}
+
+AllocationCreateTyped {
+	param RsType type
+	ret RsAllocation
+	}
+
+AllocationCreatePredefSized {
+	param RsElementPredefined predef
+	param size_t count
+	ret RsAllocation
+	}
+
+AllocationCreateSized {
+	param RsElement e
+	param size_t count
+	ret RsAllocation
+	}
+
+AllocationCreateFromBitmap {
+	param const char *file
+	param bool genMips
+	ret RsAllocation
+	}
+
+AllocationUploadToTexture {
+	param RsAllocation alloc
+	param uint32_t baseMipLevel
+	}
+
+AllocationUploadToBufferObject {
+	param RsAllocation alloc
+	}
+
+AllocationDestroy {
+	param RsAllocation alloc
+	}
+
+
+AllocationData {
+	param RsAllocation va
+	param const void * data
+	} 
+
+Allocation1DSubData {
+	param RsAllocation va
+	param uint32_t xoff
+	param uint32_t count
+	param const void *data
+	} 
+
+Allocation2DSubData {
+	param RsAllocation va
+	param uint32_t xoff
+	param uint32_t yoff
+	param uint32_t w
+	param uint32_t h
+	param const void *data
+	}
+
+
+Adapter1DCreate {
+	ret RsAdapter1D
+	}
+
+Adapter1DBindAllocation {
+	param RsAdapter1D adapt
+	param RsAllocation alloc
+	}
+
+Adapter1DDestroy {
+	param RsAdapter1D adapter
+	}
+
+Adapter1DSetConstraint {
+	param RsAdapter1D adapter
+	param RsDimension dim
+	param uint32_t value
+	}
+
+Adapter1DData {
+	param RsAdapter1D adapter
+	param const void * data
+	} 
+
+Adapter1DSubData {
+	param RsAdapter1D adapter
+	param uint32_t xoff
+	param uint32_t count
+	param const void *data
+	} 
+
+Adapter2DCreate {
+	ret RsAdapter2D
+	}
+
+Adapter2DBindAllocation {
+	param RsAdapter2D adapt
+	param RsAllocation alloc
+	}
+
+Adapter2DDestroy {
+	param RsAdapter2D adapter
+	}
+
+Adapter2DSetConstraint {
+	param RsAdapter2D adapter
+	param RsDimension dim
+	param uint32_t value
+	}
+
+Adapter2DData {
+	param RsAdapter2D adapter
+	param const void *data
+	} 
+
+Adapter2DSubData {
+	param RsAdapter2D adapter
+	param uint32_t xoff
+	param uint32_t yoff
+	param uint32_t w
+	param uint32_t h
+	param const void *data
+	}
+
+SamplerBegin {
+	}
+
+SamplerSet {
+	param RsSamplerParam p
+	param RsSamplerValue value
+	}
+
+SamplerCreate {
+	ret RsSampler
+	}
+
+
+TriangleMeshBegin {
+	param RsElement vertex
+	param RsElement index
+	}
+
+TriangleMeshAddVertex {
+	param const void *vtx
+	}
+
+TriangleMeshAddTriangle {
+	param uint32_t idx1
+	param uint32_t idx2
+	param uint32_t idx3
+	}
+
+TriangleMeshCreate {
+	ret RsTriangleMesh
+	}
+
+TriangleMeshDestroy {
+	param RsTriangleMesh mesh
+	}
+
+TriangleMeshRender {
+	param RsTriangleMesh vtm
+	}
+
+TriangleMeshRenderRange {
+	param RsTriangleMesh vtm
+	param uint32_t start
+	param uint32_t count
+	}
+
+ScriptDestroy {
+	param RsScript script
+	}
+
+ScriptBindAllocation {
+	param RsScript vtm
+	param RsAllocation va
+	param uint32_t slot
+	}
+
+
+ScriptCBegin {
+	}
+
+ScriptCSetClearColor {
+	param float r
+	param float g
+	param float b
+	param float a
+	}
+
+ScriptCSetClearDepth {
+	param float depth
+	}
+
+ScriptCSetClearStencil {
+	param uint32_t stencil
+	}
+
+ScriptCAddType {
+	param RsType type
+	}
+
+ScriptCSetRoot {
+	param bool isRoot
+	}
+
+ScriptCSetOrtho {
+	param bool isOrtho
+	}
+
+ScriptCSetScript {
+	param void * ptr
+	}
+
+ScriptCCreate {
+	ret RsScript
+	}
+
+
+ProgramFragmentStoreBegin {
+	param RsElement in
+	param RsElement out
+	}
+
+ProgramFragmentStoreColorMask {
+	param bool r
+	param bool g
+	param bool b
+	param bool a
+	}
+
+ProgramFragmentStoreBlendFunc {
+	param RsBlendSrcFunc srcFunc
+	param RsBlendDstFunc destFunc
+	}
+
+ProgramFragmentStoreDepthMask {
+	param bool enable
+}
+
+ProgramFragmentStoreDither {
+	param bool enable
+}
+
+ProgramFragmentStoreDepthFunc {
+	param RsDepthFunc func
+}
+
+ProgramFragmentStoreCreate {
+	ret RsProgramFragmentStore
+	}
+
+
+
+ProgramFragmentBegin {
+	param RsElement in
+	param RsElement out
+	}
+
+ProgramFragmentBindTexture {
+	param RsProgramFragment pf
+	param uint32_t slot
+	param RsAllocation a
+	}
+
+ProgramFragmentBindSampler {
+	param RsProgramFragment pf
+	param uint32_t slot
+	param RsSampler s
+	}
+
+ProgramFragmentSetType {
+	param uint32_t slot
+	param RsType t
+	}
+
+ProgramFragmentSetEnvMode {
+	param uint32_t slot
+	param RsTexEnvMode env
+	}
+
+ProgramFragmentSetTexEnable {
+	param uint32_t slot
+	param bool enable
+	}
+
+ProgramFragmentCreate {
+	ret RsProgramFragment
+	}
+
+
+
+ProgramVertexBegin {
+	param RsElement in
+	param RsElement out
+	}
+
+ProgramVertexCreate {
+	ret RsProgramVertex
+	}
+
+ProgramVertexBindAllocation {
+	param RsProgramVertex vpgm
+	param uint32_t slot
+	param RsAllocation constants
+	}
+
+ProgramVertexSetType {
+	param uint32_t slot
+	param RsType constants
+	}
+
+ProgramVertexSetCameraMode {
+	param bool ortho
+	}
+
+ProgramVertexSetTextureMatrixEnable {
+	param bool enable
+	}
+
+ProgramVertexSetModelMatrixEnable {
+	param bool enable
+	}
+
diff --git a/rsAdapter.cpp b/rsAdapter.cpp
new file mode 100644
index 0000000..7ac2aed
--- /dev/null
+++ b/rsAdapter.cpp
@@ -0,0 +1,245 @@
+
+/*
+ * 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"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+Adapter1D::Adapter1D()
+{
+    reset();
+}
+
+Adapter1D::Adapter1D(Allocation *a)
+{
+    reset();
+    setAllocation(a);
+}
+
+void Adapter1D::reset()
+{
+    mY = 0;
+    mZ = 0;
+    mLOD = 0;
+    mFace = 0;
+}
+
+void * Adapter1D::getElement(uint32_t x)
+{
+    rsAssert(mAllocation.get());
+    rsAssert(mAllocation->getPtr());
+    rsAssert(mAllocation->getType());
+    uint8_t * ptr = static_cast<uint8_t *>(mAllocation->getPtr());
+    ptr += mAllocation->getType()->getLODOffset(mLOD, x, mY);
+    return ptr;
+}
+
+void Adapter1D::subData(uint32_t xoff, uint32_t count, const void *data)
+{
+    if (mAllocation.get() && mAllocation.get()->getType()) {
+        void *ptr = getElement(xoff);
+        count *= mAllocation.get()->getType()->getElementSizeBytes();
+        memcpy(ptr, data, count);
+    }
+}
+
+void Adapter1D::data(const void *data)
+{
+    memcpy(getElement(0), 
+           data, 
+           mAllocation.get()->getType()->getSizeBytes());
+}
+
+namespace android {
+namespace renderscript {
+
+RsAdapter1D rsi_Adapter1DCreate(Context *rsc)
+{
+    return new Adapter1D();
+}
+
+void rsi_Adapter1DDestroy(Context *rsc, RsAdapter1D va)
+{
+    Adapter1D * a = static_cast<Adapter1D *>(va);
+    a->decRef();
+}
+
+void rsi_Adapter1DBindAllocation(Context *rsc, RsAdapter1D va, RsAllocation valloc)
+{
+    Adapter1D * a = static_cast<Adapter1D *>(va);
+    Allocation * alloc = static_cast<Allocation *>(valloc);
+    a->setAllocation(alloc);
+}
+
+void rsi_Adapter1DSetConstraint(Context *rsc, RsAdapter1D va, RsDimension dim, uint32_t value)
+{
+    Adapter1D * a = static_cast<Adapter1D *>(va);
+    switch(dim) {
+    case RS_DIMENSION_X:
+        rsAssert(!"Cannot contrain X in an 1D adapter");
+        return;
+    case RS_DIMENSION_Y:
+        a->setY(value);
+        break;
+    case RS_DIMENSION_Z:
+        a->setZ(value);
+        break;
+    case RS_DIMENSION_LOD:
+        a->setLOD(value);
+        break;
+    case RS_DIMENSION_FACE:
+        a->setFace(value);
+        break;
+    default:
+        rsAssert(!"Unimplemented constraint");
+        return;
+    }
+}
+
+void rsi_Adapter1DSubData(Context *rsc, RsAdapter1D va, uint32_t xoff, uint32_t count, const void *data)
+{
+    Adapter1D * a = static_cast<Adapter1D *>(va);
+    a->subData(xoff, count, data);
+}
+
+void rsi_Adapter1DData(Context *rsc, RsAdapter1D va, const void *data)
+{
+    Adapter1D * a = static_cast<Adapter1D *>(va);
+    a->data(data);
+}
+
+}
+}
+
+//////////////////////////
+
+Adapter2D::Adapter2D()
+{
+    reset();
+}
+
+Adapter2D::Adapter2D(Allocation *a)
+{
+    reset();
+    setAllocation(a);
+}
+
+void Adapter2D::reset()
+{
+    mZ = 0;
+    mLOD = 0;
+    mFace = 0;
+}
+
+void * Adapter2D::getElement(uint32_t x, uint32_t y) const
+{
+    rsAssert(mAllocation.get());
+    rsAssert(mAllocation->getPtr());
+    rsAssert(mAllocation->getType());
+    uint8_t * ptr = static_cast<uint8_t *>(mAllocation->getPtr());
+    ptr += mAllocation->getType()->getLODOffset(mLOD, x, y);
+    return ptr;
+}
+
+void Adapter2D::subData(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data)
+{
+    rsAssert(mAllocation.get());
+    rsAssert(mAllocation->getPtr());
+    rsAssert(mAllocation->getType());
+
+    uint32_t eSize = mAllocation.get()->getType()->getElementSizeBytes();
+    uint32_t lineSize = eSize * w;
+    uint32_t destW = getDimX();
+
+    const uint8_t *src = static_cast<const uint8_t *>(data);
+    for (uint32_t line=yoff; line < (yoff+h); line++) {
+        memcpy(getElement(xoff, line), src, lineSize);
+        src += lineSize;
+    }
+}
+
+void Adapter2D::data(const void *data)
+{
+    memcpy(getElement(0,0), 
+           data, 
+           mAllocation.get()->getType()->getSizeBytes());
+}
+
+
+
+namespace android {
+namespace renderscript {
+
+RsAdapter2D rsi_Adapter2DCreate(Context *rsc)
+{
+    return new Adapter2D();
+}
+
+void rsi_Adapter2DDestroy(Context *rsc, RsAdapter2D va)
+{
+    Adapter2D * a = static_cast<Adapter2D *>(va);
+    a->decRef();
+}
+
+void rsi_Adapter2DBindAllocation(Context *rsc, RsAdapter2D va, RsAllocation valloc)
+{
+    Adapter2D * a = static_cast<Adapter2D *>(va);
+    Allocation * alloc = static_cast<Allocation *>(valloc);
+    a->setAllocation(alloc);
+}
+
+void rsi_Adapter2DSetConstraint(Context *rsc, RsAdapter2D va, RsDimension dim, uint32_t value)
+{
+    Adapter2D * a = static_cast<Adapter2D *>(va);
+    switch(dim) {
+    case RS_DIMENSION_X:
+        rsAssert(!"Cannot contrain X in an 2D adapter");
+        return;
+    case RS_DIMENSION_Y:
+        rsAssert(!"Cannot contrain Y in an 2D adapter");
+        break;
+    case RS_DIMENSION_Z:
+        a->setZ(value);
+        break;
+    case RS_DIMENSION_LOD:
+        a->setLOD(value);
+        break;
+    case RS_DIMENSION_FACE:
+        a->setFace(value);
+        break;
+    default:
+        rsAssert(!"Unimplemented constraint");
+        return;
+    }
+}
+
+void rsi_Adapter2DData(Context *rsc, RsAdapter2D va, const void *data)
+{
+    Adapter2D * a = static_cast<Adapter2D *>(va);
+    a->data(data);
+}
+
+void rsi_Adapter2DSubData(Context *rsc, RsAdapter2D va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data)
+{
+    Adapter2D * a = static_cast<Adapter2D *>(va);
+    a->subData(xoff, yoff, w, h, data);
+}
+
+}
+}
diff --git a/rsAdapter.h b/rsAdapter.h
new file mode 100644
index 0000000..865535e
--- /dev/null
+++ b/rsAdapter.h
@@ -0,0 +1,96 @@
+/*
+ * 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_ADAPTER_H
+#define ANDROID_RS_ADAPTER_H
+
+#include "rsAllocation.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+    
+class Adapter1D : public ObjectBase
+{
+
+public:
+    // By policy this allocation will hold a pointer to the type
+    // but will not destroy it on destruction.
+    Adapter1D();
+    Adapter1D(Allocation *);
+    void reset();
+    void * getElement(uint32_t x);
+
+    void setAllocation(Allocation *a) {mAllocation.set(a);}
+
+    uint32_t getDimX() const {return mAllocation->getType()->getLODDimX(mLOD);}
+
+    const Type * getBaseType() const {return mAllocation->getType();}
+
+    inline void setY(uint32_t y) {mY = y;}
+    inline void setZ(uint32_t z) {mZ = z;}
+    inline void setLOD(uint32_t lod) {mLOD = lod;}
+    inline void setFace(uint32_t face) {mFace = face;}
+    //void setArray(uint32_t num, uint32_t value);
+
+    void subData(uint32_t xoff, uint32_t count, const void *data);
+    void data(const void *data);
+
+protected:
+    ObjectBaseRef<Allocation> mAllocation;
+    uint32_t mY;
+    uint32_t mZ;
+    uint32_t mLOD;
+    uint32_t mFace;
+};
+
+class Adapter2D : public ObjectBase
+{
+
+public:
+    // By policy this allocation will hold a pointer to the type
+    // but will not destroy it on destruction.
+    Adapter2D();
+    Adapter2D(Allocation *);
+    void reset();
+    void * getElement(uint32_t x, uint32_t y) const;
+
+    uint32_t getDimX() const {return mAllocation->getType()->getLODDimX(mLOD);}
+    uint32_t getDimY() const {return mAllocation->getType()->getLODDimY(mLOD);}
+    const Type * getBaseType() const {return mAllocation->getType();}
+
+    void setAllocation(Allocation *a) {mAllocation.set(a);}
+    inline void setZ(uint32_t z) {mZ = z;}
+    inline void setLOD(uint32_t lod) {mLOD = lod;}
+    inline void setFace(uint32_t face) {mFace = face;}
+    //void setArray(uint32_t num, uint32_t value);
+
+    void data(const void *data); 
+    void subData(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data); 
+
+protected:
+    ObjectBaseRef<Allocation> mAllocation;
+    uint32_t mZ;
+    uint32_t mLOD;
+    uint32_t mFace;
+};
+
+
+}
+}
+#endif
+
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
new file mode 100644
index 0000000..f3f2e46
--- /dev/null
+++ b/rsAllocation.cpp
@@ -0,0 +1,325 @@
+/*
+ * 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"
+
+using namespace android;
+using namespace android::renderscript;
+
+Allocation::Allocation(const Type *type)
+{
+    mPtr = NULL;
+
+    mCpuWrite = false;
+    mCpuRead = false;
+    mGpuWrite = false;
+    mGpuRead = false;
+
+    mReadWriteRatio = 0;
+    mUpdateSize = 0;
+
+    mIsTexture = false;
+    mTextureID = 0;
+
+    mIsVertexBuffer = false;
+    mBufferID = 0;
+
+    mType.set(type);
+    mPtr = malloc(mType->getSizeBytes());
+    if (!mPtr) {
+        LOGE("Allocation::Allocation, alloc failure");
+    }
+
+}
+
+Allocation::~Allocation()
+{
+}
+
+void Allocation::setCpuWritable(bool)
+{
+}
+
+void Allocation::setGpuWritable(bool)
+{
+}
+
+void Allocation::setCpuReadable(bool)
+{
+}
+
+void Allocation::setGpuReadable(bool)
+{
+}
+
+bool Allocation::fixAllocation()
+{
+    return false;
+}
+
+void Allocation::uploadToTexture(uint32_t lodOffset)
+{
+    //rsAssert(!mTextureId);
+    rsAssert(lodOffset < mType->getLODCount());
+
+    //LOGE("uploadToTexture  %i,  lod %i", mTextureID, lodOffset);
+
+    if (!mTextureID) {
+        glGenTextures(1, &mTextureID);
+    }
+    glBindTexture(GL_TEXTURE_2D, mTextureID);
+
+    Adapter2D adapt(this);
+    for(uint32_t lod = 0; (lod + lodOffset) < mType->getLODCount(); lod++) {
+        adapt.setLOD(lod+lodOffset);
+
+        uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
+        glTexImage2D(GL_TEXTURE_2D, lod, GL_RGB, 
+                     adapt.getDimX(), adapt.getDimY(), 
+                     0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, ptr);
+    }
+}
+
+void Allocation::uploadToBufferObject()
+{
+    rsAssert(!mType->getDimY());
+    rsAssert(!mType->getDimZ());
+
+    //LOGE("uploadToTexture  %i,  lod %i", mTextureID, lodOffset);
+
+    if (!mBufferID) {
+        glGenBuffers(1, &mBufferID);
+    }
+    glBindBuffer(GL_ARRAY_BUFFER, mBufferID);
+    glBufferData(GL_ARRAY_BUFFER, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+void Allocation::data(const void *data)
+{
+    memcpy(mPtr, data, mType->getSizeBytes());
+}
+
+void Allocation::subData(uint32_t xoff, uint32_t count, const void *data)
+{
+    uint32_t eSize = mType->getElementSizeBytes();
+    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
+    ptr += eSize * xoff;
+    memcpy(ptr, data, count * eSize);
+}
+
+void Allocation::subData(uint32_t xoff, uint32_t yoff, 
+             uint32_t w, uint32_t h, const void *data)
+{
+    uint32_t eSize = mType->getElementSizeBytes();
+    uint32_t lineSize = eSize * w;
+    uint32_t destW = mType->getDimX();
+
+    const uint8_t *src = static_cast<const uint8_t *>(data);
+    uint8_t *dst = static_cast<uint8_t *>(mPtr);
+    dst += eSize * (xoff + yoff * destW);
+    for (uint32_t line=yoff; line < (yoff+h); line++) {
+        uint8_t * ptr = static_cast<uint8_t *>(mPtr);
+        memcpy(dst, src, lineSize);
+        src += lineSize;
+        dst += destW * eSize;
+    }
+}
+
+void Allocation::subData(uint32_t xoff, uint32_t yoff, uint32_t zoff,
+             uint32_t w, uint32_t h, uint32_t d, const void *data)
+{
+}
+
+
+
+/////////////////
+// 
+
+
+namespace android {
+namespace renderscript {
+
+RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype)
+{
+    const Type * type = static_cast<const Type *>(vtype);
+
+    Allocation * alloc = new Allocation(type);
+    return alloc;
+}
+
+RsAllocation rsi_AllocationCreatePredefSized(Context *rsc, RsElementPredefined t, size_t count)
+{
+    RsElement e = rsi_ElementGetPredefined(rsc, t);
+    return rsi_AllocationCreateSized(rsc, e, count);
+}
+
+RsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count)
+{
+    Type * type = new Type();
+    type->setDimX(count);
+    type->setElement(static_cast<Element *>(e));
+    type->compute();
+    return rsi_AllocationCreateTyped(rsc, type);
+}
+
+void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, uint32_t baseMipLevel)
+{
+    Allocation *alloc = static_cast<Allocation *>(va);
+    alloc->uploadToTexture(baseMipLevel);
+}
+
+void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va)
+{
+    Allocation *alloc = static_cast<Allocation *>(va);
+    alloc->uploadToBufferObject();
+}
+
+void rsi_AllocationDestroy(Context *rsc, RsAllocation)
+{
+}
+
+static void mip(const Adapter2D &out, const Adapter2D &in)
+{
+    uint32_t w = out.getDimX();
+    uint32_t h = out.getDimY();
+
+    for (uint32_t y=0; y < w; y++) {
+        uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
+        const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
+        const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
+
+        for (uint32_t x=0; x < h; x++) {
+            *oPtr = rsBoxFilter565(i1[0], i1[2], i2[0], i2[1]);
+            oPtr ++;
+            i1 += 2;
+            i2 += 2;
+        }
+    }
+
+}
+
+
+RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, const char *file, bool genMips)
+{
+    typedef struct _Win3xBitmapHeader
+    {
+       uint16_t type;
+       uint32_t totalSize;
+       uint32_t reserved;
+       uint32_t offset;
+       int32_t hdrSize;            /* Size of this header in bytes */
+       int32_t width;           /* Image width in pixels */
+       int32_t height;          /* Image height in pixels */
+       int16_t planes;          /* Number of color planes */
+       int16_t bpp;             /* Number of bits per pixel */
+       /* Fields added for Windows 3.x follow this line */
+       int32_t compression;     /* Compression methods used */
+       int32_t sizeOfBitmap;    /* Size of bitmap in bytes */
+       int32_t horzResolution;  /* Horizontal resolution in pixels per meter */
+       int32_t vertResolution;  /* Vertical resolution in pixels per meter */
+       int32_t colorsUsed;      /* Number of colors in the image */
+       int32_t colorsImportant; /* Minimum number of important colors */
+    } __attribute__((__packed__)) WIN3XBITMAPHEADER;
+
+    _Win3xBitmapHeader hdr;
+
+    FILE *f = fopen(file, "rb");
+    if (f == NULL) {
+        LOGE("rsAllocationCreateFromBitmap failed to open file %s", file);
+        return NULL;
+    }
+    memset(&hdr, 0, sizeof(hdr));
+    fread(&hdr, sizeof(hdr), 1, f);
+
+    if (hdr.bpp != 24) {
+        LOGE("Unsuported BMP type");
+        fclose(f);
+        return NULL;
+    }
+
+    int32_t texWidth = rsHigherPow2(hdr.width);
+    int32_t texHeight = rsHigherPow2(hdr.height);
+
+    rsi_TypeBegin(rsc, rsi_ElementGetPredefined(rsc, RS_ELEMENT_RGB_565));
+    rsi_TypeAdd(rsc, RS_DIMENSION_X, texWidth);
+    rsi_TypeAdd(rsc, RS_DIMENSION_Y, texHeight);
+    if (genMips) {
+        rsi_TypeAdd(rsc, RS_DIMENSION_LOD, 1);
+    }
+    RsType type = rsi_TypeCreate(rsc);
+
+    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, type);
+    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
+    texAlloc->incRef();
+    if (texAlloc == NULL) {
+        LOGE("Memory allocation failure");
+        fclose(f);
+        return NULL;
+    }
+
+    // offset to letterbox if height is not pow2
+    Adapter2D adapt(texAlloc);
+    uint8_t * fileInBuf = new uint8_t[texWidth * 3];
+    uint32_t yOffset = (hdr.width - hdr.height) / 2;
+    uint16_t *tmp = static_cast<uint16_t *>(adapt.getElement(0, yOffset));
+
+    for (int y=0; y < hdr.height; y++) {
+        fseek(f, hdr.offset + (y*hdr.width*3), SEEK_SET);
+        fread(fileInBuf, 1, hdr.width * 3, f);
+        for(int x=0; x < hdr.width; x++) {
+            *tmp = rs888to565(fileInBuf[x*3], fileInBuf[x*3 + 1], fileInBuf[x*3 + 2]);
+            tmp++;
+        }
+    }
+
+    fclose(f);
+    delete [] fileInBuf;
+
+    if (genMips) {
+        Adapter2D adapt2(texAlloc);
+        for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
+            adapt.setLOD(lod);
+            adapt2.setLOD(lod + 1);
+            mip(adapt2, adapt);
+        }
+    }
+
+    return texAlloc;
+}
+
+
+void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data)
+{
+    Allocation *a = static_cast<Allocation *>(va);
+    a->data(data);
+}
+
+void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data)
+{
+    Allocation *a = static_cast<Allocation *>(va);
+    a->subData(xoff, count, data);
+}
+
+void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data)
+{
+    Allocation *a = static_cast<Allocation *>(va);
+    a->subData(xoff, yoff, w, h, data);
+}
+
+
+}
+}
diff --git a/rsAllocation.h b/rsAllocation.h
new file mode 100644
index 0000000..d0b91fd
--- /dev/null
+++ b/rsAllocation.h
@@ -0,0 +1,96 @@
+/*
+ * 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_STRUCTURED_ALLOCATION_H
+#define ANDROID_STRUCTURED_ALLOCATION_H
+
+#include "rsType.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+    
+
+class Allocation : public ObjectBase
+{
+    // The graphics equilivent of malloc.  The allocation contains a structure of elements.
+
+
+public:
+    // By policy this allocation will hold a pointer to the type
+    // but will not destroy it on destruction.
+    Allocation(const Type *);
+    virtual ~Allocation();
+
+    void setCpuWritable(bool);
+    void setGpuWritable(bool);
+    void setCpuReadable(bool);
+    void setGpuReadable(bool);
+
+    bool fixAllocation();
+
+    void * getPtr() const {return mPtr;}
+    const Type * getType() const {return mType.get();}
+
+    void uploadToTexture(uint32_t lodOffset = 0);
+    uint32_t getTextureID() const {return mTextureID;}
+
+    void uploadToBufferObject();
+    uint32_t getBufferObjectID() const {return mBufferID;}
+
+
+    void data(const void *data);
+    void subData(uint32_t xoff, uint32_t count, const void *data);
+    void subData(uint32_t xoff, uint32_t yoff, 
+                 uint32_t w, uint32_t h, const void *data);
+    void subData(uint32_t xoff, uint32_t yoff, uint32_t zoff,
+                 uint32_t w, uint32_t h, uint32_t d, const void *data);
+
+protected:
+    ObjectBaseRef<const Type> mType;
+    void * mPtr;
+
+    // Usage restrictions
+    bool mCpuWrite;
+    bool mCpuRead;
+    bool mGpuWrite;
+    bool mGpuRead;
+
+    // more usage hint data from the application
+    // which can be used by a driver to pick the best memory type.
+    // Likely ignored for now
+    float mReadWriteRatio;
+    float mUpdateSize;
+
+
+    // Is this a legal structure to be used as a texture source.
+    // Initially this will require 1D or 2D and color data
+    bool mIsTexture;
+    uint32_t mTextureID;
+
+    // Is this a legal structure to be used as a vertex source.
+    // Initially this will require 1D and x(yzw).  Additional per element data
+    // is allowed.
+    bool mIsVertexBuffer;
+    uint32_t mBufferID;
+
+};
+
+}
+}
+#endif
+
diff --git a/rsComponent.cpp b/rsComponent.cpp
new file mode 100644
index 0000000..a931811
--- /dev/null
+++ b/rsComponent.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 "rsComponent.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+Component::Component()
+{
+    mType = FLOAT;
+    mKind = NONE;
+    mIsNormalized = false;
+    mBits = 0;
+}
+
+Component::Component(
+    DataKind dk, DataType dt, 
+    bool isNormalized, uint32_t bits)
+{
+    mType = dt;
+    mKind = dk;
+    mIsNormalized = isNormalized;
+    mBits = bits;
+}
+
+Component::~Component()
+{
+}
diff --git a/rsComponent.h b/rsComponent.h
new file mode 100644
index 0000000..205e575
--- /dev/null
+++ b/rsComponent.h
@@ -0,0 +1,75 @@
+/*
+ * 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_STRUCTURED_COMPONENT_H
+#define ANDROID_RS_STRUCTURED_COMPONENT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+#include "RenderScript.h"
+#include "rsObjectBase.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class Component : public ObjectBase
+{
+public:
+    enum DataType {
+        FLOAT,
+        UNSIGNED,
+        SIGNED
+    };
+
+    enum DataKind {
+        NONE,
+        RED, GREEN, BLUE, ALPHA, LUMINANCE, INTENSITY,
+        X, Y, Z, W,
+        S, T, Q, R,
+        NX, NY, NZ,
+        INDEX,
+        USER
+    };
+
+
+    Component(DataKind dk, DataType dt, bool isNormalized, uint32_t bits);
+    virtual ~Component();
+
+    DataType getType() const {return mType;}
+    bool getIsNormalized() const {return mIsNormalized;}
+    DataKind getKind() const {return mKind;}
+    uint32_t getBits() const {return mBits;}
+
+protected:
+
+    DataType mType;
+    bool mIsNormalized;
+    DataKind mKind;
+    uint32_t mBits;
+
+private:
+    Component();
+};
+
+
+}
+}
+
+#endif //ANDROID_RS_STRUCTURED_COMPONENT_H
+
diff --git a/rsContext.cpp b/rsContext.cpp
new file mode 100644
index 0000000..163cf4d
--- /dev/null
+++ b/rsContext.cpp
@@ -0,0 +1,308 @@
+/*
+ * 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 "rsDevice.h"
+#include "rsContext.h"
+#include "rsThreadIO.h"
+
+
+using namespace android;
+using namespace android::renderscript;
+
+Context * Context::gCon = NULL;
+
+void Context::initEGL()
+{
+    mNumConfigs = -1;
+
+    EGLint s_configAttribs[] = {
+         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+         EGL_RED_SIZE,       5,
+         EGL_GREEN_SIZE,     6,
+         EGL_BLUE_SIZE,      5,
+         EGL_DEPTH_SIZE,     16,
+         EGL_NONE
+     };
+
+     LOGE("EGL 1");
+     mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+     LOGE("EGL 2  %p", mDisplay);
+     eglInitialize(mDisplay, &mMajorVersion, &mMinorVersion);
+     LOGE("EGL 3  %i  %i", mMajorVersion, mMinorVersion);
+     eglChooseConfig(mDisplay, s_configAttribs, &mConfig, 1, &mNumConfigs);
+     LOGE("EGL 4  %p", mConfig);
+
+     if (mWndSurface) {
+         mSurface = eglCreateWindowSurface(mDisplay, mConfig,
+                 new EGLNativeWindowSurface(mWndSurface),
+                 NULL);
+     } else {
+         mSurface = eglCreateWindowSurface(mDisplay, mConfig,
+                 android_createDisplaySurface(),
+                 NULL);
+     }
+
+     LOGE("EGL 5");
+     mContext = eglCreateContext(mDisplay, mConfig, NULL, NULL);
+     eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);   
+     eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth);
+     eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight);
+     LOGE("EGL 9");
+
+}
+
+void Context::runRootScript()
+{
+    rsAssert(mRootScript->mIsRoot);
+
+    glViewport(0, 0, 320, 480);
+    float aspectH = 480.f / 320.f;
+
+    if(mRootScript->mIsOrtho) {
+        glMatrixMode(GL_PROJECTION);
+        glLoadIdentity();
+        glOrthof(0, 320,  0, 480,  0, 1);
+        glMatrixMode(GL_MODELVIEW);
+    } else {
+        glMatrixMode(GL_PROJECTION);
+        glLoadIdentity();
+        glFrustumf(-1, 1,  -aspectH, aspectH,  1, 100);
+        glRotatef(-90, 0,0,1);
+        glTranslatef(0,  0,  -3);
+        glMatrixMode(GL_MODELVIEW);
+    }
+
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+    glDepthMask(GL_TRUE);
+    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+    glClearColor(mRootScript->mClearColor[0], 
+                 mRootScript->mClearColor[1],
+                 mRootScript->mClearColor[2],
+                 mRootScript->mClearColor[3]);
+    glClearDepthf(mRootScript->mClearDepth);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glClear(GL_DEPTH_BUFFER_BIT);
+
+    mRootScript->run(this, 0);
+
+}
+
+void Context::setupCheck()
+{
+    if (mFragmentStore.get()) {
+        mFragmentStore->setupGL();
+    }
+    if (mFragment.get()) {
+        mFragment->setupGL();
+    }
+    if (mVertex.get()) {
+        mVertex->setupGL();
+    }
+
+}
+
+
+void * Context::threadProc(void *vrsc)
+{
+     Context *rsc = static_cast<Context *>(vrsc);
+
+     LOGE("TP 1");
+     gIO = new ThreadIO();
+
+     rsc->mServerCommands.init(128);
+     rsc->mServerReturns.init(128);
+
+     rsc->initEGL();
+
+     LOGE("TP 2");
+
+     rsc->mRunning = true;
+     while (!rsc->mExit) {
+         gIO->playCoreCommands(rsc);
+
+         if (!rsc->mRootScript.get()) {
+             continue;
+         }
+
+
+         glColor4f(1,1,1,1);
+         glEnable(GL_LIGHT0);
+
+         if (rsc->mRootScript.get()) {
+             rsc->runRootScript();
+         }
+
+         eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
+
+         usleep(10000);
+     }
+
+     LOGE("TP 6");
+     glClearColor(0,0,0,0);
+     glClear(GL_COLOR_BUFFER_BIT);
+     eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
+     eglTerminate(rsc->mDisplay);
+
+     LOGE("TP 7");
+
+     return NULL;
+}
+
+Context::Context(Device *dev, Surface *sur)
+{
+    LOGE("CC 1");
+    dev->addContext(this);
+    mDev = dev;
+    mRunning = false;
+    mExit = false;
+
+    mServerCommands.init(256);
+    mServerReturns.init(256);
+
+    // see comment in header
+    gCon = this;
+
+    LOGE("CC 2");
+    int status = pthread_create(&mThreadId, NULL, threadProc, this);
+    if (status) {
+        LOGE("Failed to start rs context thread.");
+    }
+
+    LOGE("CC 3");
+    mWndSurface = sur;
+    while(!mRunning) {
+        sleep(1);
+    }
+    LOGE("CC 4");
+
+
+
+}
+
+Context::~Context()
+{
+    mExit = true;
+    void *res;
+
+    LOGE("DES 1");
+    int status = pthread_join(mThreadId, &res);
+    LOGE("DES 2");
+
+    if (mDev) {
+        mDev->removeContext(this);
+    }
+    LOGE("DES 3");
+}
+
+void Context::swapBuffers()
+{
+    eglSwapBuffers(mDisplay, mSurface);
+}
+
+void rsContextSwap(RsContext vrsc)
+{
+    Context *rsc = static_cast<Context *>(vrsc);
+    rsc->swapBuffers();
+}
+
+void Context::setRootScript(Script *s)
+{
+    mRootScript.set(s);
+}
+
+void Context::setFragmentStore(ProgramFragmentStore *pfs)
+{
+    mFragmentStore.set(pfs);
+    pfs->setupGL();
+}
+
+void Context::setFragment(ProgramFragment *pf)
+{
+    mFragment.set(pf);
+    pf->setupGL();
+}
+
+void Context::setVertex(ProgramVertex *pv)
+{
+    mVertex.set(pv);
+    pv->setupGL();
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// 
+
+namespace android {
+namespace renderscript {
+
+
+void rsi_ContextBindRootScript(Context *rsc, RsScript vs)
+{
+    Script *s = static_cast<Script *>(vs);
+    rsc->setRootScript(s);
+}
+
+void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs)
+{
+    Sampler *s = static_cast<Sampler *>(vs);
+
+    if (slot > RS_MAX_SAMPLER_SLOT) {
+        LOGE("Invalid sampler slot");
+        return;
+    }
+
+    s->bindToContext(&rsc->mStateSampler, slot);
+}
+
+void rsi_ContextBindProgramFragmentStore(Context *rsc, RsProgramFragmentStore vpfs)
+{
+    ProgramFragmentStore *pfs = static_cast<ProgramFragmentStore *>(vpfs);
+    rsc->setFragmentStore(pfs);
+}
+
+void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf)
+{
+    ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
+    rsc->setFragment(pf);
+}
+
+void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv)
+{
+    ProgramVertex *pv = static_cast<ProgramVertex *>(vpv);
+    rsc->setVertex(pv);
+}
+
+
+
+}
+}
+
+
+RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version)
+{
+    Device * dev = static_cast<Device *>(vdev);
+    Context *rsc = new Context(dev, (Surface *)sur);
+    return rsc;
+}
+
+void rsContextDestroy(RsContext vrsc)
+{
+    Context * rsc = static_cast<Context *>(vrsc);
+    delete rsc;
+}
+
diff --git a/rsContext.h b/rsContext.h
new file mode 100644
index 0000000..9d96a06
--- /dev/null
+++ b/rsContext.h
@@ -0,0 +1,123 @@
+/*
+ * 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_H
+#define ANDROID_RS_CONTEXT_H
+
+#include <utils/Vector.h>
+#include <ui/EGLNativeWindowSurface.h>
+#include <ui/Surface.h>
+
+#include "rsType.h"
+#include "rsMatrix.h"
+#include "rsAllocation.h"
+#include "rsTriangleMesh.h"
+#include "rsDevice.h"
+#include "rsScriptC.h"
+#include "rsAllocation.h"
+#include "rsAdapter.h"
+#include "rsSampler.h"
+#include "rsProgramFragment.h"
+#include "rsProgramFragmentStore.h"
+#include "rsProgramVertex.h"
+
+#include "rsgApiStructs.h"
+#include "rsLocklessFifo.h"
+
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+class Context 
+{
+public:
+    Context(Device *, Surface *);
+    ~Context();
+
+
+    //StructuredAllocationContext mStateAllocation;
+    ElementState mStateElement;
+    TypeState mStateType;
+    SamplerState mStateSampler;
+    ProgramFragmentState mStateFragment;
+    ProgramFragmentStoreState mStateFragmentStore;
+    ProgramVertexState mStateVertex;
+
+    TriangleMeshContext mStateTriangleMesh;
+
+    ScriptCState mScriptC;
+
+    static Context * getContext() {return gCon;}
+
+    void swapBuffers();
+    void setRootScript(Script *);
+    void setVertex(ProgramVertex *);
+    void setFragment(ProgramFragment *);
+    void setFragmentStore(ProgramFragmentStore *);
+
+    void updateSurface(void *sur);
+
+    const ProgramFragment * getFragment() {return mFragment.get();}
+    const ProgramFragmentStore * getFragmentStore() {return mFragmentStore.get();}
+
+    void setupCheck();
+
+protected:
+    Device *mDev;
+
+    EGLint mNumConfigs;
+    EGLint mMajorVersion;
+    EGLint mMinorVersion;
+    EGLConfig mConfig;
+    EGLContext mContext;
+    EGLSurface mSurface;
+    EGLint mWidth;
+    EGLint mHeight;
+    EGLDisplay mDisplay;
+
+    bool mRunning;
+    bool mExit;
+
+    LocklessCommandFifo mServerCommands;
+    LocklessCommandFifo mServerReturns;
+
+    pthread_t mThreadId;
+
+    ObjectBaseRef<Script> mRootScript;
+    ObjectBaseRef<ProgramFragment> mFragment;
+    ObjectBaseRef<ProgramVertex> mVertex;
+    ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
+
+private:
+    Context();
+
+    void initEGL();
+
+    void runRootScript();
+
+    static void * threadProc(void *);
+
+    // todo: put in TLS
+    static Context *gCon;
+    Surface *mWndSurface;
+};
+
+
+}
+}
+#endif
diff --git a/rsDevice.cpp b/rsDevice.cpp
new file mode 100644
index 0000000..1b3c41b
--- /dev/null
+++ b/rsDevice.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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 "rsDevice.h"
+#include "rsContext.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+Device::Device()
+{
+
+}
+
+Device::~Device()
+{
+
+}
+
+void Device::addContext(Context *rsc)
+{
+    mContexts.add(rsc);
+}
+
+void Device::removeContext(Context *rsc)
+{
+    for (size_t idx=0; idx < mContexts.size(); idx++) {
+        if (mContexts[idx] == rsc) {
+            mContexts.removeAt(idx);
+            break;
+        }
+    }
+}
+
+
+
+RsDevice rsDeviceCreate()
+{
+    Device * d = new Device();
+    return d;
+}
+
+void rsDeviceDestroy(RsDevice dev)
+{
+    Device * d = static_cast<Device *>(dev);
+    delete d;
+
+}
+
diff --git a/rsDevice.h b/rsDevice.h
new file mode 100644
index 0000000..3de3ffa
--- /dev/null
+++ b/rsDevice.h
@@ -0,0 +1,50 @@
+/*
+ * 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_DEVICE_H
+#define ANDROID_RS_DEVICE_H
+
+#include <utils/Vector.h>
+
+//#include "StructuredComponent.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class Context;
+
+class Device {
+public:
+    Device();
+    ~Device();
+
+    void addContext(Context *);
+    void removeContext(Context *);
+
+protected:
+    Vector<Context *> mContexts;
+
+
+};
+
+
+
+
+
+}
+}
+#endif
diff --git a/rsElement.cpp b/rsElement.cpp
new file mode 100644
index 0000000..1637544
--- /dev/null
+++ b/rsElement.cpp
@@ -0,0 +1,326 @@
+/*
+ * 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"
+
+using namespace android;
+using namespace android::renderscript;
+
+void ElementState::initPredefined()
+{
+    Component * u_8  = new Component(Component::USER,   Component::UNSIGNED,  true,  8);
+    Component * i_8  = new Component(Component::USER,   Component::SIGNED,    true,  8);
+    Component * u_16 = new Component(Component::USER,   Component::UNSIGNED,  true,  16);
+    Component * i_16 = new Component(Component::USER,   Component::SIGNED,    true,  16);
+    Component * u_32 = new Component(Component::USER,   Component::UNSIGNED,  true,  32);
+    Component * i_32 = new Component(Component::USER,   Component::SIGNED,    true,  32);
+    Component * f_32 = new Component(Component::USER,   Component::FLOAT,     true,  32);
+
+
+    Component * r_4  = new Component(Component::RED,    Component::UNSIGNED,  true,  4);
+    Component * r_5  = new Component(Component::RED,    Component::UNSIGNED,  true,  5);
+    Component * r_8  = new Component(Component::RED,    Component::UNSIGNED,  true,  8);
+
+    Component * g_4  = new Component(Component::GREEN,  Component::UNSIGNED,  true,  4);
+    Component * g_5  = new Component(Component::GREEN,  Component::UNSIGNED,  true,  5);
+    Component * g_6  = new Component(Component::GREEN,  Component::UNSIGNED,  true,  6);
+    Component * g_8  = new Component(Component::GREEN,  Component::UNSIGNED,  true,  8);
+
+    Component * b_4  = new Component(Component::BLUE,   Component::UNSIGNED,  true,  4);
+    Component * b_5  = new Component(Component::BLUE,   Component::UNSIGNED,  true,  5);
+    Component * b_8  = new Component(Component::BLUE,   Component::UNSIGNED,  true,  8);
+
+    Component * a_1  = new Component(Component::ALPHA,  Component::UNSIGNED,  true,  1);
+    Component * a_4  = new Component(Component::ALPHA,  Component::UNSIGNED,  true,  4);
+    Component * a_8  = new Component(Component::ALPHA,  Component::UNSIGNED,  true,  8);
+
+    Component * idx_16 = new Component(Component::INDEX,  Component::UNSIGNED,  false, 16);
+    Component * idx_32 = new Component(Component::INDEX,  Component::UNSIGNED,  false, 32);
+
+    Component * x    = new Component(Component::X,      Component::FLOAT,     false, 32);
+    Component * y    = new Component(Component::Y,      Component::FLOAT,     false, 32);
+    Component * z    = new Component(Component::Z,      Component::FLOAT,     false, 32);
+
+    Component * nx   = new Component(Component::NX,     Component::FLOAT,     false, 32);
+    Component * ny   = new Component(Component::NY,     Component::FLOAT,     false, 32);
+    Component * nz   = new Component(Component::NZ,     Component::FLOAT,     false, 32);
+
+    Component * s    = new Component(Component::S,      Component::FLOAT,     false, 32);
+    Component * t    = new Component(Component::T,      Component::FLOAT,     false, 32);
+
+    Element * e;
+
+    e = new Element(1);
+    e->setComponent(0, u_8);
+    mPredefinedList.add(Predefined(RS_ELEMENT_USER_U8, e));
+
+    e = new Element(1);
+    e->setComponent(0, i_8);
+    mPredefinedList.add(Predefined(RS_ELEMENT_USER_I8, e));
+
+    e = new Element(1);
+    e->setComponent(0, u_16);
+    mPredefinedList.add(Predefined(RS_ELEMENT_USER_U16, e));
+
+    e = new Element(1);
+    e->setComponent(0, i_16);
+    mPredefinedList.add(Predefined(RS_ELEMENT_USER_I16, e));
+
+    e = new Element(1);
+    e->setComponent(0, u_32);
+    mPredefinedList.add(Predefined(RS_ELEMENT_USER_U32, e));
+
+    e = new Element(1);
+    e->setComponent(0, i_32);
+    mPredefinedList.add(Predefined(RS_ELEMENT_USER_I32, e));
+
+    e = new Element(1);
+    e->setComponent(0, f_32);
+    mPredefinedList.add(Predefined(RS_ELEMENT_USER_FLOAT, e));
+
+    e = new Element(3);
+    e->setComponent(0, r_5);
+    e->setComponent(1, g_6);
+    e->setComponent(2, b_5);
+    mPredefinedList.add(Predefined(RS_ELEMENT_RGB_565, e));
+
+    e = new Element(4);
+    e->setComponent(0, r_5);
+    e->setComponent(1, g_5);
+    e->setComponent(2, b_5);
+    e->setComponent(3, a_1);
+    mPredefinedList.add(Predefined(RS_ELEMENT_RGBA_5551, e));
+
+    e = new Element(4);
+    e->setComponent(0, r_4);
+    e->setComponent(1, g_4);
+    e->setComponent(2, b_4);
+    e->setComponent(3, a_4);
+    mPredefinedList.add(Predefined(RS_ELEMENT_RGBA_4444, e));
+
+    e = new Element(3);
+    e->setComponent(0, r_8);
+    e->setComponent(1, g_8);
+    e->setComponent(2, b_8);
+    mPredefinedList.add(Predefined(RS_ELEMENT_RGB_888, e));
+
+    e = new Element(4);
+    e->setComponent(0, r_8);
+    e->setComponent(1, g_8);
+    e->setComponent(2, b_8);
+    e->setComponent(3, a_8);
+    mPredefinedList.add(Predefined(RS_ELEMENT_RGBA_8888, e));
+
+    e = new Element(1);
+    e->setComponent(0, idx_16);
+    mPredefinedList.add(Predefined(RS_ELEMENT_INDEX_16, e));
+
+    e = new Element(1);
+    e->setComponent(0, idx_32);
+    mPredefinedList.add(Predefined(RS_ELEMENT_INDEX_32, e));
+
+    e = new Element(2);
+    e->setComponent(0, x);
+    e->setComponent(1, y);
+    mPredefinedList.add(Predefined(RS_ELEMENT_XY_F32, e));
+
+    e = new Element(3);
+    e->setComponent(0, x);
+    e->setComponent(1, y);
+    e->setComponent(2, z);
+    mPredefinedList.add(Predefined(RS_ELEMENT_XYZ_F32, e));
+
+    e = new Element(4);
+    e->setComponent(0, s);
+    e->setComponent(1, t);
+    e->setComponent(2, x);
+    e->setComponent(3, y);
+    mPredefinedList.add(Predefined(RS_ELEMENT_ST_XY_F32, e));
+
+    e = new Element(5);
+    e->setComponent(0, s);
+    e->setComponent(1, t);
+    e->setComponent(2, x);
+    e->setComponent(3, y);
+    e->setComponent(4, z);
+    mPredefinedList.add(Predefined(RS_ELEMENT_ST_XYZ_F32, e));
+
+    e = new Element(6);
+    e->setComponent(0, nx);
+    e->setComponent(1, ny);
+    e->setComponent(2, nz);
+    e->setComponent(3, x);
+    e->setComponent(4, y);
+    e->setComponent(5, z);
+    mPredefinedList.add(Predefined(RS_ELEMENT_NORM_XYZ_F32, e));
+
+    e = new Element(8);
+    e->setComponent(0, nx);
+    e->setComponent(1, ny);
+    e->setComponent(2, nz);
+    e->setComponent(3, s);
+    e->setComponent(4, t);
+    e->setComponent(5, x);
+    e->setComponent(6, y);
+    e->setComponent(7, z);
+    mPredefinedList.add(Predefined(RS_ELEMENT_NORM_ST_XYZ_F32, e));
+}
+
+
+Element::Element()
+{
+    mComponents = NULL;
+    mComponentCount = 0;
+}
+
+Element::Element(uint32_t count)
+{
+    mComponents = new ObjectBaseRef<Component> [count];
+    mComponentCount = count;
+}
+
+Element::~Element()
+{
+    clear();
+}
+
+void Element::clear()
+{
+    delete [] mComponents;
+    mComponents = NULL;
+    mComponentCount = 0;
+}
+
+void Element::setComponent(uint32_t idx, Component *c)
+{
+    rsAssert(!mComponents[idx].get());
+    rsAssert(idx < mComponentCount);
+    mComponents[idx].set(c);
+    c->incRef();
+}
+
+
+size_t Element::getSizeBits() const
+{
+    size_t total = 0;
+    for (size_t ct=0; ct < mComponentCount; ct++) {
+        total += mComponents[ct]->getBits();
+    }
+    return total;
+}
+
+size_t Element::getComponentOffsetBits(uint32_t componentNumber) const
+{
+    size_t offset = 0;
+    for (uint32_t ct = 0; ct < componentNumber; ct++) {
+        offset += mComponents[ct]->getBits();
+    }
+    return offset;
+}
+
+ElementState::ElementState()
+{
+}
+
+ElementState::~ElementState()
+{
+}
+
+/////////////////////////////////////////
+// 
+
+namespace android {
+namespace renderscript {
+
+void rsi_ElementBegin(Context *rsc)
+{
+    rsc->mStateElement.mComponentBuildList.clear();
+}
+
+void rsi_ElementAddPredefined(Context *rsc, RsElementPredefined predef)
+{
+    ElementState * sec = &rsc->mStateElement;
+
+    RsElement ve = rsi_ElementGetPredefined(rsc, predef);
+    const Element *e = static_cast<const Element *>(ve);
+
+    for(size_t ct = 0; ct < sec->mPredefinedList[predef].mElement->getComponentCount(); ct++) {
+        sec->mComponentBuildList.add(sec->mPredefinedList[predef].mElement->getComponent(ct));
+    }
+}
+
+RsElement rsi_ElementGetPredefined(Context *rsc, RsElementPredefined predef)
+{
+    ElementState * sec = &rsc->mStateElement;
+
+    if (!sec->mPredefinedList.size()) {
+        sec->initPredefined();
+    }
+
+    if ((predef < 0) || 
+        (static_cast<uint32_t>(predef) >= sec->mPredefinedList.size())) {
+        LOGE("rsElementGetPredefined: Request for bad predefined type");
+        // error
+        return NULL;
+    }
+
+    rsAssert(sec->mPredefinedList[predef].mEnum == predef);
+    Element * e = sec->mPredefinedList[predef].mElement;
+    e->incRef();
+    return e;
+}
+
+void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits)
+{
+    ElementState * sec = &rsc->mStateElement;
+
+}
+
+RsElement rsi_ElementCreate(Context *rsc)
+{
+    ElementState * sec = &rsc->mStateElement;
+
+    Element *se = new Element(sec->mComponentBuildList.size());
+    sec->mAllElements.add(se);
+
+    for (size_t ct = 0; ct < se->getComponentCount(); ct++) {
+        se->setComponent(ct, sec->mComponentBuildList[ct]);
+    }
+
+    rsc->mStateElement.mComponentBuildList.clear();
+    se->incRef();
+
+    LOGE("Create %p", se);
+    return se;
+}
+
+void rsi_ElementDestroy(Context *rsc, RsElement vse)
+{
+    ElementState * sec = &rsc->mStateElement;
+    Element * se = static_cast<Element *>(vse);
+
+    for (size_t ct = 0; ct < sec->mAllElements.size(); ct++) {
+        if (sec->mAllElements[ct] == se) {
+            sec->mAllElements.removeAt(ct);
+            break;
+        }
+    }
+    se->decRef();
+}
+
+
+}
+}
diff --git a/rsElement.h b/rsElement.h
new file mode 100644
index 0000000..7852ffc
--- /dev/null
+++ b/rsElement.h
@@ -0,0 +1,96 @@
+/*
+ * 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_STRUCTURED_ELEMENT_H
+#define ANDROID_STRUCTURED_ELEMENT_H
+
+#include <utils/Vector.h>
+
+#include "rsComponent.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+// An element is a group of Components that occupies one cell in a structure.
+class Element : public ObjectBase
+{
+public:
+    Element(uint32_t count);
+    ~Element();
+
+
+    void setComponent(uint32_t idx, Component *c);
+
+
+
+    size_t getSizeBits() const;
+    size_t getSizeBytes() const { 
+        return (getSizeBits() + 7) >> 3; 
+    }
+
+    size_t getComponentOffsetBits(uint32_t componentNumber) const;
+    size_t getComponentOffsetBytes(uint32_t componentNumber) const { 
+        return (getComponentOffsetBits(componentNumber) + 7) >> 3;
+    }
+
+    uint32_t getComponentCount() const {return mComponentCount;}
+    Component * getComponent(uint32_t idx) const {return mComponents[idx].get();}
+
+protected:
+    // deallocate any components that are part of this element.
+    void clear();
+
+    size_t mComponentCount;
+    ObjectBaseRef<Component> * mComponents;
+    //uint32_t *mOffsetTable;
+
+    Element();
+};
+
+
+class ElementState {
+public:
+    ElementState();
+    ~ElementState();
+
+    Vector<Element *> mAllElements;
+    Vector<Component *> mComponentBuildList;
+
+
+
+    struct Predefined {
+        Predefined() {
+            mElement = NULL;
+        }
+        Predefined(RsElementPredefined en, Element *e) {
+            mEnum = en; 
+            mElement = e;
+        }
+        RsElementPredefined mEnum;
+        Element * mElement;
+    };
+    Vector<Predefined> mPredefinedList;
+
+    void initPredefined();
+    
+};
+
+
+}
+}
+#endif //ANDROID_STRUCTURED_ELEMENT_H
diff --git a/rsLocklessFifo.cpp b/rsLocklessFifo.cpp
new file mode 100644
index 0000000..3f51e04
--- /dev/null
+++ b/rsLocklessFifo.cpp
@@ -0,0 +1,180 @@
+/*
+ * 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 "rsLocklessFifo.h"
+
+using namespace android;
+
+#include <utils/Log.h>
+
+LocklessCommandFifo::LocklessCommandFifo()
+{
+}
+
+LocklessCommandFifo::~LocklessCommandFifo()
+{
+}
+
+bool LocklessCommandFifo::init(uint32_t sizeInBytes)
+{
+    // Add room for a buffer reset command
+    mBuffer = static_cast<uint8_t *>(malloc(sizeInBytes + 4));
+    if (!mBuffer) {
+        LOGE("LocklessFifo allocation failure");
+        return false;
+    }
+
+    int status = pthread_mutex_init(&mMutex, NULL);
+    if (status) {
+        LOGE("LocklessFifo mutex init failure");
+        free(mBuffer);
+        return false;
+    }
+    status = pthread_cond_init(&mCondition, NULL);
+    if (status) {
+        LOGE("LocklessFifo condition init failure");
+        pthread_mutex_destroy(&mMutex);
+        free(mBuffer);
+        return false;
+    }
+
+    mSize = sizeInBytes;
+    mPut = mBuffer;
+    mGet = mBuffer;
+    mEnd = mBuffer + (sizeInBytes) - 1;
+    dumpState("init");
+    return true;
+}
+
+uint32_t LocklessCommandFifo::getFreeSpace() const 
+{
+    int32_t freeSpace = 0;
+    //dumpState("getFreeSpace");
+
+    if (mPut >= mGet) {
+        freeSpace = mEnd - mPut;
+    } else {
+        freeSpace = mGet - mPut;
+    }
+
+    if (freeSpace < 0) {
+        freeSpace = 0;
+    }
+    
+    return freeSpace;
+}
+
+bool LocklessCommandFifo::isEmpty() const
+{
+    return mPut == mGet;
+}
+
+
+void * LocklessCommandFifo::reserve(uint32_t sizeInBytes)
+{
+    // Add space for command header;
+    sizeInBytes += 4;
+
+    //dumpState("reserve");
+    if (getFreeSpace() < sizeInBytes) {
+        makeSpace(sizeInBytes);
+    }
+
+    return mPut + 4;
+}
+
+void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes)
+{
+    //LOGE("commit cmd %i  size %i", command, sizeInBytes);
+    //dumpState("commit 1");
+    reinterpret_cast<uint16_t *>(mPut)[0] = command;
+    reinterpret_cast<uint16_t *>(mPut)[1] = sizeInBytes;
+    mPut += ((sizeInBytes + 3) & ~3) + 4;
+    //dumpState("commit 2");
+
+}
+
+void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes)
+{
+    commit(command, sizeInBytes);
+    flush();
+}
+
+void LocklessCommandFifo::flush()
+{
+    //dumpState("flush 1");
+    while(mPut != mGet) {
+        usleep(1);
+    }
+    //dumpState("flush 2");
+}
+
+const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData)
+{
+    while(1) {
+        while(isEmpty()) {
+            usleep(10);
+        }
+        //dumpState("get 3");
+
+        *command = reinterpret_cast<const uint16_t *>(mGet)[0];
+        *bytesData = reinterpret_cast<const uint16_t *>(mGet)[1];
+        //LOGE("Got %i, %i", *command, *bytesData);
+    
+        if (*command) {
+            // non-zero command is valid
+            return mGet+4;
+        }
+    
+        // zero command means reset to beginning.
+        mGet = mBuffer;
+    }
+}
+
+void LocklessCommandFifo::next()
+{
+    uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1];
+    mGet += ((bytes + 3) & ~3) + 4;
+    //dumpState("next");
+}
+
+void LocklessCommandFifo::makeSpace(uint32_t bytes)
+{
+    if ((mPut+bytes) > mEnd) {
+        // Need to loop regardless of where get is.
+        while((mGet > mPut) && (mPut+4 >= mGet)) {
+            sleep(1);
+        }
+
+        // Toss in a reset then the normal wait for space will do the rest.
+        reinterpret_cast<uint16_t *>(mPut)[0] = 0;
+        reinterpret_cast<uint16_t *>(mPut)[1] = 0;
+        mPut += 4;
+    }
+
+    // it will fit here so we just need to wait for space.
+    while(getFreeSpace() < bytes) {
+        sleep(1);
+    }
+    
+}
+
+void LocklessCommandFifo::dumpState(const char *s) const
+{
+    LOGE("%s  put %p, get %p,  buf %p,  end %p", s, mPut, mGet, mBuffer, mEnd);
+}
+
+
diff --git a/rsLocklessFifo.h b/rsLocklessFifo.h
new file mode 100644
index 0000000..ddef382
--- /dev/null
+++ b/rsLocklessFifo.h
@@ -0,0 +1,74 @@
+/*
+ * 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_LOCKLESS_FIFO_H
+#define ANDROID_RS_LOCKLESS_FIFO_H
+
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+namespace android {
+
+
+// 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 LocklessCommandFifo 
+{
+public:
+    bool init(uint32_t size);
+
+    LocklessCommandFifo();
+    ~LocklessCommandFifo();
+
+
+protected:
+    uint8_t * volatile mPut;
+    uint8_t * volatile mGet;
+    uint8_t * mBuffer;
+    uint8_t * mEnd;
+    uint8_t mSize;
+
+    pthread_mutex_t mMutex;
+    pthread_cond_t mCondition;
+
+public:
+    void * reserve(uint32_t bytes);
+    void commit(uint32_t command, uint32_t bytes);
+    void commitSync(uint32_t command, uint32_t bytes);
+
+    void flush();
+    const void * get(uint32_t *command, uint32_t *bytesData);
+    void next();
+
+    void makeSpace(uint32_t bytes);
+
+    bool isEmpty() const;
+    uint32_t getFreeSpace() const;
+
+
+private:
+    void dumpState(const char *) const;
+};
+
+
+}
+#endif
diff --git a/rsMatrix.cpp b/rsMatrix.cpp
new file mode 100644
index 0000000..7d22ae0
--- /dev/null
+++ b/rsMatrix.cpp
@@ -0,0 +1,138 @@
+/*
+ * 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 "math.h"
+
+#include <utils/Log.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);
+    }
+}
+
+
diff --git a/rsMatrix.h b/rsMatrix.h
new file mode 100644
index 0000000..619b494
--- /dev/null
+++ b/rsMatrix.h
@@ -0,0 +1,84 @@
+/*
+ * 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_MATRIX_H
+#define ANDROID_RS_MATRIX_H
+
+
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+struct Matrix 
+{
+    float m[16];
+
+    inline float get(int i, int j) const {
+        return m[i*4 + j];
+    }
+
+    inline void set(int i, int j, float v) {
+        m[i*4 + j] = v;
+    }
+
+    void loadIdentity();
+    void load(const float *);
+    void load(const Matrix *);
+
+    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 multiply(const Matrix *rhs) {
+        Matrix tmp;
+        tmp.loadMultiply(this, rhs);
+        load(&tmp);
+    }
+    void rotate(float rot, float x, float y, float z) {
+        Matrix tmp;
+        tmp.loadRotate(rot, x, y, z);
+        multiply(&tmp);
+    }
+    void scale(float x, float y, float z) {
+        Matrix tmp;
+        tmp.loadScale(x, y, z);
+        multiply(&tmp);
+    }
+    void translate(float x, float y, float z) {
+        Matrix tmp;
+        tmp.loadTranslate(x, y, z);
+        multiply(&tmp);
+    }
+
+
+
+};
+    
+
+
+}
+}
+
+
+
+
+#endif
+
+
+
+
diff --git a/rsObjectBase.cpp b/rsObjectBase.cpp
new file mode 100644
index 0000000..f9cb9c8
--- /dev/null
+++ b/rsObjectBase.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 "rsObjectBase.h"
+#include <utils/Log.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+ObjectBase::ObjectBase()
+{
+    mRefCount = 0;
+}
+
+ObjectBase::~ObjectBase()
+{
+    rsAssert(!mRefCount);
+}
+
+void ObjectBase::incRef() const
+{
+    mRefCount ++;
+    //LOGE("ObjectBase %p inc ref %i", this, mRefCount);
+}
+
+void ObjectBase::decRef() const
+{
+    rsAssert(mRefCount > 0);
+    mRefCount --;
+    //LOGE("ObjectBase %p dec ref %i", this, mRefCount);
+    if (!mRefCount) {
+        delete this;
+    }
+}
+
diff --git a/rsObjectBase.h b/rsObjectBase.h
new file mode 100644
index 0000000..7761e49
--- /dev/null
+++ b/rsObjectBase.h
@@ -0,0 +1,90 @@
+/*
+ * 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_OBJECT_BASE_H
+#define ANDROID_RS_OBJECT_BASE_H
+
+#include "rsUtils.h"
+
+
+namespace android {
+namespace renderscript {
+
+// An element is a group of Components that occupies one cell in a structure.
+class ObjectBase
+{
+public:
+    ObjectBase();
+    virtual ~ObjectBase();
+
+    void incRef() const;
+    void decRef() const;
+
+private:
+    mutable int32_t mRefCount;
+
+
+};
+
+template<class T> 
+class ObjectBaseRef 
+{
+public:
+    ObjectBaseRef() {
+        mRef = NULL;
+    }
+
+    ~ObjectBaseRef() {
+        clear();
+    }
+
+    void set(T *ref) {
+        if (mRef != ref) {
+            clear();
+            mRef = ref;
+            ref->incRef();
+        }
+    }
+
+    void clear() {
+        if (mRef) {
+            mRef->decRef();
+        }
+        mRef = NULL;
+    }
+
+    inline T * get() const {
+        return mRef;
+    }
+
+    inline T * operator-> () const { 
+        return mRef;  
+    }
+
+protected:
+    T * mRef;
+
+private:
+    ObjectBaseRef(const ObjectBaseRef &) {};
+
+};
+
+
+}
+}
+
+#endif //ANDROID_RS_OBJECT_BASE_H
+
diff --git a/rsProgram.cpp b/rsProgram.cpp
new file mode 100644
index 0000000..5a83fb7
--- /dev/null
+++ b/rsProgram.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 "rsProgram.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+Program::Program(Element *in, Element *out)
+{
+    mElementIn.set(in);
+    mElementOut.set(out);
+
+
+}
+
+Program::~Program()
+{
+}
+
+
+void Program::setAllocation(Allocation *alloc)
+{
+    mConstants.set(alloc);
+    mDirty = true;
+}
+
+void Program::setupGL()
+{
+
+}
+
+
diff --git a/rsProgram.h b/rsProgram.h
new file mode 100644
index 0000000..913fdd2
--- /dev/null
+++ b/rsProgram.h
@@ -0,0 +1,59 @@
+/*
+ * 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_PROGRAM_H
+#define ANDROID_RS_PROGRAM_H
+
+#include "rsObjectBase.h"
+#include "rsElement.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+
+class Program : public ObjectBase
+{
+public:
+    Program(Element *in, Element *out);
+    virtual ~Program();
+
+
+    void setAllocation(Allocation *);
+
+    virtual void setupGL();
+
+protected:
+    // Components not listed in "in" will be passed though
+    // unless overwritten by components in out.
+    ObjectBaseRef<Element> mElementIn;
+    ObjectBaseRef<Element> mElementOut;
+
+    ObjectBaseRef<Allocation> mConstants;
+
+    bool mDirty;
+
+};
+
+
+
+}
+}
+#endif
+
+
+
diff --git a/rsProgramFragment.cpp b/rsProgramFragment.cpp
new file mode 100644
index 0000000..5367c53
--- /dev/null
+++ b/rsProgramFragment.cpp
@@ -0,0 +1,212 @@
+/*
+ * 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 "rsProgramFragment.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+ProgramFragment::ProgramFragment(Element *in, Element *out) :
+    Program(in, out)
+{
+    for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
+        mEnvModes[ct] = RS_TEX_ENV_MODE_REPLACE;
+        mTextureDimensions[ct] = 2;
+    }
+    mTextureEnableMask = 0;
+}
+
+ProgramFragment::~ProgramFragment()
+{
+}
+
+void ProgramFragment::setupGL()
+{
+    for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
+        glActiveTexture(GL_TEXTURE0 + ct);
+        if (!(mTextureEnableMask & (1 << ct)) ||
+            !mSamplers[ct].get() ||
+            !mTextures[ct].get()) {
+
+            glDisable(GL_TEXTURE_2D);
+            continue;
+        }
+
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
+
+        switch(mEnvModes[ct]) {
+        case RS_TEX_ENV_MODE_REPLACE:
+            glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+            break;
+        case RS_TEX_ENV_MODE_MODULATE:
+            glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+            break;
+        case RS_TEX_ENV_MODE_DECAL:
+            glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_DECAL);
+            break;
+        }
+
+        mSamplers[ct]->setupGL();
+    }
+    glActiveTexture(GL_TEXTURE0);
+}
+
+
+void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
+{
+    if (slot >= MAX_TEXTURE) {
+        LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
+        return;
+    }
+
+    mTextures[slot].set(a);
+}
+
+void ProgramFragment::bindSampler(uint32_t slot, Sampler *s)
+{
+    if (slot >= MAX_TEXTURE) {
+        LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
+        return;
+    }
+
+    mSamplers[slot].set(s);
+}
+
+void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
+{
+    if (slot >= MAX_TEXTURE) {
+        LOGE("Attempt to setType to a slot > MAX_TEXTURE");
+        return;
+    }
+
+    if (dim >= 4) {
+        LOGE("Attempt to setType to a dimension > 3");
+        return;
+    }
+
+    mTextureFormats[slot].set(e);
+    mTextureDimensions[slot] = dim;
+}
+
+void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env)
+{
+    if (slot >= MAX_TEXTURE) {
+        LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
+        return;
+    }
+
+    mEnvModes[slot] = env;
+}
+
+void ProgramFragment::setTexEnable(uint32_t slot, bool enable)
+{
+    if (slot >= MAX_TEXTURE) {
+        LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
+        return;
+    }
+
+    uint32_t bit = 1 << slot;
+    mTextureEnableMask &= ~bit;
+    if (enable) {
+        mTextureEnableMask |= bit;
+    }
+}
+
+
+
+ProgramFragmentState::ProgramFragmentState()
+{
+    mPF = NULL;
+}
+
+ProgramFragmentState::~ProgramFragmentState()
+{
+    delete mPF;
+
+}
+
+
+
+namespace android {
+namespace renderscript {
+
+void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out)
+{
+    delete rsc->mStateFragment.mPF;
+    rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out);
+}
+
+void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
+{
+    ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
+    pf->bindTexture(slot, static_cast<Allocation *>(a));
+
+    //LOGE("%p %p", pf, rsc->getFragment());
+    if (pf == rsc->getFragment()) {
+        pf->setupGL();
+    }
+}
+
+void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s)
+{
+    ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
+    pf->bindSampler(slot, static_cast<Sampler *>(s));
+
+    if (pf == rsc->getFragment()) {
+        pf->setupGL();
+    }
+}
+
+void rsi_ProgramFragmentSetType(Context *rsc, uint32_t slot, RsType vt)
+{
+    const Type *t = static_cast<const Type *>(vt);
+    uint32_t dim = 1;
+    if (t->getDimY()) {
+        dim ++;
+        if (t->getDimZ()) {
+            dim ++;
+        }
+    }
+
+    rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim);
+}
+
+void rsi_ProgramFragmentSetEnvMode(Context *rsc, uint32_t slot, RsTexEnvMode env)
+{
+    rsc->mStateFragment.mPF->setEnvMode(slot, env);
+}
+
+void rsi_ProgramFragmentSetTexEnable(Context *rsc, uint32_t slot, bool enable)
+{
+    rsc->mStateFragment.mPF->setTexEnable(slot, enable);
+}
+
+RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
+{
+    ProgramFragment *pf = rsc->mStateFragment.mPF;
+    pf->incRef();
+    rsc->mStateFragment.mPF = 0;
+    return pf;
+}
+
+
+
+}
+}
+
diff --git a/rsProgramFragment.h b/rsProgramFragment.h
new file mode 100644
index 0000000..cc08aea
--- /dev/null
+++ b/rsProgramFragment.h
@@ -0,0 +1,98 @@
+/*
+ * 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_PROGRAM_FRAGMENT_H
+#define ANDROID_RS_PROGRAM_FRAGMENT_H
+
+#include "rsProgram.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+class ProgramFragment : public Program
+{
+public:
+    const static uint32_t MAX_TEXTURE = 2;
+    const static uint32_t MAX_CONSTANTS = 2;
+
+
+
+    ProgramFragment(Element *in, Element *out);
+    virtual ~ProgramFragment();
+
+    virtual void setupGL();
+
+
+
+    void bindTexture(uint32_t slot, Allocation *);
+    void bindSampler(uint32_t slot, Sampler *);
+    void setType(uint32_t slot, const Element *, uint32_t dim);
+
+    void setEnvMode(uint32_t slot, RsTexEnvMode);
+    void setTexEnable(uint32_t slot, bool);
+
+
+
+protected:
+    // 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[MAX_TEXTURE];
+    ObjectBaseRef<Sampler> mSamplers[MAX_TEXTURE];
+    ObjectBaseRef<const Element> mTextureFormats[MAX_TEXTURE];
+    uint32_t mTextureDimensions[MAX_TEXTURE];
+
+
+    ObjectBaseRef<Allocation> mConstants[MAX_CONSTANTS];
+    ObjectBaseRef<Type> mConstantTypes[MAX_CONSTANTS];
+
+
+    // Hacks to create a program for now
+    RsTexEnvMode mEnvModes[MAX_TEXTURE];
+    uint32_t mTextureEnableMask;
+
+
+
+
+
+};
+
+class ProgramFragmentState 
+{
+public:
+    ProgramFragmentState();
+    ~ProgramFragmentState();
+
+    ProgramFragment *mPF;
+
+    ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE];
+
+
+};
+
+
+}
+}
+#endif
+
+
+
+
diff --git a/rsProgramFragmentStore.cpp b/rsProgramFragmentStore.cpp
new file mode 100644
index 0000000..7f5d5f4
--- /dev/null
+++ b/rsProgramFragmentStore.cpp
@@ -0,0 +1,252 @@
+/*
+ * 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 "rsProgramFragmentStore.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+ProgramFragmentStore::ProgramFragmentStore(Element *in, Element *out) :
+    Program(in, out)
+{
+    mDitherEnable = true;
+    mBlendEnable = false;
+    mColorRWriteEnable = true;
+    mColorGWriteEnable = true;
+    mColorBWriteEnable = true;
+    mColorAWriteEnable = true;
+    mBlendSrc = GL_ONE;
+    mBlendDst = GL_ZERO;
+
+
+    mDepthTestEnable = false;
+    mDepthWriteEnable = true;
+    mDepthFunc = GL_LESS;
+
+
+}
+
+ProgramFragmentStore::~ProgramFragmentStore()
+{
+}
+
+void ProgramFragmentStore::setupGL()
+{
+    glColorMask(mColorRWriteEnable,
+                mColorGWriteEnable,
+                mColorBWriteEnable,
+                mColorAWriteEnable);
+    if (mBlendEnable) {
+        glEnable(GL_BLEND);
+        glBlendFunc(mBlendSrc, mBlendDst);
+    } else {
+        glDisable(GL_BLEND);
+    }
+
+    glDepthMask(mDepthWriteEnable);
+    if(mDepthTestEnable) {
+        glEnable(GL_DEPTH_TEST);
+        glDepthFunc(mDepthFunc);
+    } else {
+        glDisable(GL_DEPTH_TEST);
+    }
+
+    if (mDitherEnable) {
+        glEnable(GL_DITHER);
+    } else {
+        glDisable(GL_DITHER);
+    }
+
+
+}
+
+void ProgramFragmentStore::setDitherEnable(bool enable)
+{
+    mDitherEnable = enable;
+}
+
+void ProgramFragmentStore::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 ProgramFragmentStore::setDepthMask(bool mask)
+{
+    mDepthWriteEnable = mask;
+}
+
+void ProgramFragmentStore::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 ProgramFragmentStore::setColorMask(bool r, bool g, bool b, bool a)
+{
+    mColorRWriteEnable = r;
+    mColorGWriteEnable = g;
+    mColorBWriteEnable = b;
+    mColorAWriteEnable = a;
+}
+
+
+ProgramFragmentStoreState::ProgramFragmentStoreState()
+{
+    mPFS = NULL;
+}
+
+ProgramFragmentStoreState::~ProgramFragmentStoreState()
+{
+    delete mPFS;
+
+}
+
+
+
+namespace android {
+namespace renderscript {
+
+void rsi_ProgramFragmentStoreBegin(Context * rsc, RsElement in, RsElement out)
+{
+    delete rsc->mStateFragmentStore.mPFS;
+    rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore((Element *)in, (Element *)out);
+
+}
+
+void rsi_ProgramFragmentStoreDepthFunc(Context *rsc, RsDepthFunc func)
+{
+    rsc->mStateFragmentStore.mPFS->setDepthFunc(func);
+}
+
+void rsi_ProgramFragmentStoreDepthMask(Context *rsc, bool mask)
+{
+    rsc->mStateFragmentStore.mPFS->setDepthMask(mask);
+}
+
+void rsi_ProgramFragmentStoreColorMask(Context *rsc, bool r, bool g, bool b, bool a)
+{
+    rsc->mStateFragmentStore.mPFS->setColorMask(r, g, b, a);
+}
+
+void rsi_ProgramFragmentStoreBlendFunc(Context *rsc, RsBlendSrcFunc src, RsBlendDstFunc dst)
+{
+    rsc->mStateFragmentStore.mPFS->setBlendFunc(src, dst);
+}
+
+RsProgramFragmentStore rsi_ProgramFragmentStoreCreate(Context *rsc)
+{
+    ProgramFragmentStore *pfs = rsc->mStateFragmentStore.mPFS;
+    pfs->incRef();
+    rsc->mStateFragmentStore.mPFS = 0;
+
+    return pfs;
+}
+
+void rsi_ProgramFragmentStoreDither(Context *rsc, bool enable)
+{
+    rsc->mStateFragmentStore.mPFS->setDitherEnable(enable);
+}
+
+
+}
+}
diff --git a/rsProgramFragmentStore.h b/rsProgramFragmentStore.h
new file mode 100644
index 0000000..bbd0f38
--- /dev/null
+++ b/rsProgramFragmentStore.h
@@ -0,0 +1,89 @@
+/*
+ * 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_PROGRAM_FRAGMENT_STORE_H
+#define ANDROID_RS_PROGRAM_FRAGMENT_STORE_H
+
+#include "rsProgram.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+class ProgramFragmentStore : public Program
+{
+public:
+
+
+
+    ProgramFragmentStore(Element *in, Element *out);
+    virtual ~ProgramFragmentStore();
+
+    virtual void setupGL();
+
+
+    void setDepthFunc(RsDepthFunc);
+    void setDepthMask(bool);
+
+    void setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst);
+    void setColorMask(bool, bool, bool, bool);
+
+    void setDitherEnable(bool);
+
+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 ProgramFragmentStoreState 
+{
+public:
+    ProgramFragmentStoreState();
+    ~ProgramFragmentStoreState();
+
+    ProgramFragmentStore *mPFS;
+
+
+};
+
+
+}
+}
+#endif
+
+
+
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
new file mode 100644
index 0000000..8e2b82d
--- /dev/null
+++ b/rsProgramVertex.cpp
@@ -0,0 +1,133 @@
+/*
+ * 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 "rsProgramVertex.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+ProgramVertex::ProgramVertex(Element *in, Element *out) :
+    Program(in, out)
+{
+    mTextureMatrixEnable = false;
+    mProjectionEnable = false;
+    mTransformEnable = false;
+}
+
+ProgramVertex::~ProgramVertex()
+{
+}
+
+void ProgramVertex::setupGL()
+{
+    const float *f = static_cast<const float *>(mConstants[0]->getPtr());
+
+    glMatrixMode(GL_TEXTURE);
+    if (mTextureMatrixEnable) {
+        glLoadMatrixf(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]);
+    } else {
+        glLoadIdentity();
+    }
+
+
+    glMatrixMode(GL_PROJECTION);
+    if (mProjectionEnable) {
+        //glLoadMatrixf(&f[OFFSET_PROJECTION]);
+    } else {
+    }
+
+    glMatrixMode(GL_MODELVIEW);
+    if (mTransformEnable) {
+        glLoadMatrixf(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
+    } else {
+        glLoadIdentity();
+    }
+
+}
+
+void ProgramVertex::setConstantType(uint32_t slot, const Type *t)
+{
+    mConstantTypes[slot].set(t);
+}
+
+void ProgramVertex::bindAllocation(uint32_t slot, Allocation *a)
+{
+    mConstants[slot].set(a);
+}
+
+
+ProgramVertexState::ProgramVertexState()
+{
+    mPV = NULL;
+}
+
+ProgramVertexState::~ProgramVertexState()
+{
+    delete mPV;
+}
+
+
+
+namespace android {
+namespace renderscript {
+
+void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out)
+{
+    delete rsc->mStateVertex.mPV;
+    rsc->mStateVertex.mPV = new ProgramVertex((Element *)in, (Element *)out);
+}
+
+RsProgramVertex rsi_ProgramVertexCreate(Context *rsc)
+{
+    ProgramVertex *pv = rsc->mStateVertex.mPV;
+    pv->incRef();
+    rsc->mStateVertex.mPV = 0;
+
+    return pv;
+}
+
+void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, uint32_t slot, RsAllocation constants)
+{
+    ProgramVertex *pv = static_cast<ProgramVertex *>(vpgm);
+    pv->bindAllocation(slot, static_cast<Allocation *>(constants));
+}
+
+void rsi_ProgramVertexSetType(Context *rsc, uint32_t slot, RsType constants)
+{
+    rsc->mStateVertex.mPV->setConstantType(slot, static_cast<const Type *>(constants));
+}
+
+void rsi_ProgramVertexSetCameraMode(Context *rsc, bool ortho)
+{
+    rsc->mStateVertex.mPV->setProjectionEnabled(!ortho);
+}
+
+void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable)
+{
+    rsc->mStateVertex.mPV->setTextureMatrixEnable(enable);
+}
+
+void rsi_ProgramVertexSetModelMatrixEnable(Context *rsc, bool enable)
+{
+    rsc->mStateVertex.mPV->setTransformEnable(enable);
+}
+
+
+
+}
+}
diff --git a/rsProgramVertex.h b/rsProgramVertex.h
new file mode 100644
index 0000000..cd46900
--- /dev/null
+++ b/rsProgramVertex.h
@@ -0,0 +1,76 @@
+/*
+ * 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_PROGRAM_VERTEX_H
+#define ANDROID_RS_PROGRAM_VERTEX_H
+
+#include "rsProgram.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+class ProgramVertex : public Program
+{
+public:
+    const static uint32_t MAX_CONSTANTS = 2;
+
+    ProgramVertex(Element *in, Element *out);
+    virtual ~ProgramVertex();
+
+    virtual void setupGL();
+
+
+    void setConstantType(uint32_t slot, const Type *);
+    void bindAllocation(uint32_t slot, Allocation *);
+    void setTextureMatrixEnable(bool e) {mTextureMatrixEnable = e;}
+    void setProjectionEnabled(bool e) {mProjectionEnable = e;}
+    void setTransformEnable(bool e) {mTransformEnable = e;}
+
+protected:
+    bool mDirty;
+
+    ObjectBaseRef<Allocation> mConstants[MAX_CONSTANTS];
+    ObjectBaseRef<const Type> mConstantTypes[MAX_CONSTANTS];
+
+    // Hacks to create a program for now
+    bool mTextureMatrixEnable;
+    bool mProjectionEnable;
+    bool mTransformEnable;
+
+};
+
+
+class ProgramVertexState 
+{
+public:
+    ProgramVertexState();
+    ~ProgramVertexState();
+
+    ProgramVertex *mPV;
+
+    //ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE];
+
+
+};
+
+
+}
+}
+#endif
+
+
diff --git a/rsSampler.cpp b/rsSampler.cpp
new file mode 100644
index 0000000..3c008c9
--- /dev/null
+++ b/rsSampler.cpp
@@ -0,0 +1,143 @@
+/*
+ * 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 <GLES/gl.h>
+#include <GLES/glext.h>
+#include <utils/Log.h>
+
+#include "rsContext.h"
+#include "rsSampler.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+Sampler::Sampler()
+{
+    // Should not get called.
+    rsAssert(0);
+}
+
+Sampler::Sampler(RsSamplerValue magFilter,
+                 RsSamplerValue minFilter,
+                 RsSamplerValue wrapS,
+                 RsSamplerValue wrapT,
+                 RsSamplerValue wrapR)
+{
+    mMagFilter = magFilter;
+    mMinFilter = minFilter;
+    mWrapS = wrapS;
+    mWrapT = wrapT;
+    mWrapR = wrapR;
+}
+
+Sampler::~Sampler()
+{
+}
+
+void Sampler::setupGL()
+{
+    //LOGE("setup gl");
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+}
+
+void Sampler::bindToContext(SamplerState *ss, uint32_t slot)
+{
+    ss->mSamplers[slot].set(this);
+    mBoundSlot = slot;
+}
+
+void Sampler::unbindFromContext(SamplerState *ss)
+{
+    int32_t slot = mBoundSlot;
+    mBoundSlot = -1;
+    ss->mSamplers[slot].clear();
+}
+
+void SamplerState::setupGL()
+{
+    for (uint32_t ct=0; ct < 1/*RS_MAX_SAMPLER_SLOT*/; ct++) {
+        Sampler *s = mSamplers[ct].get();
+        if (s) {
+            s->setupGL();
+        } else {
+            glBindTexture(GL_TEXTURE_2D, 0);
+        }
+    }
+}
+
+////////////////////////////////
+
+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;
+}
+
+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;
+    }
+
+}
+
+RsSampler rsi_SamplerCreate(Context *rsc)
+{
+    SamplerState * ss = &rsc->mStateSampler;
+
+
+    Sampler * s = new Sampler(ss->mMagFilter, 
+                              ss->mMinFilter, 
+                              ss->mWrapS, 
+                              ss->mWrapT,
+                              ss->mWrapR);
+    return s;
+}
+
+}}
diff --git a/rsSampler.h b/rsSampler.h
new file mode 100644
index 0000000..45d8c61
--- /dev/null
+++ b/rsSampler.h
@@ -0,0 +1,92 @@
+/*
+ * 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_SAMPLER_H
+#define ANDROID_RS_SAMPLER_H
+
+#include <math.h>
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include "rsAllocation.h"
+#include "RenderScript.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+const static uint32_t RS_MAX_SAMPLER_SLOT = 16;
+
+class SamplerState;
+
+class Sampler : public ObjectBase
+{
+public:
+    Sampler(RsSamplerValue magFilter,
+            RsSamplerValue minFilter,
+            RsSamplerValue wrapS,
+            RsSamplerValue wrapT,
+            RsSamplerValue wrapR);
+
+    virtual ~Sampler();
+
+    void bind(Allocation *);
+    void setupGL();
+
+    void bindToContext(SamplerState *, uint32_t slot);
+    void unbindFromContext(SamplerState *);
+
+protected:
+    RsSamplerValue mMagFilter;
+    RsSamplerValue mMinFilter;
+    RsSamplerValue mWrapS;
+    RsSamplerValue mWrapT;
+    RsSamplerValue mWrapR;
+
+    int32_t mBoundSlot;
+
+private:
+    Sampler();
+
+};
+
+
+class SamplerState 
+{
+public:
+
+    RsSamplerValue mMagFilter;
+    RsSamplerValue mMinFilter;
+    RsSamplerValue mWrapS;
+    RsSamplerValue mWrapT;
+    RsSamplerValue mWrapR;
+
+
+    ObjectBaseRef<Sampler> mSamplers[RS_MAX_SAMPLER_SLOT];
+
+    void setupGL();
+
+};
+
+
+
+}
+}
+#endif //ANDROID_RS_SAMPLER_H
+
+
+
diff --git a/rsScript.cpp b/rsScript.cpp
new file mode 100644
index 0000000..24a630c
--- /dev/null
+++ b/rsScript.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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"
+
+using namespace android;
+using namespace android::renderscript;
+
+Script::Script()
+{
+    mClearColor[0] = 0;
+    mClearColor[1] = 0;
+    mClearColor[2] = 0;
+    mClearColor[3] = 1;
+    mClearDepth = 1;
+}
+
+Script::~Script()
+{
+}
+
+namespace android {
+namespace renderscript {
+
+
+void rsi_ScriptDestroy(Context * rsc, RsScript vs)
+{
+    Script *s = static_cast<Script *>(vs);
+    s->decRef();
+}
+
+void rsi_ScriptBindAllocation(Context * rsc, RsScript vs, RsAllocation va, uint32_t slot)
+{
+    Script *s = static_cast<Script *>(vs);
+    s->mSlots[slot].set(static_cast<Allocation *>(va));
+}
+
+
+}
+}
+
diff --git a/rsScript.h b/rsScript.h
new file mode 100644
index 0000000..1932870
--- /dev/null
+++ b/rsScript.h
@@ -0,0 +1,57 @@
+/*
+ * 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_SCRIPT_H
+#define ANDROID_RS_SCRIPT_H
+
+#include "rsAllocation.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+    
+
+class Script : public ObjectBase
+{
+public:
+
+    Script();
+    virtual ~Script();
+
+
+    bool mIsRoot;
+    bool mIsOrtho;
+
+    float mClearColor[4];
+    float mClearDepth;
+    uint32_t mClearStencil;
+
+
+    const Type * mConstantBufferTypes;
+    uint32_t mCounstantBufferCount;
+
+    ObjectBaseRef<Allocation> mSlots[16];
+
+    virtual void run(Context *, uint32_t launchID) = 0;
+};
+
+
+
+}
+}
+#endif
+
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
new file mode 100644
index 0000000..f825e6e
--- /dev/null
+++ b/rsScriptC.cpp
@@ -0,0 +1,454 @@
+/*
+ * 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 "rsMatrix.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+ScriptC::ScriptC()
+{
+    mScript = NULL;
+}
+
+ScriptC::~ScriptC()
+{
+}
+
+static void matrixLoadIdentity(void *con, rsc_Matrix *mat)
+{
+    Matrix *m = reinterpret_cast<Matrix *>(mat);
+    m->loadIdentity();
+}
+
+static void matrixLoadFloat(void *con, rsc_Matrix *mat, const float *f)
+{
+    Matrix *m = reinterpret_cast<Matrix *>(mat);
+    m->load(f);
+}
+
+static void matrixLoadMat(void *con, rsc_Matrix *mat, const rsc_Matrix *newmat)
+{
+    Matrix *m = reinterpret_cast<Matrix *>(mat);
+    m->load(reinterpret_cast<const Matrix *>(newmat));
+}
+
+static void matrixLoadRotate(void *con, rsc_Matrix *mat, float rot, float x, float y, float z)
+{
+    Matrix *m = reinterpret_cast<Matrix *>(mat);
+    m->loadRotate(rot, x, y, z);
+}
+
+static void matrixLoadScale(void *con, rsc_Matrix *mat, float x, float y, float z)
+{
+    Matrix *m = reinterpret_cast<Matrix *>(mat);
+    m->loadScale(x, y, z);
+}
+
+static void matrixLoadTranslate(void *con, rsc_Matrix *mat, float x, float y, float z)
+{
+    Matrix *m = reinterpret_cast<Matrix *>(mat);
+    m->loadTranslate(x, y, z);
+}
+
+static void matrixLoadMultiply(void *con, rsc_Matrix *mat, const rsc_Matrix *lhs, const rsc_Matrix *rhs)
+{
+    Matrix *m = reinterpret_cast<Matrix *>(mat);
+    m->loadMultiply(reinterpret_cast<const Matrix *>(lhs),
+                    reinterpret_cast<const Matrix *>(rhs));
+}
+
+static void matrixMultiply(void *con, rsc_Matrix *mat, const rsc_Matrix *rhs)
+{
+    Matrix *m = reinterpret_cast<Matrix *>(mat);
+    m->multiply(reinterpret_cast<const Matrix *>(rhs));
+}
+
+static void matrixRotate(void *con, rsc_Matrix *mat, float rot, float x, float y, float z)
+{
+    Matrix *m = reinterpret_cast<Matrix *>(mat);
+    m->rotate(rot, x, y, z);
+}
+
+static void matrixScale(void *con, rsc_Matrix *mat, float x, float y, float z)
+{
+    Matrix *m = reinterpret_cast<Matrix *>(mat);
+    m->scale(x, y, z);
+}
+
+static void matrixTranslate(void *con, rsc_Matrix *mat, float x, float y, float z)
+{
+    Matrix *m = reinterpret_cast<Matrix *>(mat);
+    m->translate(x, y, z);
+}
+
+
+static const void * loadVp(void *vp, uint32_t bank, uint32_t offset)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    return &static_cast<const uint8_t *>(env->mScript->mSlots[bank]->getPtr())[offset];
+}
+
+static float loadF(void *vp, uint32_t bank, uint32_t offset)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    //LOGE("bank %i, offset %i", bank, offset);
+    //LOGE("%p", env->mScript->mSlots[bank]->getPtr());
+    return static_cast<const float *>(env->mScript->mSlots[bank]->getPtr())[offset];
+}
+
+static int32_t loadI32(void *vp, uint32_t bank, uint32_t offset)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    return static_cast<const int32_t *>(env->mScript->mSlots[bank]->getPtr())[offset];
+}
+
+static uint32_t loadU32(void *vp, uint32_t bank, uint32_t offset)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    return static_cast<const uint32_t *>(env->mScript->mSlots[bank]->getPtr())[offset];
+}
+
+static void loadEnvVec4(void *vp, uint32_t bank, uint32_t offset, rsc_Vector4 *v)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    memcpy(v, &static_cast<const float *>(env->mScript->mSlots[bank]->getPtr())[offset], sizeof(rsc_Vector4));
+}
+
+static void loadEnvMatrix(void *vp, uint32_t bank, uint32_t offset, rsc_Matrix *m)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    memcpy(m, &static_cast<const float *>(env->mScript->mSlots[bank]->getPtr())[offset], sizeof(rsc_Matrix));
+}
+
+
+static void storeF(void *vp, uint32_t bank, uint32_t offset, float v)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    static_cast<float *>(env->mScript->mSlots[bank]->getPtr())[offset] = v;
+}
+
+static void storeI32(void *vp, uint32_t bank, uint32_t offset, int32_t v)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    static_cast<int32_t *>(env->mScript->mSlots[bank]->getPtr())[offset] = v;
+}
+
+static void storeU32(void *vp, uint32_t bank, uint32_t offset, uint32_t v)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    static_cast<uint32_t *>(env->mScript->mSlots[bank]->getPtr())[offset] = v;
+}
+
+static void storeEnvVec4(void *vp, uint32_t bank, uint32_t offset, const rsc_Vector4 *v)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    memcpy(&static_cast<float *>(env->mScript->mSlots[bank]->getPtr())[offset], v, sizeof(rsc_Vector4));
+}
+
+static void storeEnvMatrix(void *vp, uint32_t bank, uint32_t offset, const rsc_Matrix *m)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    memcpy(&static_cast<float *>(env->mScript->mSlots[bank]->getPtr())[offset], m, sizeof(rsc_Matrix));
+}
+
+
+static void color(void *vp, float r, float g, float b, float a)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    glColor4f(r, g, b, a);
+}
+
+static void renderTriangleMesh(void *vp, RsTriangleMesh mesh)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    rsi_TriangleMeshRender(env->mContext, mesh);
+}
+
+static void renderTriangleMeshRange(void *vp, RsTriangleMesh mesh, uint32_t start, uint32_t count)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    rsi_TriangleMeshRenderRange(env->mContext, mesh, start, count);
+}
+
+static void materialDiffuse(void *vp, float r, float g, float b, float a)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    float v[] = {r, g, b, a};
+    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, v);
+}
+
+static void materialSpecular(void *vp, float r, float g, float b, float a)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    float v[] = {r, g, b, a};
+    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, v);
+}
+
+static void lightPosition(void *vp, float x, float y, float z, float w)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    float v[] = {x, y, z, w};
+    glLightfv(GL_LIGHT0, GL_POSITION, v);
+}
+
+static void materialShininess(void *vp, float s)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &s);
+}
+
+static void uploadToTexture(void *vp, RsAllocation va, uint32_t baseMipLevel)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    rsi_AllocationUploadToTexture(env->mContext, va, baseMipLevel);
+}
+
+static void enable(void *vp, uint32_t p)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    glEnable(p);
+}
+
+static void disable(void *vp, uint32_t p)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    glDisable(p);
+}
+
+static uint32_t scriptRand(void *vp, uint32_t max)
+{
+    return (uint32_t)(((float)rand()) * max / RAND_MAX);
+}
+
+// Assumes (GL_FIXED) x,y,z (GL_UNSIGNED_BYTE)r,g,b,a
+static void drawTriangleArray(void *vp, RsAllocation alloc, uint32_t count)
+{
+    const Allocation *a = (const Allocation *)alloc;
+    const uint32_t *ptr = (const uint32_t *)a->getPtr();
+
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    env->mContext->setupCheck();
+
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
+
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glDisableClientState(GL_NORMAL_ARRAY);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glEnableClientState(GL_COLOR_ARRAY);
+
+    glVertexPointer(2, GL_FIXED, 12, ptr + 1);
+    //glTexCoordPointer(2, GL_FIXED, 24, ptr + 1);
+    glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr);
+
+    glDrawArrays(GL_TRIANGLES, 0, count * 3);
+}
+
+static void pfBindTexture(void *vp, RsProgramFragment vpf, uint32_t slot, RsAllocation va)
+{
+    //LOGE("pfBindTexture %p", vpf);
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    rsi_ProgramFragmentBindTexture(env->mContext, 
+                                   static_cast<ProgramFragment *>(vpf),
+                                   slot,
+                                   static_cast<Allocation *>(va));
+
+}
+
+static void pfBindSampler(void *vp, RsProgramFragment vpf, uint32_t slot, RsSampler vs)
+{
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    rsi_ProgramFragmentBindSampler(env->mContext, 
+                                   static_cast<ProgramFragment *>(vpf),
+                                   slot,
+                                   static_cast<Sampler *>(vs));
+
+}
+
+static void contextBindProgramFragmentStore(void *vp, RsProgramFragmentStore pfs)
+{
+    //LOGE("contextBindProgramFragmentStore %p", pfs);
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    rsi_ContextBindProgramFragmentStore(env->mContext, pfs);
+
+}
+
+static void contextBindProgramFragment(void *vp, RsProgramFragment pf)
+{
+    //LOGE("contextBindProgramFragment %p", pf);
+    ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
+    rsi_ContextBindProgramFragment(env->mContext, pf);
+
+}
+
+
+static rsc_FunctionTable scriptCPtrTable = {
+    loadVp,
+    loadF,
+    loadI32,
+    loadU32,
+    loadEnvVec4,
+    loadEnvMatrix,
+
+    storeF,
+    storeI32,
+    storeU32,
+    storeEnvVec4,
+    storeEnvMatrix,
+
+    matrixLoadIdentity,
+    matrixLoadFloat,
+    matrixLoadMat,
+    matrixLoadRotate,
+    matrixLoadScale,
+    matrixLoadTranslate,
+    matrixLoadMultiply,
+    matrixMultiply,
+    matrixRotate,
+    matrixScale,
+    matrixTranslate,
+
+    color,
+    renderTriangleMesh,
+    renderTriangleMeshRange,
+
+    pfBindTexture,
+    pfBindSampler,
+
+    materialDiffuse,
+    materialSpecular,
+    lightPosition,
+    materialShininess,
+    uploadToTexture,
+    enable,
+    disable,
+
+    scriptRand,
+    drawTriangleArray,
+    contextBindProgramFragment,
+    contextBindProgramFragmentStore
+};
+
+
+void ScriptC::run(Context *rsc, uint32_t launchID)
+{
+    Env e = {rsc, this};
+    mScript(&e, &scriptCPtrTable, launchID);
+}
+
+ScriptCState::ScriptCState()
+{
+    clear();
+}
+
+ScriptCState::~ScriptCState()
+{
+}
+
+void ScriptCState::clear()
+{
+    mConstantBufferTypes.clear();
+    mClearColor[0] = 0;
+    mClearColor[1] = 0;
+    mClearColor[2] = 0;
+    mClearColor[3] = 1;
+    mClearDepth = 1;
+    mClearStencil = 0;
+    mScript = NULL;
+    mIsRoot = false;
+    mIsOrtho = true;
+}
+
+namespace android {
+namespace renderscript {
+
+void rsi_ScriptCBegin(Context * rsc)
+{
+    ScriptCState *ss = &rsc->mScriptC;
+    ss->clear();
+}
+
+void rsi_ScriptCSetClearColor(Context * rsc, float r, float g, float b, float a)
+{
+    ScriptCState *ss = &rsc->mScriptC;
+    ss->mClearColor[0] = r;
+    ss->mClearColor[1] = g;
+    ss->mClearColor[2] = b;
+    ss->mClearColor[3] = a;
+}
+
+void rsi_ScriptCSetClearDepth(Context * rsc, float v)
+{
+    ScriptCState *ss = &rsc->mScriptC;
+    ss->mClearDepth = v;
+}
+
+void rsi_ScriptCSetClearStencil(Context * rsc, uint32_t v)
+{
+    ScriptCState *ss = &rsc->mScriptC;
+    ss->mClearStencil = v;
+}
+
+void rsi_ScriptCAddType(Context * rsc, RsType vt)
+{
+    ScriptCState *ss = &rsc->mScriptC;
+    ss->mConstantBufferTypes.add(static_cast<const Type *>(vt));
+}
+
+void rsi_ScriptCSetScript(Context * rsc, void *vp)
+{
+    ScriptCState *ss = &rsc->mScriptC;
+    ss->mScript = reinterpret_cast<rsc_RunScript>(vp);
+}
+
+void rsi_ScriptCSetRoot(Context * rsc, bool isRoot)
+{
+    ScriptCState *ss = &rsc->mScriptC;
+    ss->mIsRoot = isRoot;
+}
+
+void rsi_ScriptCSetOrtho(Context * rsc, bool isOrtho)
+{
+    ScriptCState *ss = &rsc->mScriptC;
+    ss->mIsOrtho = isOrtho;
+}
+
+RsScript rsi_ScriptCCreate(Context * rsc)
+{
+    ScriptCState *ss = &rsc->mScriptC;
+
+    ScriptC *s = new ScriptC();
+    s->mScript = ss->mScript;
+    s->mClearColor[0] = ss->mClearColor[0];
+    s->mClearColor[1] = ss->mClearColor[1];
+    s->mClearColor[2] = ss->mClearColor[2];
+    s->mClearColor[3] = ss->mClearColor[3];
+    s->mClearDepth = ss->mClearDepth;
+    s->mClearStencil = ss->mClearStencil;
+    s->mIsRoot = ss->mIsRoot;
+    s->mIsOrtho = ss->mIsOrtho;
+
+    return s;
+}
+
+}
+}
+
+
diff --git a/rsScriptC.h b/rsScriptC.h
new file mode 100644
index 0000000..f35a130
--- /dev/null
+++ b/rsScriptC.h
@@ -0,0 +1,76 @@
+/*
+ * 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_SCRIPT_C_H
+#define ANDROID_RS_SCRIPT_C_H
+
+#include "rsScript.h"
+
+#include "RenderScriptEnv.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+    
+
+class ScriptC : public Script
+{
+public:
+
+    ScriptC();
+    virtual ~ScriptC();
+
+
+    virtual void run(Context *, uint32_t launchID);
+
+
+    rsc_RunScript mScript;
+
+
+    struct Env {
+        Context *mContext;
+        ScriptC *mScript;
+    };
+
+};
+
+class ScriptCState 
+{
+public:
+    ScriptCState();
+    ~ScriptCState();
+
+
+    rsc_RunScript mScript;
+    float mClearColor[4];
+    float mClearDepth;
+    uint32_t mClearStencil;
+    bool mIsRoot;
+    bool mIsOrtho;
+
+    Vector<const Type *> mConstantBufferTypes;
+
+    void clear();
+};
+
+
+}
+}
+#endif
+
+
+
diff --git a/rsThreadIO.cpp b/rsThreadIO.cpp
new file mode 100644
index 0000000..d5ac70b
--- /dev/null
+++ b/rsThreadIO.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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 <utils/Log.h>
+
+#include "rsThreadIO.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+ThreadIO *android::renderscript::gIO = NULL;
+
+ThreadIO::ThreadIO()
+{
+    mToCore.init(16 * 1024);
+}
+
+ThreadIO::~ThreadIO()
+{
+}
+
+void ThreadIO::playCoreCommands(Context *con)
+{
+    //LOGE("playCoreCommands 1");
+    uint32_t cmdID = 0;
+    uint32_t cmdSize = 0;
+    while(!mToCore.isEmpty()) {
+        //LOGE("playCoreCommands 2");
+        const void * data = mToCore.get(&cmdID, &cmdSize);
+        //LOGE("playCoreCommands 3 %i %i", cmdID, cmdSize);
+
+        gPlaybackFuncs[cmdID](con, data);
+        //LOGE("playCoreCommands 4");
+
+        mToCore.next();
+        //LOGE("playCoreCommands 5");
+    }
+}
+
+
diff --git a/rsThreadIO.h b/rsThreadIO.h
new file mode 100644
index 0000000..f8ba37d
--- /dev/null
+++ b/rsThreadIO.h
@@ -0,0 +1,55 @@
+/*
+ * 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_THREAD_IO_H
+#define ANDROID_RS_THREAD_IO_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "RenderScript.h"
+
+#include "rsLocklessFifo.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class Context;
+
+class ThreadIO {
+public:
+    ThreadIO();
+    ~ThreadIO();
+
+    void playCoreCommands(Context *con);
+
+
+    LocklessCommandFifo mToCore;
+    //LocklessCommandFifo mToClient;
+
+    intptr_t mToCoreRet;
+
+};
+
+extern ThreadIO *gIO;
+
+
+
+}
+}
+#endif
+
diff --git a/rsTriangleMesh.cpp b/rsTriangleMesh.cpp
new file mode 100644
index 0000000..6595ebc
--- /dev/null
+++ b/rsTriangleMesh.cpp
@@ -0,0 +1,299 @@
+/*
+ * 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"
+
+using namespace android;
+using namespace android::renderscript;
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <utils/Log.h>
+
+TriangleMesh::TriangleMesh()
+{
+    mVertexElement = NULL;
+    mIndexElement = NULL;
+    mVertexData = NULL;
+    mIndexData = NULL;
+    mTriangleCount = 0;
+    mVertexDataSize = 0;
+    mIndexDataSize = 0;
+
+    mBufferObjects[0] = 0;
+    mBufferObjects[1] = 0;
+
+    mOffsetCoord = 0;
+    mOffsetTex = 0;
+    mOffsetNorm = 0;
+
+    mSizeCoord = 0;
+    mSizeTex = 0;
+    mSizeNorm = 0;
+
+}
+
+TriangleMesh::~TriangleMesh()
+{
+    free(mVertexData);
+    free(mIndexData);
+}
+
+
+
+TriangleMeshContext::TriangleMeshContext()
+{
+    clear();
+}
+
+TriangleMeshContext::~TriangleMeshContext()
+{
+}
+
+void TriangleMeshContext::clear()
+{
+    mVertexElement = NULL;
+    mVertexSizeBits = 0;
+    mIndexElement = NULL;
+    mIndexSizeBits = 0;
+    mTriangleCount = 0;
+    mVertexData.clear();
+    mIndexData.clear();
+}
+
+void TriangleMesh::analyzeElement()
+{
+    for (uint32_t ct=0; ct < mVertexElement->getComponentCount(); ct++) {
+        const Component *c = mVertexElement->getComponent(ct);
+
+        if (c->getKind() == Component::X) {
+            rsAssert(mSizeCoord == 0);
+            mSizeCoord = 1;
+            mOffsetCoord = ct;
+        }
+        if (c->getKind() == Component::Y) {
+            rsAssert(mSizeCoord == 1);
+            mSizeCoord = 2;
+        }
+        if (c->getKind() == Component::Z) {
+            rsAssert(mSizeCoord == 2);
+            mSizeCoord = 3;
+        }
+        if (c->getKind() == Component::W) {
+            rsAssert(mSizeCoord == 4);
+            mSizeCoord = 4;
+        }
+
+        if (c->getKind() == Component::NX) {
+            rsAssert(mSizeNorm == 0);
+            mSizeNorm = 1;
+            mOffsetNorm = ct;
+        }
+        if (c->getKind() == Component::NY) {
+            rsAssert(mSizeNorm == 1);
+            mSizeNorm = 2;
+        }
+        if (c->getKind() == Component::NZ) {
+            rsAssert(mSizeNorm == 2);
+            mSizeNorm = 3;
+        }
+
+        if (c->getKind() == Component::S) {
+            rsAssert(mSizeTex == 0);
+            mSizeTex = 1;
+            mOffsetTex = ct;
+        }
+        if (c->getKind() == Component::T) {
+            rsAssert(mSizeTex == 1);
+            mSizeTex = 2;
+        }
+    }
+    LOGE("TriangleMesh %i,%i  %i,%i  %i,%i", mSizeCoord, mOffsetCoord, mSizeNorm, mOffsetNorm, mSizeTex, mOffsetTex);
+
+}
+
+
+namespace android {
+namespace renderscript {
+
+void rsi_TriangleMeshBegin(Context *rsc, RsElement vertex, RsElement index)
+{
+    //LOGE("tmb  %p %p", vertex, index);
+    TriangleMeshContext *tmc = &rsc->mStateTriangleMesh;
+
+    tmc->clear();
+    tmc->mVertexElement = static_cast<Element *>(vertex);
+    tmc->mVertexSizeBits = tmc->mVertexElement->getSizeBits();
+    tmc->mIndexElement = static_cast<Element *>(index);
+    tmc->mIndexSizeBits = tmc->mIndexElement->getSizeBits();
+
+    //LOGE("Element sizes  %i  %i", tmc->mVertexSizeBits, tmc->mIndexSizeBits);
+
+    assert(!(tmc->mVertexSizeBits & 0x7));
+    assert(!(tmc->mIndexSizeBits & 0x7));
+}
+
+void rsi_TriangleMeshAddVertex(Context *rsc, const void *data)
+{
+    TriangleMeshContext *tmc = &rsc->mStateTriangleMesh;
+
+    // todo: Make this efficient.
+    for (uint32_t ct = 0; (ct * 8) < tmc->mVertexSizeBits; ct++) {
+        tmc->mVertexData.add(static_cast<const uint8_t *>(data) [ct]);
+    }
+}
+
+void rsi_TriangleMeshAddTriangle(Context *rsc, uint32_t idx1, uint32_t idx2, uint32_t idx3)
+{
+    TriangleMeshContext *tmc = &rsc->mStateTriangleMesh;
+
+    // todo: Make this efficient.
+    switch(tmc->mIndexSizeBits) {
+    case 16:
+        tmc->mIndexData.add(idx1);
+        tmc->mIndexData.add(idx2);
+        tmc->mIndexData.add(idx3);
+        break;
+    default:
+        assert(0);
+    }
+
+    tmc->mTriangleCount++;
+}
+
+RsTriangleMesh rsi_TriangleMeshCreate(Context *rsc)
+{
+    TriangleMeshContext *tmc = &rsc->mStateTriangleMesh;
+
+    TriangleMesh * tm = new TriangleMesh();
+    if (!tm) {
+        LOGE("rsTriangleMeshCreate: Error OUT OF MEMORY");
+        // error
+        return 0;
+    }
+
+    tm->mTriangleCount = tmc->mTriangleCount;
+    tm->mIndexDataSize = tmc->mIndexData.size() * tmc->mIndexSizeBits >> 3;
+    tm->mVertexDataSize = tmc->mVertexData.size();
+    tm->mIndexElement = tmc->mIndexElement;
+    tm->mVertexElement = tmc->mVertexElement;
+
+    tm->mIndexData = malloc(tm->mIndexDataSize);
+    tm->mVertexData = malloc(tm->mVertexDataSize);
+    if (!tm->mIndexData || !tm->mVertexData) {
+        LOGE("rsTriangleMeshCreate: Error OUT OF MEMORY");
+        delete tm;
+        return 0;
+    }
+
+    LOGE("Create mesh, triangleCount %i", tm->mTriangleCount);
+
+    memcpy(tm->mVertexData, tmc->mVertexData.array(), tm->mVertexDataSize);
+    memcpy(tm->mIndexData, tmc->mIndexData.array(), tm->mIndexDataSize);
+    tm->analyzeElement();
+
+    return tm;
+}
+
+void rsi_TriangleMeshDestroy(Context *rsc, RsTriangleMesh vtm)
+{
+    TriangleMeshContext *tmc = &rsc->mStateTriangleMesh;
+    TriangleMesh * tm = static_cast<TriangleMesh *>(vtm);
+
+    free(tm->mIndexData);
+    free(tm->mVertexData);
+    delete tm;
+}
+
+
+
+void rsi_TriangleMeshRenderRange(Context *rsc, RsTriangleMesh vtm, uint32_t first, uint32_t count)
+{
+    TriangleMesh * tm = static_cast<TriangleMesh *>(vtm);
+
+    rsc->setupCheck();
+
+    //LOGE("1  %p   ", vtm);
+    //LOGE("1.1  %p   %p", tm->mVertexData,  tm->mIndexData);
+    if (!tm->mBufferObjects[0]) {
+        glGenBuffers(2, &tm->mBufferObjects[0]);
+
+        glBindBuffer(GL_ARRAY_BUFFER, tm->mBufferObjects[0]);
+        glBufferData(GL_ARRAY_BUFFER, tm->mVertexDataSize, tm->mVertexData, GL_STATIC_DRAW);
+        glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER, tm->mIndexDataSize, tm->mIndexData, GL_STATIC_DRAW);
+        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    }
+
+    //LOGE("1.2");
+    if (first >= tm->mTriangleCount) {
+        return;
+    }
+    if (count >= (tm->mTriangleCount - first)) {
+        count = tm->mTriangleCount - first;
+    }
+    if (!count) {
+        return;
+    }
+
+    const float *f = (const float *)tm->mVertexData;
+
+    //LOGE("2");
+    glBindBuffer(GL_ARRAY_BUFFER, tm->mBufferObjects[0]);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
+
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glVertexPointer(tm->mSizeCoord, 
+                    GL_FLOAT, 
+                    tm->mVertexElement->getSizeBytes(), 
+                    (void *)tm->mVertexElement->getComponentOffsetBytes(tm->mOffsetCoord));
+
+    if (tm->mSizeTex) {
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+        glTexCoordPointer(tm->mSizeTex, 
+                          GL_FLOAT, 
+                          tm->mVertexElement->getSizeBytes(), 
+                          (void *)tm->mVertexElement->getComponentOffsetBytes(tm->mOffsetTex));
+    } else {
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    }
+
+    if (tm->mSizeNorm) {
+        glEnableClientState(GL_NORMAL_ARRAY);
+        glNormalPointer(GL_FLOAT, 
+                        tm->mVertexElement->getSizeBytes(), 
+                        (void *)tm->mVertexElement->getComponentOffsetBytes(tm->mOffsetNorm));
+    } else {
+        glDisableClientState(GL_NORMAL_ARRAY);
+    }
+
+    glDrawElements(GL_TRIANGLES, count * 3, GL_UNSIGNED_SHORT, (GLvoid *)(first * 3 * 2));
+
+    //LOGE("4");
+
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+}
+
+void rsi_TriangleMeshRender(Context *rsc, RsTriangleMesh vtm)
+{
+    rsi_TriangleMeshRenderRange(rsc, vtm, 0, 0xffffff);
+}
+
+}}
diff --git a/rsTriangleMesh.h b/rsTriangleMesh.h
new file mode 100644
index 0000000..67f964f
--- /dev/null
+++ b/rsTriangleMesh.h
@@ -0,0 +1,92 @@
+/*
+ * 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_TRIANGLE_MESH_H
+#define ANDROID_RS_TRIANGLE_MESH_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <math.h>
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <utils/Vector.h>
+
+#include "RenderScript.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+// An element is a group of Components that occupies one cell in a structure.
+class TriangleMesh
+{
+public:
+    TriangleMesh();
+    ~TriangleMesh();
+
+    const Element * mVertexElement;
+    const Element * mIndexElement;
+
+    void * mVertexData;
+    void * mIndexData;
+
+    size_t mVertexDataSize;
+    size_t mIndexDataSize;
+    uint32_t mTriangleCount;
+
+    size_t mOffsetCoord;
+    size_t mOffsetTex;
+    size_t mOffsetNorm;
+
+    size_t mSizeCoord;
+    size_t mSizeTex;
+    size_t mSizeNorm;
+
+    // GL buffer info
+    GLuint mBufferObjects[2];
+
+    void analyzeElement();
+protected:
+};
+
+class TriangleMeshContext
+{
+public:
+    TriangleMeshContext();
+    ~TriangleMeshContext();
+
+    const Element * mVertexElement;
+    const Element * mIndexElement;
+    size_t mVertexSizeBits;
+    size_t mIndexSizeBits;
+
+    Vector<uint8_t> mVertexData; 
+    Vector<uint16_t> mIndexData; 
+
+    uint32_t mTriangleCount;
+
+    void clear();
+};
+
+
+}
+}
+#endif //ANDROID_RS_TRIANGLE_MESH_H
+
diff --git a/rsType.cpp b/rsType.cpp
new file mode 100644
index 0000000..6b99820
--- /dev/null
+++ b/rsType.cpp
@@ -0,0 +1,229 @@
+/*
+ * 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"
+
+using namespace android;
+using namespace android::renderscript;
+
+Type::Type()
+{
+    mLODs = 0;
+    mLODCount = 0;
+    clear();
+}
+
+Type::~Type()
+{
+    if (mLODs) {
+        delete [] mLODs;
+    }
+}
+
+void Type::clear()
+{
+    if (mLODs) {
+        delete [] mLODs;
+        mLODs = NULL;
+    }
+    mDimX = 0;
+    mDimY = 0;
+    mDimZ = 0;
+    mDimLOD = 0;
+    mFaces = false;
+    mElement.clear();
+}
+
+TypeState::TypeState()
+{
+}
+
+TypeState::~TypeState()
+{
+}
+
+size_t Type::getOffsetForFace(uint32_t face) const
+{
+    rsAssert(mFaces);
+    return 0;
+}
+
+void Type::compute()
+{
+    //LOGE("compute");
+    uint32_t oldLODCount = mLODCount;
+    if (mDimLOD) {
+        uint32_t l2x = rsFindHighBit(mDimX) + 1;
+        uint32_t l2y = rsFindHighBit(mDimY) + 1;
+        uint32_t l2z = rsFindHighBit(mDimZ) + 1;
+
+        mLODCount = rsMax(l2x, l2y);
+        mLODCount = rsMax(mLODCount, l2z);
+    } else {
+        mLODCount = 1;
+    }
+    if (mLODCount != oldLODCount) {
+        delete [] mLODs;
+        mLODs = new LOD[mLODCount];
+    }
+
+    //LOGE("xyz %i %i %i", mDimX, mDimY, mDimZ);
+    //LOGE("mips %i", mLODCount);
+    //LOGE("e size %i", mElement->getSizeBytes());
+    uint32_t tx = mDimX;
+    uint32_t ty = mDimY;
+    uint32_t tz = mDimZ;
+    size_t offset = 0;
+    for (uint32_t lod=0; lod < mLODCount; lod++) {
+        mLODs[lod].mX = tx;
+        mLODs[lod].mY = ty;
+        mLODs[lod].mZ = tz;
+        mLODs[lod].mOffset = offset;
+        //LOGE("txyz %i %i %i", tx, ty, tz);
+        offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
+        tx >>= 1;
+        ty >>= 1;
+        tz >>= 1;
+    }
+
+    //LOGE("size %i", offset);
+
+    // At this point the offset is the size of a mipmap chain;
+    mMipChainSizeBytes = offset;
+
+    if (mFaces) {
+        offset *= 6;
+    }
+    mTotalSizeBytes = offset;
+
+}
+
+uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const
+{
+    uint32_t offset = mLODs[lod].mOffset;
+    offset += x * mElement->getSizeBytes();
+    return offset;
+}
+
+uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const
+{
+    uint32_t offset = mLODs[lod].mOffset;
+    offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
+    return offset;
+}
+
+uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const
+{
+    uint32_t offset = mLODs[lod].mOffset;
+    offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
+    return offset;
+}
+
+
+//////////////////////////////////////////////////
+// 
+namespace android {
+namespace renderscript {
+
+void rsi_TypeBegin(Context *rsc, RsElement vse)
+{
+    TypeState * stc = &rsc->mStateType;
+
+    stc->mX = 0;
+    stc->mY = 0;
+    stc->mZ = 0;
+    stc->mLOD = false;
+    stc->mFaces = false;
+    stc->mElement.set(static_cast<const Element *>(vse));
+}
+
+void rsi_TypeAdd(Context *rsc, RsDimension dim, size_t value)
+{
+    TypeState * stc = &rsc->mStateType;
+
+    if (dim < 0) {
+        //error
+        return;
+    }
+
+
+    switch (dim) {
+    case RS_DIMENSION_X:
+        stc->mX = value;
+        return;
+    case RS_DIMENSION_Y:
+        stc->mY = value;
+        return;
+    case RS_DIMENSION_Z:
+        stc->mZ = value;
+        return;
+    case RS_DIMENSION_FACE:
+        stc->mFaces = (value != 0);
+        return;
+    case RS_DIMENSION_LOD:
+        stc->mLOD = (value != 0);
+        return;
+    default:
+        break;
+    }
+
+
+    int32_t arrayNum = dim - RS_DIMENSION_ARRAY_0;
+    if ((dim < 0) || (dim > RS_DIMENSION_MAX)) {
+        LOGE("rsTypeAdd: Bad dimension");
+        //error
+        return;
+    }
+
+    // todo: implement array support
+
+}
+
+RsType rsi_TypeCreate(Context *rsc)
+{
+    TypeState * stc = &rsc->mStateType;
+
+    Type * st = new Type();
+    st->setDimX(stc->mX);
+    st->setDimY(stc->mY);
+    st->setDimZ(stc->mZ);
+    st->setElement(stc->mElement.get());
+    st->setDimLOD(stc->mLOD);
+    st->setDimFaces(stc->mFaces);
+    st->compute();
+
+    stc->mAllTypes.add(st);
+
+    return st;
+}
+
+void rsi_TypeDestroy(Context *rsc, RsType vst)
+{
+    TypeState * stc = &rsc->mStateType;
+    Type * st = static_cast<Type *>(vst);
+
+    for (size_t ct = 0; ct < stc->mAllTypes.size(); ct++) {
+        if (stc->mAllTypes[ct] == st) {
+            stc->mAllTypes.removeAt(ct);
+            break;
+        }
+    }
+    delete st;
+}
+
+}
+}
+
diff --git a/rsType.h b/rsType.h
new file mode 100644
index 0000000..a717893
--- /dev/null
+++ b/rsType.h
@@ -0,0 +1,134 @@
+/*
+ * 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_STRUCTURED_TYPE_H
+#define ANDROID_STRUCTURED_TYPE_H
+
+#include "rsElement.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+    
+class Type : public ObjectBase
+{
+public:
+    Type();
+    virtual ~Type();
+
+    Type * createTex2D(const Element *, size_t w, size_t h, bool mip);
+
+
+    size_t getOffsetForFace(uint32_t face) const;
+
+    size_t getSizeBytes() const {return mTotalSizeBytes;}
+    size_t getElementSizeBytes() const {return mElement->getSizeBytes();}
+    const Element * getElement() const {return mElement.get();}
+
+    uint32_t getDimX() const {return mDimX;}
+    uint32_t getDimY() const {return mDimY;}
+    uint32_t getDimZ() const {return mDimZ;}
+    uint32_t getDimLOD() const {return mDimLOD;}
+    bool getDimFaces() const {return mFaces;}
+
+    uint32_t getLODDimX(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mX;}
+    uint32_t getLODDimY(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mY;}
+    uint32_t getLODDimZ(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mZ;}
+    uint32_t getLODOffset(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mOffset;}
+
+    uint32_t getLODOffset(uint32_t lod, uint32_t x) const;
+    uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const;
+    uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const;
+
+    uint32_t getLODCount() const {return mLODCount;}
+
+
+    void setElement(const Element *e) {mElement.set(e);}
+    void setDimX(uint32_t v) {mDimX = v;}
+    void setDimY(uint32_t v) {mDimY = v;}
+    void setDimZ(uint32_t v) {mDimZ = v;}
+    void setDimFaces(bool v) {mFaces = v;}
+    void setDimLOD(bool v) {mDimLOD = v;}
+
+    void clear();
+    void compute();
+
+
+protected:
+    struct LOD {
+        size_t mX;
+        size_t mY;
+        size_t mZ;
+        size_t mOffset;
+    };
+
+    void makeLODTable();
+
+    // Internal structure from most to least significant.
+    // * Array dimensions
+    // * Faces
+    // * Mipmaps
+    // * xyz
+
+    ObjectBaseRef<const Element> mElement;
+
+    // Size of the structure in the various dimensions.  A missing Dimension is
+    // specified as a 0 and not a 1.
+    size_t mDimX;
+    size_t mDimY;
+    size_t mDimZ;
+    bool mDimLOD;
+    bool mFaces;
+
+    // A list of array dimensions.  The count is the number of array dimensions and the 
+    // sizes is a per array size.
+    //Vector<size_t> mDimArraysSizes;
+
+    // count of mipmap levels, 0 indicates no mipmapping
+
+    size_t mMipChainSizeBytes;
+    size_t mTotalSizeBytes;
+    LOD *mLODs;
+    uint32_t mLODCount;
+
+private:
+    Type(const Type &);
+};
+
+
+class TypeState {
+public:
+    TypeState();
+    ~TypeState();
+
+    Vector<Type *> mAllTypes;
+
+    size_t mX;
+    size_t mY;
+    size_t mZ;
+    uint32_t mLOD;
+    bool mFaces;
+    ObjectBaseRef<const Element> mElement;
+
+
+    
+};
+
+
+}
+}
+#endif //ANDROID_STRUCTURED_TYPE
diff --git a/rsUtils.h b/rsUtils.h
new file mode 100644
index 0000000..683c96e
--- /dev/null
+++ b/rsUtils.h
@@ -0,0 +1,114 @@
+/*
+ * 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_UTILS_H
+#define ANDROID_RS_UTILS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+namespace android {
+namespace renderscript {
+
+#if 1
+#define rsAssert(v) do {if(!(v)) LOGE("rsAssert failed: %s, in %s at %i", #v, __FILE__, __LINE__);} while(0)
+#else
+#define rsAssert(v) while(0)
+#endif
+
+template<typename T>
+T rsMin(T in1, T in2)
+{
+    if (in1 > in2) {
+        return in2;
+    }
+    return in1;
+}
+
+template<typename T>
+T rsMax(T in1, T in2)
+{
+    if (in1 < in2) {
+        return in2;
+    }
+    return in1;
+}
+
+template<typename T>
+T rsFindHighBit(T val)
+{
+    uint32_t bit = 0;
+    while(val > 1) {
+        bit++;
+        val>>=1;
+    }
+    return bit;
+}
+
+template<typename T>
+bool rsIsPow2(T val)
+{
+    return (val & (val-1)) == 0;
+}
+
+template<typename T>
+T rsHigherPow2(T v)
+{
+    if (rsIsPow2(v)) {
+        return v;
+    }
+    return 1 << (rsFindHighBit(v) + 1);
+}
+
+template<typename T>
+T rsLowerPow2(T v)
+{
+    if (rsIsPow2(v)) {
+        return v;
+    }
+    return 1 << rsFindHighBit(v);
+}
+
+
+static inline uint16_t rs888to565(uint32_t r, uint32_t g, uint32_t b)
+{
+    uint16_t t = 0;
+    t |= r >> 3;
+    t |= (g >> 2) << 5;
+    t |= (b >> 3) << 11;
+    return t;
+}
+
+static inline uint16_t rsBoxFilter565(uint16_t i1, uint16_t i2, uint16_t i3, uint16_t i4)
+{
+    uint32_t r = ((i1 & 0x1f) + (i2 & 0x1f) + (i3 & 0x1f) + (i4 & 0x1f));
+    uint32_t g = ((i1 >> 5) & 0x3f) + ((i2 >> 5) & 0x3f) + ((i3 >> 5) & 0x3f) + ((i1 >> 5) & 0x3f);
+    uint32_t b = ((i1 >> 11) + (i2 >> 11) + (i3 >> 11) + (i4 >> 11));
+    return (r >> 2) | ((g >> 2) << 5) | ((b >> 2) << 11);
+}
+
+
+
+
+
+
+}
+}
+
+#endif //ANDROID_RS_OBJECT_BASE_H
+
+
diff --git a/rsgApi.cpp.rsg b/rsgApi.cpp.rsg
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/rsgApi.cpp.rsg
@@ -0,0 +1 @@
+2
diff --git a/rsgApiFuncDecl.h.rsg b/rsgApiFuncDecl.h.rsg
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/rsgApiFuncDecl.h.rsg
@@ -0,0 +1 @@
+1
diff --git a/rsgApiReplay.cpp.rsg b/rsgApiReplay.cpp.rsg
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/rsgApiReplay.cpp.rsg
@@ -0,0 +1 @@
+3
diff --git a/rsgApiStructs.h.rsg b/rsgApiStructs.h.rsg
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/rsgApiStructs.h.rsg
@@ -0,0 +1 @@
+0
diff --git a/rsg_generator.c b/rsg_generator.c
new file mode 100644
index 0000000..a4d659d
--- /dev/null
+++ b/rsg_generator.c
@@ -0,0 +1,291 @@
+
+
+#include "lex.yy.c"
+
+void printFileHeader(FILE *f)
+{
+    fprintf(f, "/*\n");
+    fprintf(f, " * Copyright (C) 2009 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");
+    fprintf(f, " * You may obtain a copy of the License at\n");
+    fprintf(f, " *\n");
+    fprintf(f, " *      http://www.apache.org/licenses/LICENSE-2.0\n");
+    fprintf(f, " *\n");
+    fprintf(f, " * Unless required by applicable law or agreed to in writing, software\n");
+    fprintf(f, " * distributed under the License is distributed on an \"AS IS\" BASIS,\n");
+    fprintf(f, " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n");
+    fprintf(f, " * See the License for the specific language governing permissions and\n");
+    fprintf(f, " * limitations under the License.\n");
+    fprintf(f, " */\n\n");
+}
+
+void printVarType(FILE *f, const VarType *vt)
+{
+    int ct;
+    if (vt->isConst) {
+        fprintf(f, "const ");
+    }
+
+    switch(vt->type) {
+    case 0:
+        fprintf(f, "void");
+        break;
+    case 1:
+        fprintf(f, "int%i_t", vt->bits);
+        break;
+    case 2:
+        fprintf(f, "uint%i_t", vt->bits);
+        break;
+    case 3:
+        if (vt->bits == 32)
+            fprintf(f, "float");
+        else
+            fprintf(f, "double");
+        break;
+    case 4:
+        fprintf(f, "%s", vt->typename);
+        break;
+    }
+
+    if(vt->ptrLevel) {
+        fprintf(f, " ");
+        for(ct=0; ct < vt->ptrLevel; ct++) {
+            fprintf(f, "*");
+        }
+    }
+
+    if(vt->name[0]) {
+        fprintf(f, " %s", vt->name);
+    }
+}
+
+void printArgList(FILE *f, const ApiEntry * api, int assumePrevious)
+{
+    int ct;
+    for(ct=0; ct < api->paramCount; ct++) {
+        if (ct || assumePrevious) {
+            fprintf(f, ", ");
+        }
+        printVarType(f, &api->params[ct]);
+    }
+}
+
+void printStructures(FILE *f)
+{
+    int ct;
+    int ct2;
+
+    for(ct=0; ct < apiCount; ct++) {
+        fprintf(f, "typedef struct RS_CMD_%s_rec RS_CMD_%s;\n", apis[ct].name, apis[ct].name);
+    }
+    fprintf(f, "\n");
+
+    for(ct=0; ct < apiCount; ct++) {
+        const ApiEntry * api = &apis[ct];
+        fprintf(f, "#define RS_CMD_ID_%s %i\n", api->name, ct+1);
+        fprintf(f, "struct RS_CMD_%s_rec {\n", api->name);
+        //fprintf(f, "    RsCommandHeader _hdr;\n");
+
+        for(ct2=0; ct2 < api->paramCount; ct2++) {
+            fprintf(f, "    ");
+            printVarType(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 *");
+    }
+    printArgList(f, api, addContext);
+    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);
+        fprintf(f, ";\n");
+    }
+    fprintf(f, "\n\n");
+}
+
+void printPlaybackFuncs(FILE *f, const char *prefix)
+{
+    int ct;
+    for(ct=0; ct < apiCount; ct++) {
+        fprintf(f, "void %s%s (Context *, const void *);\n", prefix, apis[ct].name);
+    }
+}
+
+void printApiCpp(FILE *f)
+{
+    int ct;
+    int ct2;
+
+    fprintf(f, "#include \"rsDevice.h\"\n");
+    fprintf(f, "#include \"rsContext.h\"\n");
+    fprintf(f, "#include \"rsThreadIO.h\"\n");
+    //fprintf(f, "#include \"rsgApiStructs.h\"\n");
+    fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
+    fprintf(f, "\n");
+    fprintf(f, "using namespace android;\n");
+    fprintf(f, "using namespace android::renderscript;\n");
+    fprintf(f, "\n");
+
+    for(ct=0; ct < apiCount; ct++) {
+        int needFlush = 0;
+        const ApiEntry * api = &apis[ct];
+
+        printFuncDecl(f, api, "rs", 0);
+        fprintf(f, "\n{\n");
+        fprintf(f, "    ThreadIO *io = gIO;\n");
+        //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);
+
+        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 (api->ret.typename[0]) {
+            needFlush = 1;
+        }
+
+        fprintf(f, "    io->mToCore.commit");
+        if (needFlush) {
+            fprintf(f, "Sync");
+        }
+        fprintf(f, "(RS_CMD_ID_%s, size);\n", api->name);
+
+        if (api->ret.typename[0]) {
+            fprintf(f, "    return reinterpret_cast<");
+            printVarType(f, &api->ret);
+            fprintf(f, ">(io->mToCoreRet);\n");
+        }
+        fprintf(f, "};\n\n");
+    }
+}
+
+void printPlaybackCpp(FILE *f)
+{
+    int ct;
+    int ct2;
+
+    fprintf(f, "#include \"rsDevice.h\"\n");
+    fprintf(f, "#include \"rsContext.h\"\n");
+    fprintf(f, "#include \"rsThreadIO.h\"\n");
+    //fprintf(f, "#include \"rsgApiStructs.h\"\n");
+    fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
+    fprintf(f, "\n");
+    fprintf(f, "namespace android {\n");
+    fprintf(f, "namespace renderscript {\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");
+        //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, "gIO->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, ",");
+            fprintf(f, "\n           cmd->%s", vt->name);
+        }
+        fprintf(f, ");\n");
+
+        fprintf(f, "};\n\n");
+    }
+
+    fprintf(f, "RsPlaybackFunc gPlaybackFuncs[] = {\n");
+    fprintf(f, "    NULL,\n");
+    for(ct=0; ct < apiCount; ct++) {
+        fprintf(f, "    %s%s,\n", "rsp_", apis[ct].name);
+    }
+    fprintf(f, "};\n");
+
+    fprintf(f, "};\n");
+    fprintf(f, "};\n");
+}
+
+int main(int argc, char **argv)
+{
+    if (argc != 3) {
+        fprintf(stderr, "usage: %s commandFile outFile\n", argv[0]);
+        return 1;
+    }
+    const char* rsgFile = argv[1];
+    const char* outFile = argv[2];
+    FILE* input = fopen(rsgFile, "r");
+
+    char choice = fgetc(input);
+    fclose(input);
+
+    if (choice < '0' || choice > '3') {
+        fprintf(stderr, "Uknown command: \'%c\'\n", choice);
+        return -2;
+    }
+
+    yylex();
+    // printf("# of lines = %d\n", num_lines);
+
+    FILE *f = fopen(outFile, "w");
+
+    printFileHeader(f);
+    switch(choice) {
+        case '0': // rsgApiStructs.h
+        {
+            fprintf(f, "\n");
+            fprintf(f, "#include \"rsContext.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[];\n");
+
+            fprintf(f, "}\n");
+            fprintf(f, "}\n");
+        }
+        break;
+
+        case '1': // rsgApiFuncDecl.h
+        {
+            printFuncDecls(f, "rs", 0);
+        }
+        break;
+
+        case '2': // rsgApi.cpp
+        {
+            printApiCpp(f);
+        }
+        break;
+
+        case '3': // rsgApiReplay.cpp
+        {
+            printFileHeader(f);
+            printPlaybackCpp(f);
+        }
+        break;
+    }
+    fclose(f);
+    return 0;
+}
diff --git a/spec.lex b/spec.lex
new file mode 100644
index 0000000..0f8e9ab
--- /dev/null
+++ b/spec.lex
@@ -0,0 +1,171 @@
+%option stack
+
+%x comment
+%x api_entry
+%x api_entry2
+%x api_entry_param
+%x var_type
+
+DIGIT    [0-9]
+ID       [a-zA-Z_][a-zA-Z0-9_]*
+
+
+   int num_lines = 0;
+
+   typedef struct {
+      int isConst;
+      int type;
+      int bits;
+      int ptrLevel;
+      char name[256];
+      char typename[256];
+   } VarType;
+
+   VarType *currType = 0;
+
+   typedef struct {
+      char name[256];
+      int sync;
+      int paramCount;
+      VarType ret;
+      VarType params[16];
+   } ApiEntry;
+
+   ApiEntry apis[128];
+   int apiCount = 0;
+
+   int typeNextState;
+
+%%
+
+"/*"         BEGIN(comment);
+<comment>[^*\n]*        /* eat anything that's not a '*' */
+<comment>"*"+[^*/\n]*   /* eat up '*'s not followed by '/'s */
+<comment>\n             ++num_lines;
+<comment>"*"+"/"        BEGIN(INITIAL);
+
+<*>" "   //printf("found ' '\n");
+<*>"\n"  ++num_lines; //printf("found lf \n");
+
+{ID} {
+    memset(&apis[apiCount], 0, sizeof(ApiEntry));
+    memcpy(apis[apiCount].name, yytext, yyleng);
+    BEGIN(api_entry);
+    }
+
+<api_entry>"{" {
+    BEGIN(api_entry2);
+    }
+
+<api_entry2>"sync" {
+    apis[apiCount].sync = 1;
+    }
+
+<api_entry2>"ret" {
+    currType = &apis[apiCount].ret;
+    typeNextState = api_entry2;
+    BEGIN(var_type);
+    }
+
+<api_entry2>"param" {
+    currType = &apis[apiCount].params[apis[apiCount].paramCount];
+    apis[apiCount].paramCount++;
+    typeNextState = api_entry_param;
+    BEGIN(var_type);
+    }
+
+<var_type>"const" {
+    currType->isConst = 1;
+    }
+
+<var_type>"i8" {
+    currType->type = 1;
+    currType->bits = 8;
+    BEGIN(typeNextState);
+    }
+
+<var_type>"i16" {
+    currType->type = 1;
+    currType->bits = 16;
+    BEGIN(typeNextState);
+    }
+
+<var_type>"i32" {
+    currType->type = 1;
+    currType->bits = 32;
+    BEGIN(typeNextState);
+    }
+
+<var_type>"i64" {
+    currType->type = 1;
+    currType->bits = 64;
+    BEGIN(typeNextState);
+    }
+
+<var_type>"u8" {
+    currType->type = 2;
+    currType->bits = 8;
+    BEGIN(typeNextState);
+    }
+
+<var_type>"u16" {
+    currType->type = 2;
+    currType->bits = 16;
+    BEGIN(typeNextState);
+    }
+
+<var_type>"u32" {
+    currType->type = 2;
+    currType->bits = 32;
+    BEGIN(typeNextState);
+    }
+
+<var_type>"u64" {
+    currType->type = 2;
+    currType->bits = 64;
+    BEGIN(typeNextState);
+    }
+
+<var_type>"f" {
+    currType->type = 3;
+    currType->bits = 32;
+    BEGIN(typeNextState);
+    }
+
+<var_type>"d" {
+    currType->type = 3;
+    currType->bits = 64;
+    BEGIN(typeNextState);
+    }
+
+<var_type>{ID} {
+    currType->type = 4;
+    currType->bits = 32;
+    memcpy(currType->typename, yytext, yyleng);
+    BEGIN(typeNextState);
+    }
+
+<api_entry_param>"*" {
+    currType->ptrLevel ++;
+    }
+
+<api_entry_param>{ID} {
+    memcpy(currType->name, yytext, yyleng);
+    BEGIN(api_entry2);
+    }
+
+
+<api_entry2>"}" {
+    apiCount++;
+    BEGIN(INITIAL);
+    }
+
+
+%%
+
+
+int yywrap()
+{
+    return 1;
+}
+