Merge change I7e5ab3b1

* changes:
  Continue es2 shader dev
diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java
index bf6aac7..88b87b0 100644
--- a/graphics/java/android/renderscript/Program.java
+++ b/graphics/java/android/renderscript/Program.java
@@ -29,10 +29,12 @@
     public static final int MAX_INPUT = 8;
     public static final int MAX_OUTPUT = 8;
     public static final int MAX_CONSTANT = 8;
+    public static final int MAX_TEXTURE = 8;
 
     Element mInputs[];
     Element mOutputs[];
     Type mConstants[];
+    int mTextureCount;
     String mShader;
 
     Program(int id, RenderScript rs) {
@@ -65,6 +67,7 @@
             mInputCount = 0;
             mOutputCount = 0;
             mConstantCount = 0;
+            mTextureCount = 0;
         }
 
         public void setShader(String s) {
@@ -95,12 +98,12 @@
             mConstants[mConstantCount++] = t;
         }
 
-        public void addTexture(Type t) throws IllegalStateException {
+        public void setTextureCount(int count) throws IllegalArgumentException {
             // Should check for consistant and non-conflicting names...
-            if(mTextureCount >= MAX_CONSTANT) {
-                throw new IllegalArgumentException("Max input count exceeded.");
+            if(count >= MAX_CONSTANT) {
+                throw new IllegalArgumentException("Max texture count exceeded.");
             }
-            mTextures[mTextureCount++] = t;
+            mTextureCount = count;
         }
 
         protected void initProgram(Program p) {
@@ -110,8 +113,7 @@
             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);
+            p.mTextureCount = mTextureCount;
         }
     }
 
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index 2b2557d..f150043 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -25,7 +25,7 @@
  * @hide
  *
  **/
-public class ProgramFragment extends BaseObj {
+public class ProgramFragment extends Program {
     public static final int MAX_SLOT = 2;
 
     public enum EnvMode {
@@ -41,8 +41,7 @@
 
 
     ProgramFragment(int id, RenderScript rs) {
-        super(rs);
-        mID = id;
+        super(id, rs);
     }
 
     public void bindTexture(Allocation va, int slot)
@@ -65,6 +64,37 @@
         mRS.nProgramFragmentBindSampler(mID, slot, vs.mID);
     }
 
+    public static class ShaderBuilder extends BaseProgramBuilder {
+        public ShaderBuilder(RenderScript rs) {
+            super(rs);
+        }
+
+        public ProgramFragment create() {
+            mRS.validate();
+            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;
+            }
+            tmp[idx++] = 3;
+            tmp[idx++] = mTextureCount;
+
+            int id = mRS.nProgramFragmentCreate2(mShader, tmp);
+            ProgramFragment pf = new ProgramFragment(id, mRS);
+            initProgram(pf);
+            return pf;
+        }
+    }
 
     public static class Builder {
         RenderScript mRS;
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index 06cfc93..101f030 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -79,10 +79,8 @@
                 tmp[idx++] = 2;
                 tmp[idx++] = mConstants[i].mID;
             }
-            for (int i=0; i < mTextureCount; i++) {
-                tmp[idx++] = 3;
-                tmp[idx++] = mTextures[i].mID;
-            }
+            tmp[idx++] = 3;
+            tmp[idx++] = mTextureCount;
 
             int id = mRS.nProgramVertexCreate2(mShader, tmp);
             ProgramVertex pv = new ProgramVertex(id, mRS);
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 75bd3d0..0e4d5b0 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -175,6 +175,7 @@
     native void nProgramFragmentSetSlot(int slot, boolean enable, int env, int vt);
     native void nProgramFragmentSetShader(String txt);
     native int  nProgramFragmentCreate();
+    native int  nProgramFragmentCreate2(String shader, int[] params);
 
     native int  nProgramVertexCreate(boolean texMat);
     native int  nProgramVertexCreate2(String shader, int[] params);
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 1fa15a8..8bacefc 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -1115,6 +1115,24 @@
     return (jint)rsProgramFragmentCreate(con);
 }
 
+static jint
+nProgramFragmentCreate2(JNIEnv *_env, jobject _this, jstring shader, jintArray params)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    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("nProgramFragmentCreate2, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
+
+    jint ret = (jint)rsProgramFragmentCreate2(con, shaderUTF, shaderLen, (uint32_t *)paramPtr, paramLen);
+    _env->ReleaseStringUTFChars(shader, shaderUTF);
+    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
+    return ret;
+}
+
+
 // ---------------------------------------------------------------------------
 
 static jint
@@ -1444,6 +1462,7 @@
 {"nProgramFragmentSetSlot",        "(IZII)V",                              (void*)nProgramFragmentSetSlot },
 {"nProgramFragmentSetShader",      "(Ljava/lang/String;)V",                (void*)nProgramFragmentSetShader },
 {"nProgramFragmentCreate",         "()I",                                  (void*)nProgramFragmentCreate },
+{"nProgramFragmentCreate2",        "(Ljava/lang/String;[I)I",              (void*)nProgramFragmentCreate2 },
 
 {"nProgramRasterCreate",           "(IIZZZ)I",                             (void*)nProgramRasterCreate },
 {"nProgramRasterSetPointSize",     "(IF)V",                                (void*)nProgramRasterSetPointSize },
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 12ae6e1..44ff901 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -167,6 +167,7 @@
     RS_PROGRAM_PARAM_INPUT,
     RS_PROGRAM_PARAM_OUTPUT,
     RS_PROGRAM_PARAM_CONSTANT,
+    RS_PROGRAM_PARAM_TEXTURE_COUNT,
 };
 
 enum RsPrimitive {
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 6ce6b35..5de76b25 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -406,6 +406,14 @@
 	ret RsProgramFragment
 	}
 
+ProgramFragmentCreate2 {
+	param const char * shaderText
+	param uint32_t shaderLength
+	param const uint32_t * params
+	param uint32_t paramLength
+	ret RsProgramFragment
+	}
+
 ProgramVertexCreate {
 	param bool texMat
 	ret RsProgramVertex
@@ -416,7 +424,7 @@
 	param uint32_t shaderLength
 	param const uint32_t * params
 	param uint32_t paramLength
-	ret RsProgramFragment
+	ret RsProgramVertex
 	}
 
 LightBegin {
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index ba27fd4..bcda5fb 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -51,6 +51,7 @@
     mShaderID = 0;
     mAttribCount = 0;
     mUniformCount = 0;
+    mTextureCount = 0;
 
     mInputCount = 0;
     mOutputCount = 0;
@@ -66,6 +67,9 @@
         if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
             mConstantCount++;
         }
+        if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_COUNT) {
+            mTextureCount = params[ct+1];
+        }
     }
 
     mInputElements = new ObjectBaseRef<Element>[mInputCount];
diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h
index 01b4c8861..e9837b7 100644
--- a/libs/rs/rsProgram.h
+++ b/libs/rs/rsProgram.h
@@ -66,6 +66,7 @@
     String8 mUserShader;
     uint32_t mShaderID;
 
+    uint32_t mTextureCount;
     uint32_t mAttribCount;
     uint32_t mUniformCount;
     String8 mAttribNames[MAX_ATTRIBS];
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index 3ddaa37..2d18c42 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -40,6 +40,19 @@
     mEnvModes[1] = RS_TEX_ENV_MODE_DECAL;
 }
 
+ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
+                                 uint32_t shaderLength, const uint32_t * params,
+                                 uint32_t paramLength) :
+    Program(rsc, shaderText, shaderLength, params, paramLength)
+{
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
+
+    init(rsc);
+    mTextureEnableMask = (1 << mTextureCount) -1;
+}
+
+
 ProgramFragment::~ProgramFragment()
 {
 }
@@ -158,58 +171,68 @@
     mShader.append("varying vec4 varColor;\n");
     mShader.append("varying vec4 varTex0;\n");
 
-    uint32_t mask = mTextureEnableMask;
-    uint32_t texNum = 0;
-    while (mask) {
-        if (mask & 1) {
-            char buf[64];
-            mShader.append("uniform sampler2D uni_Tex");
-            sprintf(buf, "%i", texNum);
+    if (mUserShader.length() > 1) {
+        for (uint32_t ct=0; ct < mTextureCount; ct++) {
+            char buf[256];
+            sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
             mShader.append(buf);
-            mShader.append(";\n");
         }
-        mask >>= 1;
-        texNum++;
-    }
 
-
-    mShader.append("void main() {\n");
-    mShader.append("  vec4 col = varColor;\n");
-
-    if (mTextureEnableMask) {
-        if (mPointSpriteEnable) {
-            mShader.append("  vec2 tex0 = gl_PointCoord;\n");
-        } else {
-            mShader.append("  vec2 tex0 = varTex0.xy;\n");
-        }
-    }
-
-    mask = mTextureEnableMask;
-    texNum = 0;
-    while (mask) {
-        if (mask & 1) {
-            switch(mEnvModes[texNum]) {
-            case RS_TEX_ENV_MODE_REPLACE:
-                mShader.append("  col = texture2D(uni_Tex0, tex0);\n");
-                break;
-            case RS_TEX_ENV_MODE_MODULATE:
-                mShader.append("  col *= texture2D(uni_Tex0, tex0);\n");
-                break;
-            case RS_TEX_ENV_MODE_DECAL:
-                mShader.append("  col = texture2D(uni_Tex0, tex0);\n");
-                break;
+        mShader.append(mUserShader);
+    } else {
+        uint32_t mask = mTextureEnableMask;
+        uint32_t texNum = 0;
+        while (mask) {
+            if (mask & 1) {
+                char buf[64];
+                mShader.append("uniform sampler2D uni_Tex");
+                sprintf(buf, "%i", texNum);
+                mShader.append(buf);
+                mShader.append(";\n");
             }
-
+            mask >>= 1;
+            texNum++;
         }
-        mask >>= 1;
-        texNum++;
+
+
+        mShader.append("void main() {\n");
+        mShader.append("  vec4 col = varColor;\n");
+
+        if (mTextureEnableMask) {
+            if (mPointSpriteEnable) {
+                mShader.append("  vec2 tex0 = gl_PointCoord;\n");
+            } else {
+                mShader.append("  vec2 tex0 = varTex0.xy;\n");
+            }
+        }
+
+        mask = mTextureEnableMask;
+        texNum = 0;
+        while (mask) {
+            if (mask & 1) {
+                switch(mEnvModes[texNum]) {
+                case RS_TEX_ENV_MODE_REPLACE:
+                    mShader.append("  col = texture2D(uni_Tex0, tex0);\n");
+                    break;
+                case RS_TEX_ENV_MODE_MODULATE:
+                    mShader.append("  col *= texture2D(uni_Tex0, tex0);\n");
+                    break;
+                case RS_TEX_ENV_MODE_DECAL:
+                    mShader.append("  col = texture2D(uni_Tex0, tex0);\n");
+                    break;
+                }
+
+            }
+            mask >>= 1;
+            texNum++;
+        }
+
+        //mShader.append("  col.a = 1.0;\n");
+        //mShader.append("  col.r = 0.5;\n");
+
+        mShader.append("  gl_FragColor = col;\n");
+        mShader.append("}\n");
     }
-
-    //mShader.append("  col.a = 1.0;\n");
-    //mShader.append("  col.r = 0.5;\n");
-
-    mShader.append("  gl_FragColor = col;\n");
-    mShader.append("}\n");
 }
 
 void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
@@ -361,6 +384,14 @@
     return pf;
 }
 
+RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
+                             uint32_t shaderLength, const uint32_t * params,
+                             uint32_t paramLength)
+{
+    ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
+    pf->incUserRef();
+    return pf;
+}
 
 }
 }
diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h
index 6fc852e..1f548ad 100644
--- a/libs/rs/rsProgramFragment.h
+++ b/libs/rs/rsProgramFragment.h
@@ -33,6 +33,9 @@
 
 
     ProgramFragment(Context *, Element *in, Element *out, bool pointSpriteEnable);
+    ProgramFragment(Context *rsc, const char * shaderText,
+                             uint32_t shaderLength, const uint32_t * params,
+                             uint32_t paramLength);
     virtual ~ProgramFragment();
 
     virtual void setupGL(const Context *, ProgramFragmentState *);