Implement renderscript Invokables.
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 89db4fa..d35c5e3 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -140,6 +140,8 @@
     native void nScriptSetTimeZone(int script, byte[] timeZone);
     native void nScriptSetType(int type, boolean writable, String name, int slot);
     native void nScriptSetRoot(boolean isRoot);
+    native void nScriptSetInvokable(String name, int slot);
+    native void nScriptInvoke(int id, int slot);
 
     native void nScriptCBegin();
     native void nScriptCSetScript(byte[] script, int offset, int length);
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
index a402471..35791a3 100644
--- a/graphics/java/android/renderscript/Script.java
+++ b/graphics/java/android/renderscript/Script.java
@@ -25,6 +25,22 @@
     boolean mIsRoot;
     Type[] mTypes;
     boolean[] mWritable;
+    Invokable[] mInvokables;
+
+    public static class Invokable {
+        RenderScript mRS;
+        Script mScript;
+        int mSlot;
+        String mName;
+
+        Invokable() {
+            mSlot = -1;
+        }
+
+        public void execute() {
+            mRS.nScriptInvoke(mScript.mID, mSlot);
+        }
+    }
 
     Script(int id, RenderScript rs) {
         super(rs);
@@ -61,12 +77,15 @@
         Type[] mTypes;
         String[] mNames;
         boolean[] mWritable;
+        int mInvokableCount = 0;
+        Invokable[] mInvokables;
 
         Builder(RenderScript rs) {
             mRS = rs;
             mTypes = new Type[MAX_SLOT];
             mNames = new String[MAX_SLOT];
             mWritable = new boolean[MAX_SLOT];
+            mInvokables = new Invokable[MAX_SLOT];
         }
 
         public void setType(Type t, int slot) {
@@ -79,6 +98,15 @@
             mNames[slot] = name;
         }
 
+        public Invokable addInvokable(String func) {
+            Invokable i = new Invokable();
+            i.mName = func;
+            i.mRS = mRS;
+            i.mSlot = mInvokableCount;
+            mInvokables[mInvokableCount++] = i;
+            return i;
+        }
+
         public void setType(boolean writable, int slot) {
             mWritable[slot] = writable;
         }
@@ -90,11 +118,20 @@
                     mRS.nScriptSetType(mTypes[ct].mID, mWritable[ct], mNames[ct], ct);
                 }
             }
+            for(int ct=0; ct < mInvokableCount; ct++) {
+                mRS.nScriptSetInvokable(mInvokables[ct].mName, ct);
+            }
         }
 
         void transferObject(Script s) {
             s.mIsRoot = mIsRoot;
             s.mTypes = mTypes;
+            s.mInvokables = new Invokable[mInvokableCount];
+            for(int ct=0; ct < mInvokableCount; ct++) {
+                s.mInvokables[ct] = mInvokables[ct];
+                s.mInvokables[ct].mScript = s;
+            }
+            s.mInvokables = null;
         }
 
         public void setRoot(boolean r) {
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 90b5958..eae6f24 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -891,6 +891,29 @@
 }
 
 static void
+nScriptSetInvoke(JNIEnv *_env, jobject _this, jstring _str, jint slot)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptSetInvoke, con(%p)", con);
+    const char* n = NULL;
+    if (_str) {
+        n = _env->GetStringUTFChars(_str, NULL);
+    }
+    rsScriptSetInvoke(con, n, slot);
+    if (n) {
+        _env->ReleaseStringUTFChars(_str, n);
+    }
+}
+
+static void
+nScriptInvoke(JNIEnv *_env, jobject _this, jint obj, jint slot)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj);
+    rsScriptInvoke(con, (RsScript)obj, slot);
+}
+
+static void
 nScriptSetRoot(JNIEnv *_env, jobject _this, jboolean isRoot)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
@@ -1366,6 +1389,8 @@
 {"nScriptSetTimeZone",             "(I[B)V",                               (void*)nScriptSetTimeZone },
 {"nScriptSetType",                 "(IZLjava/lang/String;I)V",             (void*)nScriptSetType },
 {"nScriptSetRoot",                 "(Z)V",                                 (void*)nScriptSetRoot },
+{"nScriptSetInvokable",            "(Ljava/lang/String;I)V",               (void*)nScriptSetInvoke },
+{"nScriptInvoke",                  "(II)V",                                (void*)nScriptInvoke },
 
 {"nScriptCBegin",                  "()V",                                  (void*)nScriptCBegin },
 {"nScriptCSetScript",              "([BII)V",                              (void*)nScriptCSetScript },
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index ac2e738..87ad97c 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -297,6 +297,16 @@
 	param const char * name
 	}
 
+ScriptSetInvoke {
+	param const char * name
+	param uint32_t slot
+	}
+
+ScriptInvoke {
+	param RsScript s
+	param uint32_t slot
+	}
+
 ScriptSetRoot {
 	param bool isRoot
 	}
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index fde31a1..99a085d 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -27,6 +27,8 @@
     mEnviroment.mClearColor[2] = 0;
     mEnviroment.mClearColor[3] = 1;
     mEnviroment.mClearDepth = 1;
+    mEnviroment.mClearStencil = 0;
+    mEnviroment.mIsRoot = false;
 }
 
 Script::~Script()
@@ -83,10 +85,23 @@
     }
 }
 
+void rsi_ScriptSetInvoke(Context *rsc, const char *name, uint32_t slot)
+{
+    ScriptCState *ss = &rsc->mScriptC;
+    ss->mInvokableNames[slot] = name;
+}
+
+void rsi_ScriptInvoke(Context *rsc, RsScript vs, uint32_t slot)
+{
+    Script *s = static_cast<Script *>(vs);
+    s->mEnviroment.mInvokables[slot]();
+}
+
+
 void rsi_ScriptSetRoot(Context * rsc, bool isRoot)
 {
     ScriptCState *ss = &rsc->mScriptC;
-    ss->mEnviroment.mIsRoot = isRoot;
+    ss->mScript->mEnviroment.mIsRoot = isRoot;
 }
 
 
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 60f83a6..e40531e 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -34,6 +34,7 @@
 class Script : public ObjectBase
 {
 public:
+    typedef void (* InvokeFunc_t)(void);
 
     Script();
     virtual ~Script();
@@ -52,17 +53,22 @@
         ObjectBaseRef<ProgramFragment> mFragment;
         //ObjectBaseRef<ProgramRaster> mRaster;
         ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
-
+        InvokeFunc_t mInvokables[MAX_SCRIPT_BANKS];
+        const char * mScriptText;
+        uint32_t mScriptTextLength;
     };
     Enviroment_t mEnviroment;
 
     uint32_t mCounstantBufferCount;
 
+
     ObjectBaseRef<Allocation> mSlots[MAX_SCRIPT_BANKS];
     ObjectBaseRef<const Type> mTypes[MAX_SCRIPT_BANKS];
     String8 mSlotNames[MAX_SCRIPT_BANKS];
     bool mSlotWritable[MAX_SCRIPT_BANKS];
 
+
+
     virtual bool run(Context *, uint32_t launchID) = 0;
 };
 
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 8230cbc..108ae5a 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -82,36 +82,27 @@
 
 ScriptCState::ScriptCState()
 {
+    mScript = NULL;
     clear();
 }
 
 ScriptCState::~ScriptCState()
 {
-    if (mAccScript) {
-        accDeleteScript(mAccScript);
-    }
+    delete mScript;
+    mScript = NULL;
 }
 
 void ScriptCState::clear()
 {
-    memset(&mProgram, 0, sizeof(mProgram));
-
     for (uint32_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
         mConstantBufferTypes[ct].clear();
         mSlotNames[ct].setTo("");
+        mInvokableNames[ct].setTo("");
         mSlotWritable[ct] = false;
     }
 
-    memset(&mEnviroment, 0, sizeof(mEnviroment));
-    mEnviroment.mClearColor[0] = 0;
-    mEnviroment.mClearColor[1] = 0;
-    mEnviroment.mClearColor[2] = 0;
-    mEnviroment.mClearColor[3] = 1;
-    mEnviroment.mClearDepth = 1;
-    mEnviroment.mClearStencil = 0;
-    mEnviroment.mIsRoot = false;
-
-    mAccScript = NULL;
+    delete mScript;
+    mScript = new ScriptC();
 
     mInt32Defines.clear();
     mFloatDefines.clear();
@@ -127,9 +118,9 @@
     return NULL;
 }
 
-void ScriptCState::runCompiler(Context *rsc)
+void ScriptCState::runCompiler(Context *rsc, ScriptC *s)
 {
-    mAccScript = accCreateScript();
+    s->mAccScript = accCreateScript();
     String8 tmp;
 
     rsc->appendNameDefines(&tmp);
@@ -139,44 +130,51 @@
     appendTypes(&tmp);
     tmp.append("#line 1\n");
 
-    const char* scriptSource[] = {tmp.string(), mProgram.mScriptText};
-    int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ;
-    accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength);
-    accRegisterSymbolCallback(mAccScript, symbolLookup, NULL);
-    accCompileScript(mAccScript);
-    accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript);
-    accGetScriptLabel(mAccScript, "init", (ACCvoid**) &mProgram.mInit);
-    rsAssert(mProgram.mScript);
+    const char* scriptSource[] = {tmp.string(), s->mEnviroment.mScriptText};
+    int scriptLength[] = {tmp.length(), s->mEnviroment.mScriptTextLength} ;
+    accScriptSource(s->mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength);
+    accRegisterSymbolCallback(s->mAccScript, symbolLookup, NULL);
+    accCompileScript(s->mAccScript);
+    accGetScriptLabel(s->mAccScript, "main", (ACCvoid**) &s->mProgram.mScript);
+    accGetScriptLabel(s->mAccScript, "init", (ACCvoid**) &s->mProgram.mInit);
+    rsAssert(s->mProgram.mScript);
 
-    if (!mProgram.mScript) {
+    if (!s->mProgram.mScript) {
         ACCchar buf[4096];
         ACCsizei len;
-        accGetScriptInfoLog(mAccScript, sizeof(buf), &len, buf);
+        accGetScriptInfoLog(s->mAccScript, sizeof(buf), &len, buf);
         LOGE(buf);
     }
 
-    if (mProgram.mInit) {
-        mProgram.mInit();
+    if (s->mProgram.mInit) {
+        s->mProgram.mInit();
     }
 
     for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
         if (mSlotNames[ct].length() > 0) {
-            accGetScriptLabel(mAccScript,
+            accGetScriptLabel(s->mAccScript,
                               mSlotNames[ct].string(),
-                              (ACCvoid**) &mProgram.mSlotPointers[ct]);
-            LOGE("var  %s  %p", mSlotNames[ct].string(), mProgram.mSlotPointers[ct]);
+                              (ACCvoid**) &s->mProgram.mSlotPointers[ct]);
         }
     }
 
-    mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
-    mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
-    mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
+    for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
+        if (mInvokableNames[ct].length() > 0) {
+            accGetScriptLabel(s->mAccScript,
+                              mInvokableNames[ct].string(),
+                              (ACCvoid**) &s->mEnviroment.mInvokables[ct]);
+        }
+    }
 
-    if (mProgram.mScript) {
+    s->mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
+    s->mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
+    s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
+
+    if (s->mProgram.mScript) {
         const static int pragmaMax = 16;
         ACCsizei pragmaCount;
         ACCchar * str[pragmaMax];
-        accGetPragmas(mAccScript, &pragmaCount, pragmaMax, &str[0]);
+        accGetPragmas(s->mAccScript, &pragmaCount, pragmaMax, &str[0]);
 
         for (int ct=0; ct < pragmaCount; ct+=2) {
             if (!strcmp(str[ct], "version")) {
@@ -188,12 +186,12 @@
                     continue;
                 }
                 if (!strcmp(str[ct+1], "parent")) {
-                    mEnviroment.mVertex.clear();
+                    s->mEnviroment.mVertex.clear();
                     continue;
                 }
                 ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]);
                 if (pv != NULL) {
-                    mEnviroment.mVertex.set(pv);
+                    s->mEnviroment.mVertex.set(pv);
                     continue;
                 }
                 LOGE("Unreconized value %s passed to stateVertex", str[ct+1]);
@@ -208,12 +206,12 @@
                     continue;
                 }
                 if (!strcmp(str[ct+1], "parent")) {
-                    mEnviroment.mFragment.clear();
+                    s->mEnviroment.mFragment.clear();
                     continue;
                 }
                 ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]);
                 if (pf != NULL) {
-                    mEnviroment.mFragment.set(pf);
+                    s->mEnviroment.mFragment.set(pf);
                     continue;
                 }
                 LOGE("Unreconized value %s passed to stateFragment", str[ct+1]);
@@ -224,13 +222,13 @@
                     continue;
                 }
                 if (!strcmp(str[ct+1], "parent")) {
-                    mEnviroment.mFragmentStore.clear();
+                    s->mEnviroment.mFragmentStore.clear();
                     continue;
                 }
                 ProgramFragmentStore * pfs =
                     (ProgramFragmentStore *)rsc->lookupName(str[ct+1]);
                 if (pfs != NULL) {
-                    mEnviroment.mFragmentStore.set(pfs);
+                    s->mEnviroment.mFragmentStore.set(pfs);
                     continue;
                 }
                 LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]);
@@ -351,33 +349,6 @@
             s.append(";\n");
             LOGD(s);
             str->append(s);
-#if 0
-            for (size_t ct2=0; ct2 < e->getComponentCount(); ct2++) {
-                const Component *c = e->getComponent(ct2);
-                tmp.setTo("#define ");
-                tmp.append(mSlotNames[ct]);
-                tmp.append("_");
-                tmp.append(c->getComponentName());
-                switch (c->getType()) {
-                case Component::FLOAT:
-                    tmp.append(" loadF(");
-                    break;
-                case Component::SIGNED:
-                    sprintf(buf, " loadI%i(", c->getBits());
-                    tmp.append(buf);
-                    break;
-                case Component::UNSIGNED:
-                    sprintf(buf, " loadU%i(", c->getBits());
-                    tmp.append(buf);
-                    break;
-                }
-                sprintf(buf, "%i, %i)\n", ct, ct2);
-                tmp.append(buf);
-
-                LOGD(tmp);
-                str->append(tmp);
-            }
-#endif
         }
     }
 }
@@ -394,15 +365,16 @@
 
 void rsi_ScriptCSetScript(Context * rsc, void *vp)
 {
-    ScriptCState *ss = &rsc->mScriptC;
-    ss->mProgram.mScript = reinterpret_cast<ScriptC::RunScript_t>(vp);
+    rsAssert(0);
+    //ScriptCState *ss = &rsc->mScriptC;
+    //ss->mProgram.mScript = reinterpret_cast<ScriptC::RunScript_t>(vp);
 }
 
 void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len)
 {
     ScriptCState *ss = &rsc->mScriptC;
-    ss->mProgram.mScriptText = text;
-    ss->mProgram.mScriptTextLength = len;
+    ss->mScript->mEnviroment.mScriptText = text;
+    ss->mScript->mEnviroment.mScriptTextLength = len;
 }
 
 
@@ -410,14 +382,11 @@
 {
     ScriptCState *ss = &rsc->mScriptC;
 
-    ss->runCompiler(rsc);
+    ScriptC *s = ss->mScript;
+    ss->mScript = NULL;
 
-    ScriptC *s = new ScriptC();
+    ss->runCompiler(rsc, s);
     s->incUserRef();
-    s->mAccScript = ss->mAccScript;
-    ss->mAccScript = NULL;
-    s->mEnviroment = ss->mEnviroment;
-    s->mProgram = ss->mProgram;
     for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
         s->mTypes[ct].set(ss->mConstantBufferTypes[ct].get());
         s->mSlotNames[ct] = ss->mSlotNames[ct];
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 8aa99ef..355f0c3 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -67,17 +67,15 @@
     ScriptCState();
     ~ScriptCState();
 
-    ACCscript* mAccScript;
-
-    ScriptC::Program_t mProgram;
-    Script::Enviroment_t mEnviroment;
+    ScriptC *mScript;
 
     ObjectBaseRef<const Type> mConstantBufferTypes[MAX_SCRIPT_BANKS];
     String8 mSlotNames[MAX_SCRIPT_BANKS];
     bool mSlotWritable[MAX_SCRIPT_BANKS];
+    String8 mInvokableNames[MAX_SCRIPT_BANKS];
 
     void clear();
-    void runCompiler(Context *rsc);
+    void runCompiler(Context *rsc, ScriptC *s);
     void appendVarDefines(String8 *str);
     void appendTypes(String8 *str);