Continue development of es2.0 user shader support for renderscript.  This change cleans up ProgramVertex creation and adds support for passing input, output, and constant type info.
diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java
new file mode 100644
index 0000000..bf6aac7
--- /dev/null
+++ b/graphics/java/android/renderscript/Program.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.renderscript;
+
+
+import android.util.Config;
+import android.util.Log;
+
+
+/**
+ * @hide
+ *
+ **/
+public class Program extends BaseObj {
+    public static final int MAX_INPUT = 8;
+    public static final int MAX_OUTPUT = 8;
+    public static final int MAX_CONSTANT = 8;
+
+    Element mInputs[];
+    Element mOutputs[];
+    Type mConstants[];
+    String mShader;
+
+    Program(int id, RenderScript rs) {
+        super(rs);
+        mID = id;
+    }
+
+    public void bindConstants(Allocation a, int slot) {
+        mRS.nProgramBindConstants(mID, slot, a.mID);
+    }
+
+    public static class BaseProgramBuilder {
+        RenderScript mRS;
+        Element mInputs[];
+        Element mOutputs[];
+        Type mConstants[];
+        Type mTextures[];
+        int mInputCount;
+        int mOutputCount;
+        int mConstantCount;
+        int mTextureCount;
+        String mShader;
+
+
+        protected BaseProgramBuilder(RenderScript rs) {
+            mRS = rs;
+            mInputs = new Element[MAX_INPUT];
+            mOutputs = new Element[MAX_OUTPUT];
+            mConstants = new Type[MAX_CONSTANT];
+            mInputCount = 0;
+            mOutputCount = 0;
+            mConstantCount = 0;
+        }
+
+        public void setShader(String s) {
+            mShader = s;
+        }
+
+        public void addInput(Element e) throws IllegalStateException {
+            // Should check for consistant and non-conflicting names...
+            if(mInputCount >= MAX_INPUT) {
+                throw new IllegalArgumentException("Max input count exceeded.");
+            }
+            mInputs[mInputCount++] = e;
+        }
+
+        public void addOutput(Element e) throws IllegalStateException {
+            // Should check for consistant and non-conflicting names...
+            if(mOutputCount >= MAX_OUTPUT) {
+                throw new IllegalArgumentException("Max output count exceeded.");
+            }
+            mOutputs[mOutputCount++] = e;
+        }
+
+        public void addConstant(Type t) throws IllegalStateException {
+            // Should check for consistant and non-conflicting names...
+            if(mConstantCount >= MAX_CONSTANT) {
+                throw new IllegalArgumentException("Max input count exceeded.");
+            }
+            mConstants[mConstantCount++] = t;
+        }
+
+        public void addTexture(Type t) throws IllegalStateException {
+            // Should check for consistant and non-conflicting names...
+            if(mTextureCount >= MAX_CONSTANT) {
+                throw new IllegalArgumentException("Max input count exceeded.");
+            }
+            mTextures[mTextureCount++] = t;
+        }
+
+        protected void initProgram(Program p) {
+            p.mInputs = new Element[mInputCount];
+            System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
+            p.mOutputs = new Element[mOutputCount];
+            System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
+            p.mConstants = new Type[mConstantCount];
+            System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
+            p.mTextures = new Type[mTextureCount];
+            System.arraycopy(mTextures, 0, p.mTextures, 0, mTextureCount);
+        }
+    }
+
+}
+
+
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index e284984..06cfc93 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -25,81 +25,69 @@
  * @hide
  *
  **/
-public class ProgramVertex extends BaseObj {
+public class ProgramVertex extends Program {
     public static final int MAX_LIGHT = 8;
 
+
     ProgramVertex(int id, RenderScript rs) {
-        super(rs);
-        mID = id;
+        super(id, rs);
     }
 
     public void bindAllocation(MatrixAllocation va) {
         mRS.validate();
-        mRS.nProgramVertexBindAllocation(mID, va.mAlloc.mID);
+        bindConstants(va.mAlloc, 0);
     }
 
 
     public static class Builder {
         RenderScript mRS;
-        Element mIn;
-        Element mOut;
-        Light[] mLights;
-        int mLightCount;
         boolean mTextureMatrixEnable;
-        String mShader;
-
 
         public Builder(RenderScript rs, Element in, Element out) {
             mRS = rs;
-            mIn = in;
-            mOut = out;
-            mLights = new Light[MAX_LIGHT];
-            mLightCount = 0;
         }
 
         public void setTextureMatrixEnable(boolean enable) {
             mTextureMatrixEnable = enable;
         }
 
-        public void setShader(String s) {
-            mShader = s;
+        public ProgramVertex create() {
+            int id = mRS.nProgramVertexCreate(mTextureMatrixEnable);
+            return new ProgramVertex(id, mRS);
         }
+    }
 
-        public void addLight(Light l) throws IllegalStateException {
-            if(mLightCount >= MAX_LIGHT) {
-                throw new IllegalArgumentException("Max light count exceeded.");
-            }
-            mLights[mLightCount] = l;
-            mLightCount++;
-        }
-
-
-
-        static synchronized ProgramVertex internalCreate(RenderScript rs, Builder b) {
-            int inID = 0;
-            int outID = 0;
-            if (b.mIn != null) {
-                inID = b.mIn.mID;
-            }
-            if (b.mOut != null) {
-                outID = b.mOut.mID;
-            }
-            rs.nProgramVertexBegin(inID, outID);
-            if (b.mShader != null) {
-                rs.nProgramVertexSetShader(b.mShader);
-            } else {
-                for(int ct=0; ct < b.mLightCount; ct++) {
-                    rs.nProgramVertexAddLight(b.mLights[ct].mID);
-                }
-                rs.nProgramVertexSetTextureMatrixEnable(b.mTextureMatrixEnable);
-            }
-            int id = rs.nProgramVertexCreate();
-            return new ProgramVertex(id, rs);
+    public static class ShaderBuilder extends BaseProgramBuilder {
+        public ShaderBuilder(RenderScript rs) {
+            super(rs);
         }
 
         public ProgramVertex create() {
             mRS.validate();
-            return internalCreate(mRS, this);
+            int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount +1) * 2];
+            int idx = 0;
+
+            for (int i=0; i < mInputCount; i++) {
+                tmp[idx++] = 0;
+                tmp[idx++] = mInputs[i].mID;
+            }
+            for (int i=0; i < mOutputCount; i++) {
+                tmp[idx++] = 1;
+                tmp[idx++] = mOutputs[i].mID;
+            }
+            for (int i=0; i < mConstantCount; i++) {
+                tmp[idx++] = 2;
+                tmp[idx++] = mConstants[i].mID;
+            }
+            for (int i=0; i < mTextureCount; i++) {
+                tmp[idx++] = 3;
+                tmp[idx++] = mTextures[i].mID;
+            }
+
+            int id = mRS.nProgramVertexCreate2(mShader, tmp);
+            ProgramVertex pv = new ProgramVertex(id, mRS);
+            initProgram(pv);
+            return pv;
         }
     }
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index eff0fbb..75bd3d0 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -167,6 +167,8 @@
     native void nProgramRasterSetLineWidth(int pr, float v);
     native void nProgramRasterSetPointSize(int pr, float v);
 
+    native void nProgramBindConstants(int pv, int slot, int mID);
+
     native void nProgramFragmentBegin(int in, int out, boolean pointSpriteEnable);
     native void nProgramFragmentBindTexture(int vpf, int slot, int a);
     native void nProgramFragmentBindSampler(int vpf, int slot, int s);
@@ -174,12 +176,8 @@
     native void nProgramFragmentSetShader(String txt);
     native int  nProgramFragmentCreate();
 
-    native void nProgramVertexBindAllocation(int pv, int mID);
-    native void nProgramVertexBegin(int inID, int outID);
-    native void nProgramVertexSetTextureMatrixEnable(boolean enable);
-    native void nProgramVertexAddLight(int id);
-    native void nProgramVertexSetShader(String txt);
-    native int  nProgramVertexCreate();
+    native int  nProgramVertexCreate(boolean texMat);
+    native int  nProgramVertexCreate2(String shader, int[] params);
 
     native void nLightBegin();
     native void nLightSetIsMono(boolean isMono);
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index ea5feb8..1fa15a8 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -1053,6 +1053,15 @@
     return (jint)rsProgramFragmentStoreCreate(con);
 }
 
+// ---------------------------------------------------------------------------
+
+static void
+nProgramBindConstants(JNIEnv *_env, jobject _this, jint vpv, jint slot, jint a)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
+    rsProgramBindConstants(con, (RsProgram)vpv, slot, (RsAllocation)a);
+}
 
 // ---------------------------------------------------------------------------
 
@@ -1108,57 +1117,30 @@
 
 // ---------------------------------------------------------------------------
 
-static void
-nProgramVertexSetShader(JNIEnv *_env, jobject _this, jstring name)
+static jint
+nProgramVertexCreate(JNIEnv *_env, jobject _this, jboolean texMat)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
-    const char* n = _env->GetStringUTFChars(name, NULL);
-    LOG_API("nProgramVertexSetShader, con(%p)", con);
-    rsProgramVertexSetShader(con, n, _env->GetStringUTFLength(name));
-    _env->ReleaseStringUTFChars(name, n);
-}
-
-
-static void
-nProgramVertexBegin(JNIEnv *_env, jobject _this, jint in, jint out)
-{
-    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
-    LOG_API("nProgramVertexBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
-    rsProgramVertexBegin(con, (RsElement)in, (RsElement)out);
-}
-
-static void
-nProgramVertexBindAllocation(JNIEnv *_env, jobject _this, jint vpv, jint a)
-{
-    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
-    LOG_API("nProgramVertexBindAllocation, con(%p), vpf(%p), a(%p)", con, (RsProgramVertex)vpv, (RsAllocation)a);
-    rsProgramVertexBindAllocation(con, (RsProgramFragment)vpv, (RsAllocation)a);
-}
-
-static void
-nProgramVertexSetTextureMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable)
-{
-    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
-    LOG_API("nProgramVertexSetTextureMatrixEnable, con(%p), enable(%i)", con, enable);
-    rsProgramVertexSetTextureMatrixEnable(con, enable);
-}
-
-static void
-nProgramVertexAddLight(JNIEnv *_env, jobject _this, jint light)
-{
-    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
-    LOG_API("nProgramVertexAddLight, con(%p), light(%p)", con, (RsLight)light);
-    rsProgramVertexAddLight(con, (RsLight)light);
+    LOG_API("nProgramVertexCreate, con(%p), texMat(%i)", con, texMat);
+    return (jint)rsProgramVertexCreate(con, texMat);
 }
 
 static jint
-nProgramVertexCreate(JNIEnv *_env, jobject _this)
+nProgramVertexCreate2(JNIEnv *_env, jobject _this, jstring shader, jintArray params)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
-    LOG_API("nProgramVertexCreate, con(%p)", con);
-    return (jint)rsProgramVertexCreate(con);
-}
+    const char* shaderUTF = _env->GetStringUTFChars(shader, NULL);
+    jint shaderLen = _env->GetStringUTFLength(shader);
+    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
+    jint paramLen = _env->GetArrayLength(params);
 
+    LOG_API("nProgramVertexCreate2, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
+
+    jint ret = (jint)rsProgramVertexCreate2(con, shaderUTF, shaderLen, (uint32_t *)paramPtr, paramLen);
+    _env->ReleaseStringUTFChars(shader, shaderUTF);
+    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
+    return ret;
+}
 
 // ---------------------------------------------------------------------------
 
@@ -1454,6 +1436,8 @@
 {"nProgramFragmentStoreDither",    "(Z)V",                                 (void*)nProgramFragmentStoreDither },
 {"nProgramFragmentStoreCreate",    "()I",                                  (void*)nProgramFragmentStoreCreate },
 
+{"nProgramBindConstants",          "(III)V",                               (void*)nProgramBindConstants },
+
 {"nProgramFragmentBegin",          "(IIZ)V",                               (void*)nProgramFragmentBegin },
 {"nProgramFragmentBindTexture",    "(III)V",                               (void*)nProgramFragmentBindTexture },
 {"nProgramFragmentBindSampler",    "(III)V",                               (void*)nProgramFragmentBindSampler },
@@ -1465,12 +1449,8 @@
 {"nProgramRasterSetPointSize",     "(IF)V",                                (void*)nProgramRasterSetPointSize },
 {"nProgramRasterSetLineWidth",     "(IF)V",                                (void*)nProgramRasterSetLineWidth },
 
-{"nProgramVertexBindAllocation",   "(II)V",                                (void*)nProgramVertexBindAllocation },
-{"nProgramVertexBegin",            "(II)V",                                (void*)nProgramVertexBegin },
-{"nProgramVertexSetTextureMatrixEnable",   "(Z)V",                         (void*)nProgramVertexSetTextureMatrixEnable },
-{"nProgramVertexAddLight",         "(I)V",                                 (void*)nProgramVertexAddLight },
-{"nProgramVertexSetShader",        "(Ljava/lang/String;)V",                (void*)nProgramVertexSetShader },
-{"nProgramVertexCreate",           "()I",                                  (void*)nProgramVertexCreate },
+{"nProgramVertexCreate",           "(Z)I",                                 (void*)nProgramVertexCreate },
+{"nProgramVertexCreate2",          "(Ljava/lang/String;[I)I",              (void*)nProgramVertexCreate2 },
 
 {"nLightBegin",                    "()V",                                  (void*)nLightBegin },
 {"nLightSetIsMono",                "(Z)V",                                 (void*)nLightSetIsMono },