Merge "Added benchmark mode. Added some image processing operations."
diff --git a/Android.mk b/Android.mk
index 95571e7..c1910ff 100644
--- a/Android.mk
+++ b/Android.mk
@@ -91,13 +91,15 @@
 	rsNoise.cpp \
 	rsProgram.cpp \
 	rsProgramFragment.cpp \
-	rsProgramFragmentStore.cpp \
+	rsProgramStore.cpp \
 	rsProgramRaster.cpp \
 	rsProgramVertex.cpp \
 	rsSampler.cpp \
 	rsScript.cpp \
 	rsScriptC.cpp \
 	rsScriptC_Lib.cpp \
+	rsScriptC_LibCL.cpp \
+	rsScriptC_LibGL.cpp \
     rsShaderCache.cpp \
 	rsSignal.cpp \
 	rsSimpleMesh.cpp \
diff --git a/RenderScript.h b/RenderScript.h
index 7415ba9..5e246ce 100644
--- a/RenderScript.h
+++ b/RenderScript.h
@@ -44,7 +44,7 @@
 typedef void * RsProgram;
 typedef void * RsProgramVertex;
 typedef void * RsProgramFragment;
-typedef void * RsProgramFragmentStore;
+typedef void * RsProgramStore;
 typedef void * RsProgramRaster;
 
 typedef void (* RsBitmapCallback_t)(void *);
diff --git a/RenderScriptEnv.h b/RenderScriptEnv.h
index 99b8c04..144e539 100644
--- a/RenderScriptEnv.h
+++ b/RenderScriptEnv.h
@@ -12,7 +12,7 @@
 typedef void * RsSimpleMesh;
 typedef void * RsType;
 typedef void * RsProgramFragment;
-typedef void * RsProgramFragmentStore;
+typedef void * RsProgramStore;
 typedef void * RsLight;
 
 
diff --git a/java/Film/src/com/android/film/FilmRS.java b/java/Film/src/com/android/film/FilmRS.java
index f45684c..e26b051 100644
--- a/java/Film/src/com/android/film/FilmRS.java
+++ b/java/Film/src/com/android/film/FilmRS.java
@@ -213,11 +213,10 @@
 
         Log.e("rs", "Done loading named");
 
-        mStripPositionType = Type.createFromClass(mRS, StripPosition.class, 1);
+        //mStripPositionType = Type.createFromClass(mRS, StripPosition.class, 1);
 
         ScriptC.Builder sb = new ScriptC.Builder(mRS);
         sb.setScript(mRes, R.raw.filmstrip);
-        //sb.setRoot(true);
         //sb.setType(mStripPositionType, "Pos", 1);
         mScriptStrip = sb.create();
         mScriptStrip.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
diff --git a/rs.spec b/rs.spec
index a589d5b..4ad25ae 100644
--- a/rs.spec
+++ b/rs.spec
@@ -4,8 +4,8 @@
 	param RsScript sampler
 	}
 
-ContextBindProgramFragmentStore {
-	param RsProgramFragmentStore pgm
+ContextBindProgramStore {
+	param RsProgramStore pgm
 	}
 
 ContextBindProgramFragment {
@@ -293,10 +293,6 @@
 	togglePlay
 	}
 
-ScriptSetRoot {
-	param bool isRoot
-	}
-
 ScriptSetVarI {
 	param RsScript s
 	param uint32_t slot
@@ -332,47 +328,38 @@
 	ret RsScript
 	}
 
-ScriptCSetDefineF {
-    param const char* name
-    param float value
-    }
 
-ScriptCSetDefineI32 {
-    param const char* name
-    param int32_t value
-    }
-
-ProgramFragmentStoreBegin {
+ProgramStoreBegin {
 	param RsElement in
 	param RsElement out
 	}
 
-ProgramFragmentStoreColorMask {
+ProgramStoreColorMask {
 	param bool r
 	param bool g
 	param bool b
 	param bool a
 	}
 
-ProgramFragmentStoreBlendFunc {
+ProgramStoreBlendFunc {
 	param RsBlendSrcFunc srcFunc
 	param RsBlendDstFunc destFunc
 	}
 
-ProgramFragmentStoreDepthMask {
+ProgramStoreDepthMask {
 	param bool enable
 }
 
-ProgramFragmentStoreDither {
+ProgramStoreDither {
 	param bool enable
 }
 
-ProgramFragmentStoreDepthFunc {
+ProgramStoreDepthFunc {
 	param RsDepthFunc func
 }
 
-ProgramFragmentStoreCreate {
-	ret RsProgramFragmentStore
+ProgramStoreCreate {
+	ret RsProgramStore
 	}
 
 ProgramRasterCreate {
diff --git a/rsContext.cpp b/rsContext.cpp
index 017500b..da85f83 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -111,6 +111,9 @@
         LOGE("eglCreateContext returned EGL_NO_CONTEXT");
     }
     gGLContextCount++;
+
+    eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
+    eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight);
 }
 
 void Context::deinitEGL()
@@ -131,7 +134,7 @@
 {
     ObjectBaseRef<ProgramFragment> frag(mFragment);
     ObjectBaseRef<ProgramVertex> vtx(mVertex);
-    ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore);
+    ObjectBaseRef<ProgramStore> store(mFragmentStore);
     ObjectBaseRef<ProgramRaster> raster(mRaster);
 
     uint32_t ret = s->run(this, launchID);
@@ -155,11 +158,8 @@
 {
     timerSet(RS_TIMER_CLEAR_SWAP);
 
-    eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
-    eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight);
-    glViewport(0, 0, mEGL.mWidth, mEGL.mHeight);
+    glViewport(0, 0, mWidth, mHeight);
     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
     glClearColor(mRootScript->mEnviroment.mClearColor[0],
                  mRootScript->mEnviroment.mClearColor[1],
                  mRootScript->mEnviroment.mClearColor[2],
@@ -299,13 +299,13 @@
      }
 
      if (rsc->mIsGraphicsContext) {
-         rsc->mStateRaster.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+         rsc->mStateRaster.init(rsc);
          rsc->setRaster(NULL);
-         rsc->mStateVertex.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+         rsc->mStateVertex.init(rsc);
          rsc->setVertex(NULL);
-         rsc->mStateFragment.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+         rsc->mStateFragment.init(rsc);
          rsc->setFragment(NULL);
-         rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+         rsc->mStateFragmentStore.init(rsc);
          rsc->setFragmentStore(NULL);
          rsc->mStateVertexArray.init(rsc);
      }
@@ -493,6 +493,8 @@
 
     mWndSurface = sur;
     if (mWndSurface != NULL) {
+        mWidth = w;
+        mHeight = h;
         bool first = false;
         if (!mEGL.mContext) {
             first = true;
@@ -510,11 +512,7 @@
         ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext);
         checkEglError("eglMakeCurrent", ret);
 
-        eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
-        eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight);
-        mWidth = w;
-        mHeight = h;
-        mStateVertex.updateSize(this, w, h);
+        mStateVertex.updateSize(this);
 
         if ((int)mWidth != mEGL.mWidth || (int)mHeight != mEGL.mHeight) {
             LOGE("EGL/Surface mismatch  EGL (%i x %i)  SF (%i x %i)", mEGL.mWidth, mEGL.mHeight, mWidth, mHeight);
@@ -582,7 +580,7 @@
     mRootScript.set(s);
 }
 
-void Context::setFragmentStore(ProgramFragmentStore *pfs)
+void Context::setFragmentStore(ProgramStore *pfs)
 {
     rsAssert(mIsGraphicsContext);
     if (pfs == NULL) {
@@ -806,9 +804,9 @@
     s->bindToContext(&rsc->mStateSampler, slot);
 }
 
-void rsi_ContextBindProgramFragmentStore(Context *rsc, RsProgramFragmentStore vpfs)
+void rsi_ContextBindProgramStore(Context *rsc, RsProgramStore vpfs)
 {
-    ProgramFragmentStore *pfs = static_cast<ProgramFragmentStore *>(vpfs);
+    ProgramStore *pfs = static_cast<ProgramStore *>(vpfs);
     rsc->setFragmentStore(pfs);
 }
 
diff --git a/rsContext.h b/rsContext.h
index 8249f5b..4a6072d 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -33,7 +33,7 @@
 #include "rsSampler.h"
 #include "rsLight.h"
 #include "rsProgramFragment.h"
-#include "rsProgramFragmentStore.h"
+#include "rsProgramStore.h"
 #include "rsProgramRaster.h"
 #include "rsProgramVertex.h"
 #include "rsShaderCache.h"
@@ -71,7 +71,7 @@
     TypeState mStateType;
     SamplerState mStateSampler;
     ProgramFragmentState mStateFragment;
-    ProgramFragmentStoreState mStateFragmentStore;
+    ProgramStoreState mStateFragmentStore;
     ProgramRasterState mStateRaster;
     ProgramVertexState mStateVertex;
     LightState mStateLight;
@@ -85,12 +85,12 @@
     void setRaster(ProgramRaster *);
     void setVertex(ProgramVertex *);
     void setFragment(ProgramFragment *);
-    void setFragmentStore(ProgramFragmentStore *);
+    void setFragmentStore(ProgramStore *);
 
     void updateSurface(void *sur);
 
     const ProgramFragment * getFragment() {return mFragment.get();}
-    const ProgramFragmentStore * getFragmentStore() {return mFragmentStore.get();}
+    const ProgramStore * getFragmentStore() {return mFragmentStore.get();}
     const ProgramRaster * getRaster() {return mRaster.get();}
     const ProgramVertex * getVertex() {return mVertex.get();}
 
@@ -118,15 +118,15 @@
     ProgramVertex * getDefaultProgramVertex() const {
         return mStateVertex.mDefault.get();
     }
-    ProgramFragmentStore * getDefaultProgramFragmentStore() const {
+    ProgramStore * getDefaultProgramStore() const {
         return mStateFragmentStore.mDefault.get();
     }
     ProgramRaster * getDefaultProgramRaster() const {
         return mStateRaster.mDefault.get();
     }
 
-    uint32_t getWidth() const {return mEGL.mWidth;}
-    uint32_t getHeight() const {return mEGL.mHeight;}
+    uint32_t getWidth() const {return mWidth;}
+    uint32_t getHeight() const {return mHeight;}
 
 
     ThreadIO mIO;
@@ -221,7 +221,7 @@
     ObjectBaseRef<Script> mRootScript;
     ObjectBaseRef<ProgramFragment> mFragment;
     ObjectBaseRef<ProgramVertex> mVertex;
-    ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
+    ObjectBaseRef<ProgramStore> mFragmentStore;
     ObjectBaseRef<ProgramRaster> mRaster;
 
 
diff --git a/rsProgram.cpp b/rsProgram.cpp
index 478a6dc..70e2868 100644
--- a/rsProgram.cpp
+++ b/rsProgram.cpp
@@ -195,7 +195,7 @@
 
     if (rsc->props.mLogShaders) {
         LOGV("Loading shader type %x, ID %i", type, mShaderID);
-        LOGV(mShader.string());
+        LOGV("%s", mShader.string());
     }
 
     if (mShaderID) {
diff --git a/rsProgramFragment.cpp b/rsProgramFragment.cpp
index d192195..c3fd5c5 100644
--- a/rsProgramFragment.cpp
+++ b/rsProgramFragment.cpp
@@ -300,7 +300,7 @@
 
 }
 
-void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
+void ProgramFragmentState::init(Context *rsc)
 {
     uint32_t tmp[5] = {
         RS_TEX_ENV_MODE_NONE, 0,
@@ -328,7 +328,7 @@
 {
     ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
     pf->incUserRef();
-    LOGE("rsi_ProgramFragmentCreate %p", pf);
+    //LOGE("rsi_ProgramFragmentCreate %p", pf);
     return pf;
 }
 
@@ -338,7 +338,7 @@
 {
     ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
     pf->incUserRef();
-    LOGE("rsi_ProgramFragmentCreate2 %p", pf);
+    //LOGE("rsi_ProgramFragmentCreate2 %p", pf);
     return pf;
 }
 
diff --git a/rsProgramFragment.h b/rsProgramFragment.h
index 9fa565d..db91524 100644
--- a/rsProgramFragment.h
+++ b/rsProgramFragment.h
@@ -57,7 +57,7 @@
     ~ProgramFragmentState();
 
     ProgramFragment *mPF;
-    void init(Context *rsc, int32_t w, int32_t h);
+    void init(Context *rsc);
     void deinit(Context *rsc);
 
     ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE];
diff --git a/rsProgramRaster.cpp b/rsProgramRaster.cpp
index 13887d1..c095635 100644
--- a/rsProgramRaster.cpp
+++ b/rsProgramRaster.cpp
@@ -102,7 +102,7 @@
 {
 }
 
-void ProgramRasterState::init(Context *rsc, int32_t w, int32_t h)
+void ProgramRasterState::init(Context *rsc)
 {
     ProgramRaster *pr = new ProgramRaster(rsc, false, false, false);
     mDefault.set(pr);
diff --git a/rsProgramRaster.h b/rsProgramRaster.h
index c3a9c90..04eaaa8 100644
--- a/rsProgramRaster.h
+++ b/rsProgramRaster.h
@@ -56,7 +56,7 @@
 public:
     ProgramRasterState();
     ~ProgramRasterState();
-    void init(Context *rsc, int32_t w, int32_t h);
+    void init(Context *rsc);
     void deinit(Context *rsc);
 
     ObjectBaseRef<ProgramRaster> mDefault;
diff --git a/rsProgramFragmentStore.cpp b/rsProgramStore.cpp
similarity index 78%
rename from rsProgramFragmentStore.cpp
rename to rsProgramStore.cpp
index 8a2157f..ff70509 100644
--- a/rsProgramFragmentStore.cpp
+++ b/rsProgramStore.cpp
@@ -15,7 +15,7 @@
  */
 
 #include "rsContext.h"
-#include "rsProgramFragmentStore.h"
+#include "rsProgramStore.h"
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
@@ -24,7 +24,7 @@
 using namespace android::renderscript;
 
 
-ProgramFragmentStore::ProgramFragmentStore(Context *rsc) :
+ProgramStore::ProgramStore(Context *rsc) :
     Program(rsc)
 {
     mAllocFile = __FILE__;
@@ -46,11 +46,11 @@
 
 }
 
-ProgramFragmentStore::~ProgramFragmentStore()
+ProgramStore::~ProgramStore()
 {
 }
 
-void ProgramFragmentStore::setupGL(const Context *rsc, ProgramFragmentStoreState *state)
+void ProgramStore::setupGL(const Context *rsc, ProgramStoreState *state)
 {
     if (state->mLast.get() == this) {
         return;
@@ -85,7 +85,7 @@
     }
 }
 
-void ProgramFragmentStore::setupGL2(const Context *rsc, ProgramFragmentStoreState *state)
+void ProgramStore::setupGL2(const Context *rsc, ProgramStoreState *state)
 {
     if (state->mLast.get() == this) {
         return;
@@ -121,12 +121,12 @@
 }
 
 
-void ProgramFragmentStore::setDitherEnable(bool enable)
+void ProgramStore::setDitherEnable(bool enable)
 {
     mDitherEnable = enable;
 }
 
-void ProgramFragmentStore::setDepthFunc(RsDepthFunc func)
+void ProgramStore::setDepthFunc(RsDepthFunc func)
 {
     mDepthTestEnable = true;
 
@@ -156,12 +156,12 @@
     }
 }
 
-void ProgramFragmentStore::setDepthMask(bool mask)
+void ProgramStore::setDepthMask(bool mask)
 {
     mDepthWriteEnable = mask;
 }
 
-void ProgramFragmentStore::setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst)
+void ProgramStore::setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst)
 {
     mBlendEnable = true;
     if ((src == RS_BLEND_SRC_ONE) &&
@@ -227,7 +227,7 @@
     }
 }
 
-void ProgramFragmentStore::setColorMask(bool r, bool g, bool b, bool a)
+void ProgramStore::setColorMask(bool r, bool g, bool b, bool a)
 {
     mColorRWriteEnable = r;
     mColorGWriteEnable = g;
@@ -236,24 +236,24 @@
 }
 
 
-ProgramFragmentStoreState::ProgramFragmentStoreState()
+ProgramStoreState::ProgramStoreState()
 {
     mPFS = NULL;
 }
 
-ProgramFragmentStoreState::~ProgramFragmentStoreState()
+ProgramStoreState::~ProgramStoreState()
 {
     delete mPFS;
 
 }
 
-void ProgramFragmentStoreState::init(Context *rsc, int32_t w, int32_t h)
+void ProgramStoreState::init(Context *rsc)
 {
-    ProgramFragmentStore *pfs = new ProgramFragmentStore(rsc);
+    ProgramStore *pfs = new ProgramStore(rsc);
     mDefault.set(pfs);
 }
 
-void ProgramFragmentStoreState::deinit(Context *rsc)
+void ProgramStoreState::deinit(Context *rsc)
 {
     mDefault.clear();
     mLast.clear();
@@ -263,42 +263,42 @@
 namespace android {
 namespace renderscript {
 
-void rsi_ProgramFragmentStoreBegin(Context * rsc, RsElement in, RsElement out)
+void rsi_ProgramStoreBegin(Context * rsc, RsElement in, RsElement out)
 {
     delete rsc->mStateFragmentStore.mPFS;
-    rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore(rsc);
+    rsc->mStateFragmentStore.mPFS = new ProgramStore(rsc);
 
 }
 
-void rsi_ProgramFragmentStoreDepthFunc(Context *rsc, RsDepthFunc func)
+void rsi_ProgramStoreDepthFunc(Context *rsc, RsDepthFunc func)
 {
     rsc->mStateFragmentStore.mPFS->setDepthFunc(func);
 }
 
-void rsi_ProgramFragmentStoreDepthMask(Context *rsc, bool mask)
+void rsi_ProgramStoreDepthMask(Context *rsc, bool mask)
 {
     rsc->mStateFragmentStore.mPFS->setDepthMask(mask);
 }
 
-void rsi_ProgramFragmentStoreColorMask(Context *rsc, bool r, bool g, bool b, bool a)
+void rsi_ProgramStoreColorMask(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)
+void rsi_ProgramStoreBlendFunc(Context *rsc, RsBlendSrcFunc src, RsBlendDstFunc dst)
 {
     rsc->mStateFragmentStore.mPFS->setBlendFunc(src, dst);
 }
 
-RsProgramFragmentStore rsi_ProgramFragmentStoreCreate(Context *rsc)
+RsProgramStore rsi_ProgramStoreCreate(Context *rsc)
 {
-    ProgramFragmentStore *pfs = rsc->mStateFragmentStore.mPFS;
+    ProgramStore *pfs = rsc->mStateFragmentStore.mPFS;
     pfs->incUserRef();
     rsc->mStateFragmentStore.mPFS = 0;
     return pfs;
 }
 
-void rsi_ProgramFragmentStoreDither(Context *rsc, bool enable)
+void rsi_ProgramStoreDither(Context *rsc, bool enable)
 {
     rsc->mStateFragmentStore.mPFS->setDitherEnable(enable);
 }
diff --git a/rsProgramFragmentStore.h b/rsProgramStore.h
similarity index 71%
rename from rsProgramFragmentStore.h
rename to rsProgramStore.h
index 3412c99..d686aa8 100644
--- a/rsProgramFragmentStore.h
+++ b/rsProgramStore.h
@@ -23,16 +23,16 @@
 namespace android {
 namespace renderscript {
 
-class ProgramFragmentStoreState;
+class ProgramStoreState;
 
-class ProgramFragmentStore : public Program
+class ProgramStore : public Program
 {
 public:
-    ProgramFragmentStore(Context *);
-    virtual ~ProgramFragmentStore();
+    ProgramStore(Context *);
+    virtual ~ProgramStore();
 
-    virtual void setupGL(const Context *, ProgramFragmentStoreState *);
-    virtual void setupGL2(const Context *, ProgramFragmentStoreState *);
+    virtual void setupGL(const Context *, ProgramStoreState *);
+    virtual void setupGL2(const Context *, ProgramStoreState *);
 
     void setDepthFunc(RsDepthFunc);
     void setDepthMask(bool);
@@ -60,19 +60,19 @@
     bool mStencilTestEnable;
 };
 
-class ProgramFragmentStoreState
+class ProgramStoreState
 {
 public:
-    ProgramFragmentStoreState();
-    ~ProgramFragmentStoreState();
-    void init(Context *rsc, int32_t w, int32_t h);
+    ProgramStoreState();
+    ~ProgramStoreState();
+    void init(Context *rsc);
     void deinit(Context *rsc);
 
-    ObjectBaseRef<ProgramFragmentStore> mDefault;
-    ObjectBaseRef<ProgramFragmentStore> mLast;
+    ObjectBaseRef<ProgramStore> mDefault;
+    ObjectBaseRef<ProgramStore> mLast;
 
 
-    ProgramFragmentStore *mPFS;
+    ProgramStore *mPFS;
 };
 
 
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
index a2b2df4..c3264ae 100644
--- a/rsProgramVertex.cpp
+++ b/rsProgramVertex.cpp
@@ -362,7 +362,7 @@
 {
 }
 
-void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h)
+void ProgramVertexState::init(Context *rsc)
 {
     RsElement e = (RsElement) Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
 
@@ -382,13 +382,13 @@
     color[2] = 1.f;
     color[3] = 1.f;
 
-    updateSize(rsc, w, h);
+    updateSize(rsc);
 }
 
-void ProgramVertexState::updateSize(Context *rsc, int32_t w, int32_t h)
+void ProgramVertexState::updateSize(Context *rsc)
 {
     Matrix m;
-    m.loadOrtho(0,w, h,0, -1,1);
+    m.loadOrtho(0,rsc->getWidth(), rsc->getHeight(),0, -1,1);
     mDefaultAlloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4);
 
     m.loadIdentity();
diff --git a/rsProgramVertex.h b/rsProgramVertex.h
index 28554cc..bdac978 100644
--- a/rsProgramVertex.h
+++ b/rsProgramVertex.h
@@ -71,9 +71,9 @@
     ProgramVertexState();
     ~ProgramVertexState();
 
-    void init(Context *rsc, int32_t w, int32_t h);
+    void init(Context *rsc);
     void deinit(Context *rsc);
-    void updateSize(Context *rsc, int32_t w, int32_t h);
+    void updateSize(Context *rsc);
 
     ObjectBaseRef<ProgramVertex> mDefault;
     ObjectBaseRef<ProgramVertex> mLast;
diff --git a/rsScript.cpp b/rsScript.cpp
index 1c63c11..b0bbb22 100644
--- a/rsScript.cpp
+++ b/rsScript.cpp
@@ -97,12 +97,6 @@
     LOGE("rsi_ScriptSetType");
 }
 
-void rsi_ScriptSetInvoke(Context *rsc, const char *name, uint32_t slot)
-{
-    LOGE("rsi_ScriptSetInvoke");
-}
-
-
 void rsi_ScriptInvoke(Context *rsc, RsScript vs, uint32_t slot)
 {
     //LOGE("rsi_ScriptInvoke %i", slot);
@@ -145,7 +139,7 @@
     }
     s->setupScript();
 
-    LOGE("rsi_ScriptInvokeV, len=%i", len);
+    //LOGE("rsi_ScriptInvokeV, len=%i", len);
     const uint32_t * dPtr = (const uint32_t *)data;
     switch(len) {
     case 0:
@@ -177,11 +171,6 @@
 
 }
 
-void rsi_ScriptSetRoot(Context * rsc, bool isRoot)
-{
-    LOGE("rsi_ScriptSetRoot");
-}
-
 void rsi_ScriptSetVarI(Context *rsc, RsScript vs, uint32_t slot, int value)
 {
     Script *s = static_cast<Script *>(vs);
diff --git a/rsScript.h b/rsScript.h
index f05269a..c2fe8ef 100644
--- a/rsScript.h
+++ b/rsScript.h
@@ -27,7 +27,7 @@
 class ProgramVertex;
 class ProgramFragment;
 class ProgramRaster;
-class ProgramFragmentStore;
+class ProgramStore;
 
 #define MAX_SCRIPT_BANKS 32
 
@@ -50,7 +50,7 @@
         ObjectBaseRef<ProgramVertex> mVertex;
         ObjectBaseRef<ProgramFragment> mFragment;
         ObjectBaseRef<ProgramRaster> mRaster;
-        ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
+        ObjectBaseRef<ProgramStore> mFragmentStore;
 
         uint32_t mInvokeFunctionCount;
         InvokeFunc_t *mInvokeFunctions;
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index 45c3052..1cf8f97 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -71,6 +71,22 @@
     }
 }
 
+const Allocation *ScriptC::ptrToAllocation(const void *ptr) const
+{
+    if (!ptr) {
+        return NULL;
+    }
+    for (uint32_t ct=0; ct < mEnviroment.mFieldCount; ct++) {
+        if (!mSlots[ct].get())
+            continue;
+        if (mSlots[ct]->getPtr() == ptr) {
+            return mSlots[ct].get();
+        }
+    }
+    LOGE("ScriptC::ptrToAllocation, failed to find %p", ptr);
+    return NULL;
+}
+
 
 uint32_t ScriptC::run(Context *rsc, uint32_t launchIndex)
 {
@@ -136,7 +152,16 @@
 
 static BCCvoid* symbolLookup(BCCvoid* pContext, const BCCchar* name)
 {
-    const ScriptCState::SymbolTable_t *sym = ScriptCState::lookupSymbol(name);
+    const ScriptCState::SymbolTable_t *sym;
+    sym = ScriptCState::lookupSymbol(name);
+    if (sym) {
+        return sym->mPtr;
+    }
+    sym = ScriptCState::lookupSymbolCL(name);
+    if (sym) {
+        return sym->mPtr;
+    }
+    sym = ScriptCState::lookupSymbolGL(name);
     if (sym) {
         return sym->mPtr;
     }
@@ -151,9 +176,7 @@
     s->mBccScript = bccCreateScript();
     bccScriptBitcode(s->mBccScript, s->mEnviroment.mScriptText, s->mEnviroment.mScriptTextLength);
     bccRegisterSymbolCallback(s->mBccScript, symbolLookup, NULL);
-    LOGE("ScriptCState::runCompiler 3");
     bccCompileScript(s->mBccScript);
-    LOGE("ScriptCState::runCompiler 4");
     bccGetScriptLabel(s->mBccScript, "root", (BCCvoid**) &s->mProgram.mRoot);
     bccGetScriptLabel(s->mBccScript, "init", (BCCvoid**) &s->mProgram.mInit);
     LOGE("root %p,  init %p", s->mProgram.mRoot, s->mProgram.mInit);
@@ -183,7 +206,7 @@
 
     s->mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
     s->mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
-    s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
+    s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramStore());
     s->mEnviroment.mRaster.set(rsc->getDefaultProgramRaster());
 
     if (s->mProgram.mRoot) {
@@ -193,6 +216,7 @@
         bccGetPragmas(s->mBccScript, &pragmaCount, pragmaMax, &str[0]);
 
         for (int ct=0; ct < pragmaCount; ct+=2) {
+            //LOGE("pragme %s %s", str[ct], str[ct+1]);
             if (!strcmp(str[ct], "version")) {
                 continue;
             }
@@ -298,16 +322,6 @@
     return s;
 }
 
-void rsi_ScriptCSetDefineF(Context *rsc, const char* name, float value)
-{
-    LOGE("Error rsi_ScriptCSetDefineF");
-}
-
-void rsi_ScriptCSetDefineI32(Context *rsc, const char* name, int32_t value)
-{
-    LOGE("Error rsi_ScriptCSetDefineI");
-}
-
 }
 }
 
diff --git a/rsScriptC.h b/rsScriptC.h
index c23fb73..1aab08c 100644
--- a/rsScriptC.h
+++ b/rsScriptC.h
@@ -52,6 +52,8 @@
 
     BCCscript*    mBccScript;
 
+    const Allocation *ptrToAllocation(const void *) const;
+
     virtual void setupScript();
     virtual uint32_t run(Context *, uint32_t launchID);
 };
@@ -76,8 +78,10 @@
         const char * mName;
         void * mPtr;
     };
-    static SymbolTable_t gSyms[];
+    //static SymbolTable_t gSyms[];
     static const SymbolTable_t * lookupSymbol(const char *);
+    static const SymbolTable_t * lookupSymbolCL(const char *);
+    static const SymbolTable_t * lookupSymbolGL(const char *);
 };
 
 
diff --git a/rsScriptC_Lib.cpp b/rsScriptC_Lib.cpp
index 5cf0fdb..f976676 100644
--- a/rsScriptC_Lib.cpp
+++ b/rsScriptC_Lib.cpp
@@ -22,13 +22,6 @@
 #include "acc/acc.h"
 #include "utils/Timers.h"
 
-#define GL_GLEXT_PROTOTYPES
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
 #include <time.h>
 
 using namespace android;
@@ -40,153 +33,6 @@
     ScriptC * sc = (ScriptC *) tls->mScript
 
 
-static float SC_acospi(float v) {
-    return acosf(v)/ M_PI;
-}
-
-static float SC_asinpi(float v) {
-    return asinf(v) / M_PI;
-}
-
-static float SC_atanpi(float v) {
-    return atanf(v) / M_PI;
-}
-
-static float SC_atan2pi(float y, float x) {
-    return atan2f(y, x) / M_PI;
-}
-
-static float SC_cospi(float v) {
-    return cosf(v * M_PI);
-}
-
-static float SC_exp10(float v) {
-    return pow(10.f, v);
-
-}
-
-static float SC_fract(float v, int *iptr) {
-    int i = (int)floor(v);
-    iptr[0] = i;
-    return fmin(v - i, 0x1.fffffep-1f);
-}
-
-static float SC_log2(float v) {
-    return log10(v) / log10(2.f);
-}
-
-static float SC_pown(float v, int p) {
-    return powf(v, (float)p);
-}
-
-static float SC_powr(float v, float p) {
-    return powf(v, p);
-}
-
-float SC_rootn(float v, int r) {
-    return pow(v, 1.f / r);
-}
-
-float SC_rsqrt(float v) {
-    return 1.f / sqrtf(v);
-}
-
-float SC_sincos(float v, float *cosptr) {
-    *cosptr = cosf(v);
-    return sinf(v);
-}
-
-static float SC_sinpi(float v) {
-    return sinf(v * M_PI);
-}
-
-static float SC_tanpi(float v) {
-    return tanf(v * M_PI);
-}
-
-    //{ "logb", (void *)& },
-    //{ "mad", (void *)& },
-    //{ "nan", (void *)& },
-    //{ "tgamma", (void *)& },
-
-//////////////////////////////////////////////////////////////////////////////
-// Integer
-//////////////////////////////////////////////////////////////////////////////
-
-
-static uint32_t SC_abs_i32(int32_t v) {return abs(v);}
-static uint16_t SC_abs_i16(int16_t v) {return (uint16_t)abs(v);}
-static uint8_t SC_abs_i8(int8_t v) {return (uint8_t)abs(v);}
-
-static uint32_t SC_clz_u32(uint32_t v) {return __builtin_clz(v);}
-static uint16_t SC_clz_u16(uint16_t v) {return (uint16_t)__builtin_clz(v);}
-static uint8_t SC_clz_u8(uint8_t v) {return (uint8_t)__builtin_clz(v);}
-static int32_t SC_clz_i32(int32_t v) {return (int32_t)__builtin_clz((uint32_t)v);}
-static int16_t SC_clz_i16(int16_t v) {return (int16_t)__builtin_clz(v);}
-static int8_t SC_clz_i8(int8_t v) {return (int8_t)__builtin_clz(v);}
-
-static uint32_t SC_max_u32(uint32_t v, uint32_t v2) {return rsMax(v, v2);}
-static uint16_t SC_max_u16(uint16_t v, uint16_t v2) {return rsMax(v, v2);}
-static uint8_t SC_max_u8(uint8_t v, uint8_t v2) {return rsMax(v, v2);}
-static int32_t SC_max_i32(int32_t v, int32_t v2) {return rsMax(v, v2);}
-static int16_t SC_max_i16(int16_t v, int16_t v2) {return rsMax(v, v2);}
-static int8_t SC_max_i8(int8_t v, int8_t v2) {return rsMax(v, v2);}
-
-static uint32_t SC_min_u32(uint32_t v, uint32_t v2) {return rsMin(v, v2);}
-static uint16_t SC_min_u16(uint16_t v, uint16_t v2) {return rsMin(v, v2);}
-static uint8_t SC_min_u8(uint8_t v, uint8_t v2) {return rsMin(v, v2);}
-static int32_t SC_min_i32(int32_t v, int32_t v2) {return rsMin(v, v2);}
-static int16_t SC_min_i16(int16_t v, int16_t v2) {return rsMin(v, v2);}
-static int8_t SC_min_i8(int8_t v, int8_t v2) {return rsMin(v, v2);}
-
-//////////////////////////////////////////////////////////////////////////////
-// Float util
-//////////////////////////////////////////////////////////////////////////////
-
-static float SC_clamp_f32(float amount, float low, float high)
-{
-    return amount < low ? low : (amount > high ? high : amount);
-}
-
-static float SC_degrees(float radians)
-{
-    return radians * (180.f / M_PI);
-}
-
-static float SC_max_f32(float v, float v2)
-{
-    return rsMax(v, v2);
-}
-
-static float SC_min_f32(float v, float v2)
-{
-    return rsMin(v, v2);
-}
-
-static float SC_mix_f32(float start, float stop, float amount)
-{
-    //LOGE("lerpf %f  %f  %f", start, stop, amount);
-    return start + (stop - start) * amount;
-}
-
-static float SC_radians(float degrees)
-{
-    return degrees * (M_PI / 180.f);
-}
-
-static float SC_step_f32(float edge, float v)
-{
-    if (v < edge) return 0.f;
-    return 1.f;
-}
-
-static float SC_sign_f32(float value)
-{
-    if (value > 0) return 1.f;
-    if (value < 0) return -1.f;
-    return value;
-}
-
 
 
 //////////////////////////////////////////////////////////////////////////////
@@ -211,23 +57,6 @@
     float y;
 } vec2_t;
 
-//////////////////////////////////////////////////////////////////////////////
-// IO routines
-//////////////////////////////////////////////////////////////////////////////
-
-static float* SC_loadSimpleMeshVerticesF(RsSimpleMesh mesh, uint32_t idx)
-{
-    SimpleMesh *tm = static_cast<SimpleMesh *>(mesh);
-    void *vp = tm->mVertexBuffers[idx]->getPtr();;
-    return static_cast<float *>(vp);
-}
-
-static void SC_updateSimpleMesh(RsSimpleMesh mesh)
-{
-    GET_TLS();
-    SimpleMesh *sm = static_cast<SimpleMesh *>(mesh);
-    sm->uploadAll(rsc);
-}
 
 //////////////////////////////////////////////////////////////////////////////
 // Vec3 routines
@@ -620,255 +449,6 @@
 }
 
 
-
-//////////////////////////////////////////////////////////////////////////////
-// Context
-//////////////////////////////////////////////////////////////////////////////
-
-static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
-{
-    GET_TLS();
-    rsi_ProgramBindTexture(rsc,
-                           static_cast<ProgramFragment *>(vpf),
-                           slot,
-                           static_cast<Allocation *>(va));
-
-}
-
-static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
-{
-    GET_TLS();
-    rsi_ProgramBindSampler(rsc,
-                           static_cast<ProgramFragment *>(vpf),
-                           slot,
-                           static_cast<Sampler *>(vs));
-
-}
-
-static void SC_bindProgramFragmentStore(RsProgramFragmentStore pfs)
-{
-    GET_TLS();
-    rsi_ContextBindProgramFragmentStore(rsc, pfs);
-}
-
-static void SC_bindProgramFragment(RsProgramFragment pf)
-{
-    GET_TLS();
-    rsi_ContextBindProgramFragment(rsc, pf);
-}
-
-static void SC_bindProgramVertex(RsProgramVertex pv)
-{
-    GET_TLS();
-    rsi_ContextBindProgramVertex(rsc, pv);
-}
-
-static void SC_bindProgramRaster(RsProgramRaster pv)
-{
-    GET_TLS();
-    rsi_ContextBindProgramRaster(rsc, pv);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// VP
-//////////////////////////////////////////////////////////////////////////////
-
-static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
-{
-    GET_TLS();
-    rsc->getVertex()->setModelviewMatrix(m);
-}
-
-static void SC_vpLoadTextureMatrix(const rsc_Matrix *m)
-{
-    GET_TLS();
-    rsc->getVertex()->setTextureMatrix(m);
-}
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-// Drawing
-//////////////////////////////////////////////////////////////////////////////
-
-static void SC_drawLine(float x1, float y1, float z1,
-                        float x2, float y2, float z2)
-{
-    GET_TLS();
-    if (!rsc->setupCheck()) {
-        return;
-    }
-
-    float vtx[] = { x1, y1, z1, x2, y2, z2 };
-    VertexArray va;
-    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
-    if (rsc->checkVersion2_0()) {
-        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
-    } else {
-        va.setupGL(rsc, &rsc->mStateVertexArray);
-    }
-
-    glDrawArrays(GL_LINES, 0, 2);
-}
-
-static void SC_drawPoint(float x, float y, float z)
-{
-    GET_TLS();
-    if (!rsc->setupCheck()) {
-        return;
-    }
-
-    float vtx[] = { x, y, z };
-
-    VertexArray va;
-    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
-    if (rsc->checkVersion2_0()) {
-        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
-    } else {
-        va.setupGL(rsc, &rsc->mStateVertexArray);
-    }
-
-    glDrawArrays(GL_POINTS, 0, 1);
-}
-
-static void SC_drawQuadTexCoords(float x1, float y1, float z1,
-                                 float u1, float v1,
-                                 float x2, float y2, float z2,
-                                 float u2, float v2,
-                                 float x3, float y3, float z3,
-                                 float u3, float v3,
-                                 float x4, float y4, float z4,
-                                 float u4, float v4)
-{
-    GET_TLS();
-    if (!rsc->setupCheck()) {
-        return;
-    }
-
-    //LOGE("Quad");
-    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
-    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
-    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
-    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
-
-    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
-    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
-
-    VertexArray va;
-    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
-    va.addLegacy(GL_FLOAT, 2, 8, RS_KIND_TEXTURE, false, (uint32_t)tex);
-    if (rsc->checkVersion2_0()) {
-        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
-    } else {
-        va.setupGL(rsc, &rsc->mStateVertexArray);
-    }
-
-
-    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-}
-
-static void SC_drawQuad(float x1, float y1, float z1,
-                        float x2, float y2, float z2,
-                        float x3, float y3, float z3,
-                        float x4, float y4, float z4)
-{
-    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
-                         x2, y2, z2, 1, 1,
-                         x3, y3, z3, 1, 0,
-                         x4, y4, z4, 0, 0);
-}
-
-static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
-{
-    GET_TLS();
-    ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
-    rsc->setVertex(rsc->getDefaultProgramVertex());
-    //rsc->setupCheck();
-
-    //GLint crop[4] = {0, h, w, -h};
-
-    float sh = rsc->getHeight();
-
-    SC_drawQuad(x,   sh - y,     z,
-                x+w, sh - y,     z,
-                x+w, sh - (y+h), z,
-                x,   sh - (y+h), z);
-    rsc->setVertex((ProgramVertex *)tmp.get());
-}
-
-static void SC_drawSpriteScreenspaceCropped(float x, float y, float z, float w, float h,
-        float cx0, float cy0, float cx1, float cy1)
-{
-    GET_TLS();
-    if (!rsc->setupCheck()) {
-        return;
-    }
-
-    GLint crop[4] = {cx0, cy0, cx1, cy1};
-    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
-    glDrawTexfOES(x, y, z, w, h);
-}
-
-static void SC_drawSprite(float x, float y, float z, float w, float h)
-{
-    GET_TLS();
-    float vin[3] = {x, y, z};
-    float vout[4];
-
-    //LOGE("ds  in %f %f %f", x, y, z);
-    rsc->getVertex()->transformToScreen(rsc, vout, vin);
-    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
-    vout[0] /= vout[3];
-    vout[1] /= vout[3];
-    vout[2] /= vout[3];
-
-    vout[0] *= rsc->getWidth() / 2;
-    vout[1] *= rsc->getHeight() / 2;
-    vout[0] += rsc->getWidth() / 2;
-    vout[1] += rsc->getHeight() / 2;
-
-    vout[0] -= w/2;
-    vout[1] -= h/2;
-
-    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
-
-    // U, V, W, H
-    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
-    //rsc->setupCheck();
-}
-
-
-static void SC_drawRect(float x1, float y1,
-                        float x2, float y2, float z)
-{
-    //LOGE("SC_drawRect %f,%f  %f,%f  %f", x1, y1, x2, y2, z);
-    SC_drawQuad(x1, y2, z,
-                x2, y2, z,
-                x2, y1, z,
-                x1, y1, z);
-}
-
-static void SC_drawSimpleMesh(RsSimpleMesh vsm)
-{
-    GET_TLS();
-    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
-    if (!rsc->setupCheck()) {
-        return;
-    }
-    sm->render(rsc);
-}
-
-static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
-{
-    GET_TLS();
-    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
-    if (!rsc->setupCheck()) {
-        return;
-    }
-    sm->renderRange(rsc, start, len);
-}
-
-
 //////////////////////////////////////////////////////////////////////////////
 //
 //////////////////////////////////////////////////////////////////////////////
@@ -911,131 +491,6 @@
 }
 
 
-static void SC_color(float r, float g, float b, float a)
-{
-    GET_TLS();
-    rsc->mStateVertex.color[0] = r;
-    rsc->mStateVertex.color[1] = g;
-    rsc->mStateVertex.color[2] = b;
-    rsc->mStateVertex.color[3] = a;
-    if (!rsc->checkVersion2_0()) {
-        glColor4f(r, g, b, a);
-    }
-}
-
-static void SC_pointAttenuation(float a, float b, float c)
-{
-    GLfloat params[] = { a, b, c };
-    glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
-}
-
-static void SC_hsbToRgb(float h, float s, float b, float* rgb)
-{
-    float red = 0.0f;
-    float green = 0.0f;
-    float blue = 0.0f;
-
-    float x = h;
-    float y = s;
-    float z = b;
-
-    float hf = (x - (int) x) * 6.0f;
-    int ihf = (int) hf;
-    float f = hf - ihf;
-    float pv = z * (1.0f - y);
-    float qv = z * (1.0f - y * f);
-    float tv = z * (1.0f - y * (1.0f - f));
-
-    switch (ihf) {
-        case 0:         // Red is the dominant color
-            red = z;
-            green = tv;
-            blue = pv;
-            break;
-        case 1:         // Green is the dominant color
-            red = qv;
-            green = z;
-            blue = pv;
-            break;
-        case 2:
-            red = pv;
-            green = z;
-            blue = tv;
-            break;
-        case 3:         // Blue is the dominant color
-            red = pv;
-            green = qv;
-            blue = z;
-            break;
-        case 4:
-            red = tv;
-            green = pv;
-            blue = z;
-            break;
-        case 5:         // Red is the dominant color
-            red = z;
-            green = pv;
-            blue = qv;
-            break;
-    }
-
-    rgb[0] = red;
-    rgb[1] = green;
-    rgb[2] = blue;
-}
-
-static int SC_hsbToAbgr(float h, float s, float b, float a)
-{
-    //LOGE("hsb a %f, %f, %f    %f", h, s, b, a);
-    float rgb[3];
-    SC_hsbToRgb(h, s, b, rgb);
-    //LOGE("rgb  %f, %f, %f ", rgb[0], rgb[1], rgb[2]);
-    return int(a      * 255.0f) << 24 |
-           int(rgb[2] * 255.0f) << 16 |
-           int(rgb[1] * 255.0f) <<  8 |
-           int(rgb[0] * 255.0f);
-}
-
-static void SC_hsb(float h, float s, float b, float a)
-{
-    GET_TLS();
-    float rgb[3];
-    SC_hsbToRgb(h, s, b, rgb);
-    if (rsc->checkVersion2_0()) {
-        glVertexAttrib4f(1, rgb[0], rgb[1], rgb[2], a);
-    } else {
-        glColor4f(rgb[0], rgb[1], rgb[2], a);
-    }
-}
-
-static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
-{
-    GET_TLS();
-    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
-}
-
-static void SC_uploadToBufferObject(RsAllocation va)
-{
-    GET_TLS();
-    rsi_AllocationUploadToBufferObject(rsc, va);
-}
-
-static void SC_syncToGL(RsAllocation va)
-{
-    GET_TLS();
-    Allocation *a = static_cast<Allocation *>(va);
-
-}
-
-static void SC_ClearColor(float r, float g, float b, float a)
-{
-    //LOGE("c %f %f %f %f", r, g, b, a);
-    GET_TLS();
-    sc->mEnviroment.mClearColor[0] = r;
-    sc->mEnviroment.mClearColor[1] = g;
-    sc->mEnviroment.mClearColor[2] = b;
-    sc->mEnviroment.mClearColor[3] = a;
-}
 
 static void SC_debugF(const char *s, float f)
 {
@@ -1057,18 +512,6 @@
     LOGE("%s 0x%x", s, i);
 }
 
-static uint32_t SC_getWidth()
-{
-    GET_TLS();
-    return rsc->getWidth();
-}
-
-static uint32_t SC_getHeight()
-{
-    GET_TLS();
-    return rsc->getHeight();
-}
-
 static uchar4 SC_convertColorTo8888_f3(float r, float g, float b) {
     uchar4 t;
     t.f[0] = (uint8_t)(r * 255.f);
@@ -1120,6 +563,14 @@
     return a / b;
 }
 
+int SC_getAllocation(const void *ptr)
+{
+    GET_TLS();
+    const Allocation *alloc = sc->ptrToAllocation(ptr);
+    return (int)alloc;
+}
+
+
 //////////////////////////////////////////////////////////////////////////////
 // Class implementation
 //////////////////////////////////////////////////////////////////////////////
@@ -1141,115 +592,9 @@
 //                 ::= f  # float
 //                 ::= d  # double
 
-ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
+static ScriptCState::SymbolTable_t gSyms[] = {
     { "__divsi3", (void *)&SC_divsi3 },
 
-    // IO
-    { "loadSimpleMeshVerticesF", (void *)&SC_loadSimpleMeshVerticesF },
-    { "updateSimpleMesh", (void *)&SC_updateSimpleMesh },
-
-    // OpenCL math
-    { "_Z4acosf", (void *)&acosf },
-    { "_Z5acoshf", (void *)&acoshf },
-    { "_Z6acospif", (void *)&SC_acospi },
-    { "_Z4asinf", (void *)&asinf },
-    { "_Z5asinhf", (void *)&asinhf },
-    { "_Z6asinpif", (void *)&SC_asinpi },
-    { "_Z4atanf", (void *)&atanf },
-    { "_Z5atan2f", (void *)&atan2f },
-    { "_Z6atanpif", (void *)&SC_atanpi },
-    { "_Z7atan2pif", (void *)&SC_atan2pi },
-    { "_Z4cbrtf", (void *)&cbrtf },
-    { "_Z4ceilf", (void *)&ceilf },
-    { "_Z8copysignff", (void *)&copysignf },
-    { "_Z3cosf", (void *)&cosf },
-    { "_Z4coshf", (void *)&coshf },
-    { "_Z5cospif", (void *)&SC_cospi },
-    { "_Z4erfcf", (void *)&erfcf },
-    { "_Z3erff", (void *)&erff },
-    { "_Z3expf", (void *)&expf },
-    { "_Z4exp2f", (void *)&exp2f },
-    { "_Z5exp10f", (void *)&SC_exp10 },
-    { "_Z5expm1f", (void *)&expm1f },
-    { "_Z4fabsf", (void *)&fabsf },
-    { "_Z4fdimff", (void *)&fdimf },
-    { "_Z5floorf", (void *)&floorf },
-    { "_Z3fmafff", (void *)&fmaf },
-    { "_Z4fmaxff", (void *)&fmaxf },
-    { "_Z4fminff", (void *)&fminf },  // float fmin(float, float)
-    { "_Z4fmodff", (void *)&fmodf },
-    { "_Z5fractfPf", (void *)&SC_fract },
-    { "_Z5frexpfPi", (void *)&frexpf },
-    { "_Z5hypotff", (void *)&hypotf },
-    { "_Z5ilogbf", (void *)&ilogbf },
-    { "_Z5ldexpfi", (void *)&ldexpf },
-    { "_Z6lgammaf", (void *)&lgammaf },
-    { "_Z3logf", (void *)&logf },
-    { "_Z4log2f", (void *)&SC_log2 },
-    { "_Z5log10f", (void *)&log10f },
-    { "_Z5log1pf", (void *)&log1pf },
-    //{ "logb", (void *)& },
-    //{ "mad", (void *)& },
-    { "modf", (void *)&modff },
-    //{ "nan", (void *)& },
-    { "_Z9nextafterff", (void *)&nextafterf },
-    { "_Z3powff", (void *)&powf },
-    { "_Z4pownfi", (void *)&SC_pown },
-    { "_Z4powrff", (void *)&SC_powr },
-    { "_Z9remainderff", (void *)&remainderf },
-    { "remquo", (void *)&remquof },
-    { "_Z4rintf", (void *)&rintf },
-    { "_Z5rootnfi", (void *)&SC_rootn },
-    { "_Z5roundf", (void *)&roundf },
-    { "_Z5rsqrtf", (void *)&SC_rsqrt },
-    { "_Z3sinf", (void *)&sinf },
-    { "sincos", (void *)&SC_sincos },
-    { "_Z4sinhf", (void *)&sinhf },
-    { "_Z5sinpif", (void *)&SC_sinpi },
-    { "_Z4sqrtf", (void *)&sqrtf },
-    { "_Z3tanf", (void *)&tanf },
-    { "_Z4tanhf", (void *)&tanhf },
-    { "_Z5tanpif", (void *)&SC_tanpi },
-    //{ "tgamma", (void *)& },
-    { "_Z5truncf", (void *)&truncf },
-
-    // OpenCL Int
-    { "_Z3absi", (void *)&SC_abs_i32 },
-    { "_Z3abss", (void *)&SC_abs_i16 },
-    { "_Z3absc", (void *)&SC_abs_i8 },
-    { "_Z3clzj", (void *)&SC_clz_u32 },
-    { "_Z3clzt", (void *)&SC_clz_u16 },
-    { "_Z3clzh", (void *)&SC_clz_u8 },
-    { "_Z3clzi", (void *)&SC_clz_i32 },
-    { "_Z3clzs", (void *)&SC_clz_i16 },
-    { "_Z3clzc", (void *)&SC_clz_i8 },
-    { "_Z3maxjj", (void *)&SC_max_u32 },
-    { "_Z3maxtt", (void *)&SC_max_u16 },
-    { "_Z3maxhh", (void *)&SC_max_u8 },
-    { "_Z3maxii", (void *)&SC_max_i32 },
-    { "_Z3maxss", (void *)&SC_max_i16 },
-    { "_Z3maxcc", (void *)&SC_max_i8 },
-    { "_Z3minjj", (void *)&SC_min_u32 },
-    { "_Z3mintt", (void *)&SC_min_u16 },
-    { "_Z3minhh", (void *)&SC_min_u8 },
-    { "_Z3minii", (void *)&SC_min_i32 },
-    { "_Z3minss", (void *)&SC_min_i16 },
-    { "_Z3mincc", (void *)&SC_min_i8 },
-
-    // OpenCL 6.11.4
-    { "_Z5clampfff", (void *)&SC_clamp_f32 },
-    { "_Z7degreesf", (void *)&SC_degrees },
-    { "_Z3maxff", (void *)&SC_max_f32 },
-    { "_Z3minff", (void *)&SC_min_f32 },
-    { "_Z3mixfff", (void *)&SC_mix_f32 },
-    { "_Z7radiansf", (void *)&SC_radians },
-    { "_Z4stepff", (void *)&SC_step_f32 },
-    //{ "smoothstep", (void *)& },
-    { "_Z4signf", (void *)&SC_sign_f32 },
-
-
-
-
     { "modf", (void *)&fmod },
     { "_Z4fracf", (void *)&SC_frac },
     //{ "sinf_fast", (void *)&SC_sinf_fast },
@@ -1314,19 +659,6 @@
     { "vec4Dot", (void *)&SC_vec4Dot },
     { "vec4Scale", (void *)&SC_vec4Scale },
 
-    // context
-    { "bindProgramFragment", (void *)&SC_bindProgramFragment },
-    { "bindProgramFragmentStore", (void *)&SC_bindProgramFragmentStore },
-    { "bindProgramStore", (void *)&SC_bindProgramFragmentStore },
-    { "bindProgramVertex", (void *)&SC_bindProgramVertex },
-    { "bindProgramRaster", (void *)&SC_bindProgramRaster },
-    { "bindSampler", (void *)&SC_bindSampler },
-    { "bindTexture", (void *)&SC_bindTexture },
-
-    // vp
-    { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix },
-    { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix },
-
     // allocation
     { "allocGetDimX", (void *)&SC_allocGetDimX },
     { "allocGetDimY", (void *)&SC_allocGetDimY },
@@ -1334,35 +666,8 @@
     { "allocGetDimLOD", (void *)&SC_allocGetDimLOD },
     { "allocGetDimFaces", (void *)&SC_allocGetDimFaces },
 
-    // drawing
-    { "drawRect", (void *)&SC_drawRect },
-    { "drawQuad", (void *)&SC_drawQuad },
-    { "drawQuadTexCoords", (void *)&SC_drawQuadTexCoords },
-    { "drawSprite", (void *)&SC_drawSprite },
-    { "drawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace },
-    { "drawSpriteScreenspaceCropped", (void *)&SC_drawSpriteScreenspaceCropped },
-    { "drawLine", (void *)&SC_drawLine },
-    { "drawPoint", (void *)&SC_drawPoint },
-    { "drawSimpleMesh", (void *)&SC_drawSimpleMesh },
-    { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange },
-
 
     // misc
-    { "pfClearColor", (void *)&SC_ClearColor },
-    { "color", (void *)&SC_color },
-    { "hsb", (void *)&SC_hsb },
-    { "hsbToRgb", (void *)&SC_hsbToRgb },
-    { "hsbToAbgr", (void *)&SC_hsbToAbgr },
-    { "pointAttenuation", (void *)&SC_pointAttenuation },
-
-    { "uploadToTexture", (void *)&SC_uploadToTexture },
-    { "uploadToBufferObject", (void *)&SC_uploadToBufferObject },
-
-    { "syncToGL", (void *)&SC_syncToGL },
-
-    { "getWidth", (void *)&SC_getWidth },
-    { "getHeight", (void *)&SC_getHeight },
-
     { "sendToClient", (void *)&SC_toClient },
 
     { "_Z18convertColorTo8888fff", (void *)&SC_convertColorTo8888_f3 },
@@ -1377,6 +682,8 @@
     { "debugPi", (void *)&SC_debugPi },
 
     { "scriptCall", (void *)&SC_scriptCall },
+    { "rsGetAllocation", (void *)&SC_getAllocation },
+
 
     { NULL, NULL }
 };
diff --git a/rsScriptC_LibCL.cpp b/rsScriptC_LibCL.cpp
new file mode 100644
index 0000000..ce8e7b2
--- /dev/null
+++ b/rsScriptC_LibCL.cpp
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+#include "rsScriptC.h"
+
+// Implements rs_cl.rsh
+
+
+using namespace android;
+using namespace android::renderscript;
+
+
+static float SC_acospi(float v) {
+    return acosf(v)/ M_PI;
+}
+
+static float SC_asinpi(float v) {
+    return asinf(v) / M_PI;
+}
+
+static float SC_atanpi(float v) {
+    return atanf(v) / M_PI;
+}
+
+static float SC_atan2pi(float y, float x) {
+    return atan2f(y, x) / M_PI;
+}
+
+static float SC_cospi(float v) {
+    return cosf(v * M_PI);
+}
+
+static float SC_exp10(float v) {
+    return pow(10.f, v);
+
+}
+
+static float SC_fract(float v, int *iptr) {
+    int i = (int)floor(v);
+    iptr[0] = i;
+    return fmin(v - i, 0x1.fffffep-1f);
+}
+
+static float SC_log2(float v) {
+    return log10(v) / log10(2.f);
+}
+
+static float SC_pown(float v, int p) {
+    return powf(v, (float)p);
+}
+
+static float SC_powr(float v, float p) {
+    return powf(v, p);
+}
+
+float SC_rootn(float v, int r) {
+    return pow(v, 1.f / r);
+}
+
+float SC_rsqrt(float v) {
+    return 1.f / sqrtf(v);
+}
+
+float SC_sincos(float v, float *cosptr) {
+    *cosptr = cosf(v);
+    return sinf(v);
+}
+
+static float SC_sinpi(float v) {
+    return sinf(v * M_PI);
+}
+
+static float SC_tanpi(float v) {
+    return tanf(v * M_PI);
+}
+
+    //{ "logb", (void *)& },
+    //{ "mad", (void *)& },
+    //{ "nan", (void *)& },
+    //{ "tgamma", (void *)& },
+
+//////////////////////////////////////////////////////////////////////////////
+// Integer
+//////////////////////////////////////////////////////////////////////////////
+
+
+static uint32_t SC_abs_i32(int32_t v) {return abs(v);}
+static uint16_t SC_abs_i16(int16_t v) {return (uint16_t)abs(v);}
+static uint8_t SC_abs_i8(int8_t v) {return (uint8_t)abs(v);}
+
+static uint32_t SC_clz_u32(uint32_t v) {return __builtin_clz(v);}
+static uint16_t SC_clz_u16(uint16_t v) {return (uint16_t)__builtin_clz(v);}
+static uint8_t SC_clz_u8(uint8_t v) {return (uint8_t)__builtin_clz(v);}
+static int32_t SC_clz_i32(int32_t v) {return (int32_t)__builtin_clz((uint32_t)v);}
+static int16_t SC_clz_i16(int16_t v) {return (int16_t)__builtin_clz(v);}
+static int8_t SC_clz_i8(int8_t v) {return (int8_t)__builtin_clz(v);}
+
+static uint32_t SC_max_u32(uint32_t v, uint32_t v2) {return rsMax(v, v2);}
+static uint16_t SC_max_u16(uint16_t v, uint16_t v2) {return rsMax(v, v2);}
+static uint8_t SC_max_u8(uint8_t v, uint8_t v2) {return rsMax(v, v2);}
+static int32_t SC_max_i32(int32_t v, int32_t v2) {return rsMax(v, v2);}
+static int16_t SC_max_i16(int16_t v, int16_t v2) {return rsMax(v, v2);}
+static int8_t SC_max_i8(int8_t v, int8_t v2) {return rsMax(v, v2);}
+
+static uint32_t SC_min_u32(uint32_t v, uint32_t v2) {return rsMin(v, v2);}
+static uint16_t SC_min_u16(uint16_t v, uint16_t v2) {return rsMin(v, v2);}
+static uint8_t SC_min_u8(uint8_t v, uint8_t v2) {return rsMin(v, v2);}
+static int32_t SC_min_i32(int32_t v, int32_t v2) {return rsMin(v, v2);}
+static int16_t SC_min_i16(int16_t v, int16_t v2) {return rsMin(v, v2);}
+static int8_t SC_min_i8(int8_t v, int8_t v2) {return rsMin(v, v2);}
+
+//////////////////////////////////////////////////////////////////////////////
+// Float util
+//////////////////////////////////////////////////////////////////////////////
+
+static float SC_clamp_f32(float amount, float low, float high)
+{
+    return amount < low ? low : (amount > high ? high : amount);
+}
+
+static float SC_degrees(float radians)
+{
+    return radians * (180.f / M_PI);
+}
+
+static float SC_max_f32(float v, float v2)
+{
+    return rsMax(v, v2);
+}
+
+static float SC_min_f32(float v, float v2)
+{
+    return rsMin(v, v2);
+}
+
+static float SC_mix_f32(float start, float stop, float amount)
+{
+    //LOGE("lerpf %f  %f  %f", start, stop, amount);
+    return start + (stop - start) * amount;
+}
+
+static float SC_radians(float degrees)
+{
+    return degrees * (M_PI / 180.f);
+}
+
+static float SC_step_f32(float edge, float v)
+{
+    if (v < edge) return 0.f;
+    return 1.f;
+}
+
+static float SC_sign_f32(float value)
+{
+    if (value > 0) return 1.f;
+    if (value < 0) return -1.f;
+    return value;
+}
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Class implementation
+//////////////////////////////////////////////////////////////////////////////
+
+// llvm name mangling ref
+//  <builtin-type> ::= v  # void
+//                 ::= b  # bool
+//                 ::= c  # char
+//                 ::= a  # signed char
+//                 ::= h  # unsigned char
+//                 ::= s  # short
+//                 ::= t  # unsigned short
+//                 ::= i  # int
+//                 ::= j  # unsigned int
+//                 ::= l  # long
+//                 ::= m  # unsigned long
+//                 ::= x  # long long, __int64
+//                 ::= y  # unsigned long long, __int64
+//                 ::= f  # float
+//                 ::= d  # double
+
+static ScriptCState::SymbolTable_t gSyms[] = {
+    // OpenCL math
+    { "_Z4acosf", (void *)&acosf },
+    { "_Z5acoshf", (void *)&acoshf },
+    { "_Z6acospif", (void *)&SC_acospi },
+    { "_Z4asinf", (void *)&asinf },
+    { "_Z5asinhf", (void *)&asinhf },
+    { "_Z6asinpif", (void *)&SC_asinpi },
+    { "_Z4atanf", (void *)&atanf },
+    { "_Z5atan2f", (void *)&atan2f },
+    { "_Z6atanpif", (void *)&SC_atanpi },
+    { "_Z7atan2pif", (void *)&SC_atan2pi },
+    { "_Z4cbrtf", (void *)&cbrtf },
+    { "_Z4ceilf", (void *)&ceilf },
+    { "_Z8copysignff", (void *)&copysignf },
+    { "_Z3cosf", (void *)&cosf },
+    { "_Z4coshf", (void *)&coshf },
+    { "_Z5cospif", (void *)&SC_cospi },
+    { "_Z4erfcf", (void *)&erfcf },
+    { "_Z3erff", (void *)&erff },
+    { "_Z3expf", (void *)&expf },
+    { "_Z4exp2f", (void *)&exp2f },
+    { "_Z5exp10f", (void *)&SC_exp10 },
+    { "_Z5expm1f", (void *)&expm1f },
+    { "_Z4fabsf", (void *)&fabsf },
+    { "_Z4fdimff", (void *)&fdimf },
+    { "_Z5floorf", (void *)&floorf },
+    { "_Z3fmafff", (void *)&fmaf },
+    { "_Z4fmaxff", (void *)&fmaxf },
+    { "_Z4fminff", (void *)&fminf },  // float fmin(float, float)
+    { "_Z4fmodff", (void *)&fmodf },
+    { "_Z5fractfPf", (void *)&SC_fract },
+    { "_Z5frexpfPi", (void *)&frexpf },
+    { "_Z5hypotff", (void *)&hypotf },
+    { "_Z5ilogbf", (void *)&ilogbf },
+    { "_Z5ldexpfi", (void *)&ldexpf },
+    { "_Z6lgammaf", (void *)&lgammaf },
+    { "_Z3logf", (void *)&logf },
+    { "_Z4log2f", (void *)&SC_log2 },
+    { "_Z5log10f", (void *)&log10f },
+    { "_Z5log1pf", (void *)&log1pf },
+    //{ "logb", (void *)& },
+    //{ "mad", (void *)& },
+    { "modf", (void *)&modff },
+    //{ "nan", (void *)& },
+    { "_Z9nextafterff", (void *)&nextafterf },
+    { "_Z3powff", (void *)&powf },
+    { "_Z4pownfi", (void *)&SC_pown },
+    { "_Z4powrff", (void *)&SC_powr },
+    { "_Z9remainderff", (void *)&remainderf },
+    { "remquo", (void *)&remquof },
+    { "_Z4rintf", (void *)&rintf },
+    { "_Z5rootnfi", (void *)&SC_rootn },
+    { "_Z5roundf", (void *)&roundf },
+    { "_Z5rsqrtf", (void *)&SC_rsqrt },
+    { "_Z3sinf", (void *)&sinf },
+    { "sincos", (void *)&SC_sincos },
+    { "_Z4sinhf", (void *)&sinhf },
+    { "_Z5sinpif", (void *)&SC_sinpi },
+    { "_Z4sqrtf", (void *)&sqrtf },
+    { "_Z3tanf", (void *)&tanf },
+    { "_Z4tanhf", (void *)&tanhf },
+    { "_Z5tanpif", (void *)&SC_tanpi },
+    //{ "tgamma", (void *)& },
+    { "_Z5truncf", (void *)&truncf },
+
+    // OpenCL Int
+    { "_Z3absi", (void *)&SC_abs_i32 },
+    { "_Z3abss", (void *)&SC_abs_i16 },
+    { "_Z3absc", (void *)&SC_abs_i8 },
+    { "_Z3clzj", (void *)&SC_clz_u32 },
+    { "_Z3clzt", (void *)&SC_clz_u16 },
+    { "_Z3clzh", (void *)&SC_clz_u8 },
+    { "_Z3clzi", (void *)&SC_clz_i32 },
+    { "_Z3clzs", (void *)&SC_clz_i16 },
+    { "_Z3clzc", (void *)&SC_clz_i8 },
+    { "_Z3maxjj", (void *)&SC_max_u32 },
+    { "_Z3maxtt", (void *)&SC_max_u16 },
+    { "_Z3maxhh", (void *)&SC_max_u8 },
+    { "_Z3maxii", (void *)&SC_max_i32 },
+    { "_Z3maxss", (void *)&SC_max_i16 },
+    { "_Z3maxcc", (void *)&SC_max_i8 },
+    { "_Z3minjj", (void *)&SC_min_u32 },
+    { "_Z3mintt", (void *)&SC_min_u16 },
+    { "_Z3minhh", (void *)&SC_min_u8 },
+    { "_Z3minii", (void *)&SC_min_i32 },
+    { "_Z3minss", (void *)&SC_min_i16 },
+    { "_Z3mincc", (void *)&SC_min_i8 },
+
+    // OpenCL 6.11.4
+    { "_Z5clampfff", (void *)&SC_clamp_f32 },
+    { "_Z7degreesf", (void *)&SC_degrees },
+    { "_Z3maxff", (void *)&SC_max_f32 },
+    { "_Z3minff", (void *)&SC_min_f32 },
+    { "_Z3mixfff", (void *)&SC_mix_f32 },
+    { "_Z7radiansf", (void *)&SC_radians },
+    { "_Z4stepff", (void *)&SC_step_f32 },
+    //{ "smoothstep", (void *)& },
+    { "_Z4signf", (void *)&SC_sign_f32 },
+
+    { NULL, NULL }
+};
+
+const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolCL(const char *sym)
+{
+    ScriptCState::SymbolTable_t *syms = gSyms;
+
+    while (syms->mPtr) {
+        if (!strcmp(syms->mName, sym)) {
+            return syms;
+        }
+        syms++;
+    }
+    return NULL;
+}
+
diff --git a/rsScriptC_LibGL.cpp b/rsScriptC_LibGL.cpp
new file mode 100644
index 0000000..c9d5034
--- /dev/null
+++ b/rsScriptC_LibGL.cpp
@@ -0,0 +1,528 @@
+/*
+ * 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"
+#include "rsNoise.h"
+
+#include "acc/acc.h"
+#include "utils/Timers.h"
+
+#define GL_GLEXT_PROTOTYPES
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <time.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+#define GET_TLS()  Context::ScriptTLSStruct * tls = \
+    (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
+    Context * rsc = tls->mContext; \
+    ScriptC * sc = (ScriptC *) tls->mScript
+
+
+//////////////////////////////////////////////////////////////////////////////
+// IO routines
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_updateSimpleMesh(RsSimpleMesh mesh)
+{
+    GET_TLS();
+    SimpleMesh *sm = static_cast<SimpleMesh *>(mesh);
+    sm->uploadAll(rsc);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Context
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
+{
+    GET_TLS();
+    rsi_ProgramBindTexture(rsc,
+                           static_cast<ProgramFragment *>(vpf),
+                           slot,
+                           static_cast<Allocation *>(va));
+
+}
+
+static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
+{
+    GET_TLS();
+    rsi_ProgramBindSampler(rsc,
+                           static_cast<ProgramFragment *>(vpf),
+                           slot,
+                           static_cast<Sampler *>(vs));
+
+}
+
+static void SC_bindProgramStore(RsProgramStore pfs)
+{
+    GET_TLS();
+    rsi_ContextBindProgramStore(rsc, pfs);
+}
+
+static void SC_bindProgramFragment(RsProgramFragment pf)
+{
+    GET_TLS();
+    rsi_ContextBindProgramFragment(rsc, pf);
+}
+
+static void SC_bindProgramVertex(RsProgramVertex pv)
+{
+    GET_TLS();
+    rsi_ContextBindProgramVertex(rsc, pv);
+}
+
+static void SC_bindProgramRaster(RsProgramRaster pv)
+{
+    GET_TLS();
+    rsi_ContextBindProgramRaster(rsc, pv);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// VP
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
+{
+    GET_TLS();
+    rsc->getVertex()->setModelviewMatrix(m);
+}
+
+static void SC_vpLoadTextureMatrix(const rsc_Matrix *m)
+{
+    GET_TLS();
+    rsc->getVertex()->setTextureMatrix(m);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Drawing
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_drawLine(float x1, float y1, float z1,
+                        float x2, float y2, float z2)
+{
+    GET_TLS();
+    if (!rsc->setupCheck()) {
+        return;
+    }
+
+    float vtx[] = { x1, y1, z1, x2, y2, z2 };
+    VertexArray va;
+    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
+    if (rsc->checkVersion2_0()) {
+        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
+    } else {
+        va.setupGL(rsc, &rsc->mStateVertexArray);
+    }
+
+    glDrawArrays(GL_LINES, 0, 2);
+}
+
+static void SC_drawPoint(float x, float y, float z)
+{
+    GET_TLS();
+    if (!rsc->setupCheck()) {
+        return;
+    }
+
+    float vtx[] = { x, y, z };
+
+    VertexArray va;
+    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
+    if (rsc->checkVersion2_0()) {
+        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
+    } else {
+        va.setupGL(rsc, &rsc->mStateVertexArray);
+    }
+
+    glDrawArrays(GL_POINTS, 0, 1);
+}
+
+static void SC_drawQuadTexCoords(float x1, float y1, float z1,
+                                 float u1, float v1,
+                                 float x2, float y2, float z2,
+                                 float u2, float v2,
+                                 float x3, float y3, float z3,
+                                 float u3, float v3,
+                                 float x4, float y4, float z4,
+                                 float u4, float v4)
+{
+    GET_TLS();
+    if (!rsc->setupCheck()) {
+        return;
+    }
+
+    //LOGE("Quad");
+    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
+    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
+    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
+    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
+
+    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
+    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
+
+    VertexArray va;
+    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
+    va.addLegacy(GL_FLOAT, 2, 8, RS_KIND_TEXTURE, false, (uint32_t)tex);
+    if (rsc->checkVersion2_0()) {
+        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
+    } else {
+        va.setupGL(rsc, &rsc->mStateVertexArray);
+    }
+
+
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+}
+
+static void SC_drawQuad(float x1, float y1, float z1,
+                        float x2, float y2, float z2,
+                        float x3, float y3, float z3,
+                        float x4, float y4, float z4)
+{
+    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
+                         x2, y2, z2, 1, 1,
+                         x3, y3, z3, 1, 0,
+                         x4, y4, z4, 0, 0);
+}
+
+static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
+{
+    GET_TLS();
+    ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
+    rsc->setVertex(rsc->getDefaultProgramVertex());
+    //rsc->setupCheck();
+
+    //GLint crop[4] = {0, h, w, -h};
+
+    float sh = rsc->getHeight();
+
+    SC_drawQuad(x,   sh - y,     z,
+                x+w, sh - y,     z,
+                x+w, sh - (y+h), z,
+                x,   sh - (y+h), z);
+    rsc->setVertex((ProgramVertex *)tmp.get());
+}
+
+static void SC_drawSpriteScreenspaceCropped(float x, float y, float z, float w, float h,
+        float cx0, float cy0, float cx1, float cy1)
+{
+    GET_TLS();
+    if (!rsc->setupCheck()) {
+        return;
+    }
+
+    GLint crop[4] = {cx0, cy0, cx1, cy1};
+    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+    glDrawTexfOES(x, y, z, w, h);
+}
+
+static void SC_drawSprite(float x, float y, float z, float w, float h)
+{
+    GET_TLS();
+    float vin[3] = {x, y, z};
+    float vout[4];
+
+    //LOGE("ds  in %f %f %f", x, y, z);
+    rsc->getVertex()->transformToScreen(rsc, vout, vin);
+    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
+    vout[0] /= vout[3];
+    vout[1] /= vout[3];
+    vout[2] /= vout[3];
+
+    vout[0] *= rsc->getWidth() / 2;
+    vout[1] *= rsc->getHeight() / 2;
+    vout[0] += rsc->getWidth() / 2;
+    vout[1] += rsc->getHeight() / 2;
+
+    vout[0] -= w/2;
+    vout[1] -= h/2;
+
+    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
+
+    // U, V, W, H
+    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
+    //rsc->setupCheck();
+}
+
+
+static void SC_drawRect(float x1, float y1,
+                        float x2, float y2, float z)
+{
+    //LOGE("SC_drawRect %f,%f  %f,%f  %f", x1, y1, x2, y2, z);
+    SC_drawQuad(x1, y2, z,
+                x2, y2, z,
+                x2, y1, z,
+                x1, y1, z);
+}
+
+static void SC_drawSimpleMesh(RsSimpleMesh vsm)
+{
+    GET_TLS();
+    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
+    if (!rsc->setupCheck()) {
+        return;
+    }
+    sm->render(rsc);
+}
+
+static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
+{
+    GET_TLS();
+    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
+    if (!rsc->setupCheck()) {
+        return;
+    }
+    sm->renderRange(rsc, start, len);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+static void SC_color(float r, float g, float b, float a)
+{
+    GET_TLS();
+    rsc->mStateVertex.color[0] = r;
+    rsc->mStateVertex.color[1] = g;
+    rsc->mStateVertex.color[2] = b;
+    rsc->mStateVertex.color[3] = a;
+    if (!rsc->checkVersion2_0()) {
+        glColor4f(r, g, b, a);
+    }
+}
+
+static void SC_pointAttenuation(float a, float b, float c)
+{
+    GLfloat params[] = { a, b, c };
+    glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
+}
+
+static void SC_hsbToRgb(float h, float s, float b, float* rgb)
+{
+    float red = 0.0f;
+    float green = 0.0f;
+    float blue = 0.0f;
+
+    float x = h;
+    float y = s;
+    float z = b;
+
+    float hf = (x - (int) x) * 6.0f;
+    int ihf = (int) hf;
+    float f = hf - ihf;
+    float pv = z * (1.0f - y);
+    float qv = z * (1.0f - y * f);
+    float tv = z * (1.0f - y * (1.0f - f));
+
+    switch (ihf) {
+        case 0:         // Red is the dominant color
+            red = z;
+            green = tv;
+            blue = pv;
+            break;
+        case 1:         // Green is the dominant color
+            red = qv;
+            green = z;
+            blue = pv;
+            break;
+        case 2:
+            red = pv;
+            green = z;
+            blue = tv;
+            break;
+        case 3:         // Blue is the dominant color
+            red = pv;
+            green = qv;
+            blue = z;
+            break;
+        case 4:
+            red = tv;
+            green = pv;
+            blue = z;
+            break;
+        case 5:         // Red is the dominant color
+            red = z;
+            green = pv;
+            blue = qv;
+            break;
+    }
+
+    rgb[0] = red;
+    rgb[1] = green;
+    rgb[2] = blue;
+}
+
+static int SC_hsbToAbgr(float h, float s, float b, float a)
+{
+    //LOGE("hsb a %f, %f, %f    %f", h, s, b, a);
+    float rgb[3];
+    SC_hsbToRgb(h, s, b, rgb);
+    //LOGE("rgb  %f, %f, %f ", rgb[0], rgb[1], rgb[2]);
+    return int(a      * 255.0f) << 24 |
+           int(rgb[2] * 255.0f) << 16 |
+           int(rgb[1] * 255.0f) <<  8 |
+           int(rgb[0] * 255.0f);
+}
+
+static void SC_hsb(float h, float s, float b, float a)
+{
+    GET_TLS();
+    float rgb[3];
+    SC_hsbToRgb(h, s, b, rgb);
+    if (rsc->checkVersion2_0()) {
+        glVertexAttrib4f(1, rgb[0], rgb[1], rgb[2], a);
+    } else {
+        glColor4f(rgb[0], rgb[1], rgb[2], a);
+    }
+}
+
+static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
+{
+    GET_TLS();
+    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
+}
+
+static void SC_uploadToBufferObject(RsAllocation va)
+{
+    GET_TLS();
+    rsi_AllocationUploadToBufferObject(rsc, va);
+}
+
+static void SC_syncToGL(RsAllocation va)
+{
+    GET_TLS();
+    Allocation *a = static_cast<Allocation *>(va);
+
+}
+
+static void SC_ClearColor(float r, float g, float b, float a)
+{
+    //LOGE("c %f %f %f %f", r, g, b, a);
+    GET_TLS();
+    sc->mEnviroment.mClearColor[0] = r;
+    sc->mEnviroment.mClearColor[1] = g;
+    sc->mEnviroment.mClearColor[2] = b;
+    sc->mEnviroment.mClearColor[3] = a;
+}
+
+static uint32_t SC_getWidth()
+{
+    GET_TLS();
+    return rsc->getWidth();
+}
+
+static uint32_t SC_getHeight()
+{
+    GET_TLS();
+    return rsc->getHeight();
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Class implementation
+//////////////////////////////////////////////////////////////////////////////
+
+// llvm name mangling ref
+//  <builtin-type> ::= v  # void
+//                 ::= b  # bool
+//                 ::= c  # char
+//                 ::= a  # signed char
+//                 ::= h  # unsigned char
+//                 ::= s  # short
+//                 ::= t  # unsigned short
+//                 ::= i  # int
+//                 ::= j  # unsigned int
+//                 ::= l  # long
+//                 ::= m  # unsigned long
+//                 ::= x  # long long, __int64
+//                 ::= y  # unsigned long long, __int64
+//                 ::= f  # float
+//                 ::= d  # double
+
+static ScriptCState::SymbolTable_t gSyms[] = {
+    // IO
+    { "updateSimpleMesh", (void *)&SC_updateSimpleMesh },
+
+    // context
+    { "bindProgramFragment", (void *)&SC_bindProgramFragment },
+    { "bindProgramStore", (void *)&SC_bindProgramStore },
+    { "bindProgramVertex", (void *)&SC_bindProgramVertex },
+    { "bindProgramRaster", (void *)&SC_bindProgramRaster },
+    { "bindSampler", (void *)&SC_bindSampler },
+    { "bindTexture", (void *)&SC_bindTexture },
+
+    // vp
+    { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix },
+    { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix },
+
+    // drawing
+    { "drawRect", (void *)&SC_drawRect },
+    { "drawQuad", (void *)&SC_drawQuad },
+    { "drawQuadTexCoords", (void *)&SC_drawQuadTexCoords },
+    { "drawSprite", (void *)&SC_drawSprite },
+    { "drawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace },
+    { "drawSpriteScreenspaceCropped", (void *)&SC_drawSpriteScreenspaceCropped },
+    { "drawLine", (void *)&SC_drawLine },
+    { "drawPoint", (void *)&SC_drawPoint },
+    { "drawSimpleMesh", (void *)&SC_drawSimpleMesh },
+    { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange },
+
+
+    // misc
+    { "pfClearColor", (void *)&SC_ClearColor },
+    { "color", (void *)&SC_color },
+    { "hsb", (void *)&SC_hsb },
+    { "hsbToRgb", (void *)&SC_hsbToRgb },
+    { "hsbToAbgr", (void *)&SC_hsbToAbgr },
+    { "pointAttenuation", (void *)&SC_pointAttenuation },
+
+    { "uploadToTexture", (void *)&SC_uploadToTexture },
+    { "uploadToBufferObject", (void *)&SC_uploadToBufferObject },
+
+    { "syncToGL", (void *)&SC_syncToGL },
+
+    { "getWidth", (void *)&SC_getWidth },
+    { "getHeight", (void *)&SC_getHeight },
+
+    { NULL, NULL }
+};
+
+const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym)
+{
+    ScriptCState::SymbolTable_t *syms = gSyms;
+
+    while (syms->mPtr) {
+        if (!strcmp(syms->mName, sym)) {
+            return syms;
+        }
+        syms++;
+    }
+    return NULL;
+}
+
diff --git a/scriptc/rs_math.rsh b/scriptc/rs_math.rsh
index 48ab066..1d2f1e4 100644
--- a/scriptc/rs_math.rsh
+++ b/scriptc/rs_math.rsh
@@ -650,4 +650,5 @@
 extern void matrixScale(void *mat, float x, float y, float z);
 extern void matrixTranslate(void *mat, float x, float y, float z);
 
+extern rs_allocation rsGetAllocation(const void *);