Fixing uniform binding for fragment shader.
Updating the glsl fragment shader to color the lights.

Change-Id: I6f850d1aa22059a2974e379f652f7e99d6a799fb
diff --git a/java/Samples/res/raw/shaderf.glsl b/java/Samples/res/raw/shaderf.glsl
index 81452ab..fdcf481 100644
--- a/java/Samples/res/raw/shaderf.glsl
+++ b/java/Samples/res/raw/shaderf.glsl
@@ -7,12 +7,9 @@
 void main() {
    vec2 t0 = varTex0.xy;
    lowp vec4 col = texture2D(uni_Tex0, t0).rgba;
-   /*col = col * (light0_Diffuse * UNI_light0_DiffuseColor + light1_Diffuse * UNI_light1_DiffuseColor);
-   col += light0_Specular * UNI_light0_SpecularColor;
-   col += light1_Specular * UNI_light1_SpecularColor;*/
-   col = col * (light0_Diffuse + light1_Diffuse);
-   col += light0_Specular;
-   col += light1_Specular;
+   col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor + light1_Diffuse * UNI_light1_DiffuseColor);
+   col.xyz += light0_Specular * UNI_light0_SpecularColor;
+   col.xyz += light1_Specular * UNI_light1_SpecularColor;
    gl_FragColor = col;
 }
 
diff --git a/java/Samples/src/com/android/samples/rsrenderstates.rs b/java/Samples/src/com/android/samples/rsrenderstates.rs
index 165a6d7..91613cf 100644
--- a/java/Samples/src/com/android/samples/rsrenderstates.rs
+++ b/java/Samples/src/com/android/samples/rsrenderstates.rs
@@ -73,6 +73,8 @@
 //What we are showing
 #pragma rs export_var(gDisplayMode)
 
+float gDt = 0;
+
 void init() {
 }
 
@@ -300,7 +302,7 @@
     rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
 
     // Aplly a rotation to our mesh
-    gTorusRotation += 50.0f * rsGetDt();
+    gTorusRotation += 50.0f * gDt;
     if(gTorusRotation > 360.0f) {
         gTorusRotation -= 360.0f;
     }
@@ -333,15 +335,15 @@
     float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f};
     float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f};
     float3 light0DiffCol = {0.9f, 0.7f, 0.7f};
-    float3 light0SpecCol = {0.9f, 0.8f, 0.8f};
-    float3 light1DiffCol = {0.7f, 0.7f, 0.9f};
-    float3 light1SpecCol = {0.8f, 0.8f, 0.9f};
+    float3 light0SpecCol = {0.9f, 0.6f, 0.6f};
+    float3 light1DiffCol = {0.5f, 0.5f, 0.9f};
+    float3 light1SpecCol = {0.5f, 0.5f, 0.9f};
 
-    gLight0Rotation += 150.0f * rsGetDt();
+    gLight0Rotation += 50.0f * gDt;
     if(gLight0Rotation > 360.0f) {
         gLight0Rotation -= 360.0f;
     }
-    gLight1Rotation -= 50.0f * rsGetDt();
+    gLight1Rotation -= 50.0f * gDt;
     if(gLight1Rotation > 360.0f) {
         gLight1Rotation -= 360.0f;
     }
@@ -359,7 +361,7 @@
     gVSConstants->light0_Posision.z = light0Pos.z;
     gVSConstants->light0_Diffuse = 1.0f;
     gVSConstants->light0_Specular = 0.5f;
-    gVSConstants->light0_CosinePower = 70.0f;
+    gVSConstants->light0_CosinePower = 40.0f;
     // Set light 1 properties
     gVSConstants->light1_Posision.x = light1Pos.x;
     gVSConstants->light1_Posision.y = light1Pos.y;
@@ -382,7 +384,7 @@
     // Update vertex shader constants
     // Load model matrix
     // Aplly a rotation to our mesh
-    gTorusRotation += 50.0f * rsGetDt();
+    gTorusRotation += 50.0f * gDt;
     if(gTorusRotation > 360.0f) {
         gTorusRotation -= 360.0f;
     }
@@ -390,6 +392,7 @@
     // Position our model on the screen
     rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
     rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+    rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
     setupCustomShaderLights();
 
     rsgBindProgramVertex(gProgVertexCustom);
@@ -416,6 +419,8 @@
 
 int root(int launchID) {
 
+    gDt = rsGetDt();
+
     rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
     rsgClearDepth(1.0f);
 
diff --git a/rsProgram.cpp b/rsProgram.cpp
index c4f8b2e..6041db8 100644
--- a/rsProgram.cpp
+++ b/rsProgram.cpp
@@ -241,7 +241,129 @@
     mUserShader.setTo(txt, len);
 }
 
+void Program::appendUserConstants() {
+    for (uint32_t ct=0; ct < mConstantCount; ct++) {
+        const Element *e = mConstantTypes[ct]->getElement();
+        for (uint32_t field=0; field < e->getFieldCount(); field++) {
+            const Element *f = e->getField(field);
+            const char *fn = e->getFieldName(field);
 
+            if (fn[0] == '#') {
+                continue;
+            }
+
+            // Cannot be complex
+            rsAssert(!f->getFieldCount());
+            if(f->getType() == RS_TYPE_MATRIX_4X4) {
+                mShader.append("uniform mat4 UNI_");
+            }
+            else if(f->getType() == RS_TYPE_MATRIX_3X3) {
+                mShader.append("uniform mat3 UNI_");
+            }
+            else if(f->getType() == RS_TYPE_MATRIX_2X2) {
+                mShader.append("uniform mat2 UNI_");
+            }
+            else {
+                switch(f->getComponent().getVectorSize()) {
+                case 1: mShader.append("uniform float UNI_"); break;
+                case 2: mShader.append("uniform vec2 UNI_"); break;
+                case 3: mShader.append("uniform vec3 UNI_"); break;
+                case 4: mShader.append("uniform vec4 UNI_"); break;
+                default:
+                    rsAssert(0);
+                }
+            }
+
+            mShader.append(fn);
+            mShader.append(";\n");
+        }
+    }
+}
+
+void Program::setupUserConstants(ShaderCache *sc, bool isFragment) {
+    uint32_t uidx = 1;
+    for (uint32_t ct=0; ct < mConstantCount; ct++) {
+        Allocation *alloc = mConstants[ct+1].get();
+        if (!alloc) {
+            continue;
+        }
+
+        const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
+        const Element *e = mConstantTypes[ct]->getElement();
+        for (uint32_t field=0; field < e->getFieldCount(); field++) {
+            const Element *f = e->getField(field);
+            const char *fieldName = e->getFieldName(field);
+            // If this field is padding, skip it
+            if(fieldName[0] == '#') {
+                continue;
+            }
+
+            uint32_t offset = e->getFieldOffsetBytes(field);
+            const float *fd = reinterpret_cast<const float *>(&data[offset]);
+
+            int32_t slot = -1;
+            if(!isFragment) {
+                slot = sc->vtxUniformSlot(uidx);
+            }
+            else {
+                slot = sc->fragUniformSlot(uidx);
+            }
+
+            //LOGE("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
+            if (slot >= 0) {
+                if(f->getType() == RS_TYPE_MATRIX_4X4) {
+                    glUniformMatrix4fv(slot, 1, GL_FALSE, fd);
+                }
+                else if(f->getType() == RS_TYPE_MATRIX_3X3) {
+                    glUniformMatrix3fv(slot, 1, GL_FALSE, fd);
+                }
+                else if(f->getType() == RS_TYPE_MATRIX_2X2) {
+                    glUniformMatrix2fv(slot, 1, GL_FALSE, fd);
+                }
+                else {
+                    switch(f->getComponent().getVectorSize()) {
+                    case 1:
+                        //LOGE("Uniform 1 = %f", fd[0]);
+                        glUniform1fv(slot, 1, fd);
+                        break;
+                    case 2:
+                        //LOGE("Uniform 2 = %f %f", fd[0], fd[1]);
+                        glUniform2fv(slot, 1, fd);
+                        break;
+                    case 3:
+                        //LOGE("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
+                        glUniform3fv(slot, 1, fd);
+                        break;
+                    case 4:
+                        //LOGE("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
+                        glUniform4fv(slot, 1, fd);
+                        break;
+                    default:
+                        rsAssert(0);
+                    }
+                }
+            }
+            uidx ++;
+        }
+    }
+}
+
+void Program::initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix)
+{
+    rsAssert(e->getFieldCount());
+    for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
+        const Element *ce = e->getField(ct);
+        if (ce->getFieldCount()) {
+            initAddUserElement(ce, names, count, prefix);
+        }
+        else if(e->getFieldName(ct)[0] != '#') {
+            String8 tmp(prefix);
+            tmp.append(e->getFieldName(ct));
+            names[*count].setTo(tmp.string());
+            (*count)++;
+        }
+    }
+}
 
 namespace android {
 namespace renderscript {
diff --git a/rsProgram.h b/rsProgram.h
index 86f85fb..ddc5e8a 100644
--- a/rsProgram.h
+++ b/rsProgram.h
@@ -72,6 +72,11 @@
     uint32_t mConstantCount;
     bool mIsValid;
 
+    // Applies to vertex and fragment shaders only
+    void appendUserConstants();
+    void setupUserConstants(ShaderCache *sc, bool isFragment);
+    void initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix);
+
     ObjectBaseRef<Allocation> mConstants[MAX_UNIFORMS];
 
     mutable bool mDirty;
diff --git a/rsProgramFragment.cpp b/rsProgramFragment.cpp
index a045043..ec9c569 100644
--- a/rsProgramFragment.cpp
+++ b/rsProgramFragment.cpp
@@ -71,7 +71,7 @@
         mConstantColorUniformIndex = mUniformCount;
         mUniformNames[mUniformCount++].setTo("uni_Color");
     //}
-    createShader();
+    init(rsc);
 }
 
 ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
@@ -93,9 +93,9 @@
     mUniformNames[0].setTo("uni_Tex0");
     mUniformNames[1].setTo("uni_Tex1");
 
-    createShader();
-
     mTextureEnableMask = (1 << mTextureCount) -1;
+
+    init(rsc);
 }
 
 
@@ -134,6 +134,9 @@
         rsc->checkError("ProgramFragment::color setup");
     }
 
+    rsc->checkError("ProgramFragment::setupGL2 begin uniforms");
+    setupUserConstants(sc, true);
+
     for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
         glActiveTexture(GL_TEXTURE0 + ct);
         if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
@@ -179,7 +182,7 @@
             sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
             mShader.append(buf);
         }
-
+        appendUserConstants();
         mShader.append(mUserShader);
     } else {
         uint32_t mask = mTextureEnableMask;
@@ -272,6 +275,13 @@
 
 void ProgramFragment::init(Context *rsc)
 {
+    if (mUserShader.size() > 0) {
+        for (uint32_t ct=0; ct < mConstantCount; ct++) {
+            initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_");
+        }
+    }
+
+    createShader();
 }
 
 void ProgramFragment::serialize(OStream *stream) const
@@ -304,7 +314,6 @@
     };
     ProgramFragment *pf = new ProgramFragment(rsc, tmp, 6);
     mDefault.set(pf);
-    pf->init(rsc);
 }
 
 void ProgramFragmentState::deinit(Context *rsc)
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
index 8468e26..41d8247 100644
--- a/rsProgramVertex.cpp
+++ b/rsProgramVertex.cpp
@@ -134,43 +134,7 @@
         mShader.append(mUniformNames[0]);
         mShader.append(";\n");
 
-        for (uint32_t ct=0; ct < mConstantCount; ct++) {
-            const Element *e = mConstantTypes[ct]->getElement();
-            for (uint32_t field=0; field < e->getFieldCount(); field++) {
-                const Element *f = e->getField(field);
-                const char *fn = e->getFieldName(field);
-
-                if (fn[0] == '#') {
-                    continue;
-                }
-
-                // Cannot be complex
-                rsAssert(!f->getFieldCount());
-                if(f->getType() == RS_TYPE_MATRIX_4X4) {
-                    mShader.append("uniform mat4 UNI_");
-                }
-                else if(f->getType() == RS_TYPE_MATRIX_3X3) {
-                    mShader.append("uniform mat3 UNI_");
-                }
-                else if(f->getType() == RS_TYPE_MATRIX_2X2) {
-                    mShader.append("uniform mat2 UNI_");
-                }
-                else {
-                    switch(f->getComponent().getVectorSize()) {
-                    case 1: mShader.append("uniform float UNI_"); break;
-                    case 2: mShader.append("uniform vec2 UNI_"); break;
-                    case 3: mShader.append("uniform vec3 UNI_"); break;
-                    case 4: mShader.append("uniform vec4 UNI_"); break;
-                    default:
-                        rsAssert(0);
-                    }
-                }
-
-                mShader.append(fn);
-                mShader.append(";\n");
-            }
-        }
-
+        appendUserConstants();
 
         for (uint32_t ct=0; ct < mInputCount; ct++) {
             const Element *e = mInputElements[ct].get();
@@ -248,65 +212,7 @@
     }
 
     rsc->checkError("ProgramVertex::setupGL2 begin uniforms");
-    uint32_t uidx = 1;
-    for (uint32_t ct=0; ct < mConstantCount; ct++) {
-        Allocation *alloc = mConstants[ct+1].get();
-        if (!alloc) {
-            continue;
-        }
-
-        const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
-        const Element *e = mConstantTypes[ct]->getElement();
-        for (uint32_t field=0; field < e->getFieldCount(); field++) {
-            const Element *f = e->getField(field);
-            uint32_t offset = e->getFieldOffsetBytes(field);
-            int32_t slot = sc->vtxUniformSlot(uidx);
-            const char *fieldName = e->getFieldName(field);
-
-            const float *fd = reinterpret_cast<const float *>(&data[offset]);
-
-            // If this field is padding, skip it
-            if(fieldName[0] == '#') {
-                continue;
-            }
-
-            //LOGE("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
-            if (slot >= 0) {
-                if(f->getType() == RS_TYPE_MATRIX_4X4) {
-                    glUniformMatrix4fv(slot, 1, GL_FALSE, fd);
-                }
-                else if(f->getType() == RS_TYPE_MATRIX_3X3) {
-                    glUniformMatrix3fv(slot, 1, GL_FALSE, fd);
-                }
-                else if(f->getType() == RS_TYPE_MATRIX_2X2) {
-                    glUniformMatrix2fv(slot, 1, GL_FALSE, fd);
-                }
-                else {
-                    switch(f->getComponent().getVectorSize()) {
-                    case 1:
-                        //LOGE("Uniform 1 = %f", fd[0]);
-                        glUniform1fv(slot, 1, fd);
-                        break;
-                    case 2:
-                        //LOGE("Uniform 2 = %f %f", fd[0], fd[1]);
-                        glUniform2fv(slot, 1, fd);
-                        break;
-                    case 3:
-                        //LOGE("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
-                        glUniform3fv(slot, 1, fd);
-                        break;
-                    case 4:
-                        //LOGE("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
-                        glUniform4fv(slot, 1, fd);
-                        break;
-                    default:
-                        rsAssert(0);
-                    }
-                }
-            }
-            uidx ++;
-        }
-    }
+    setupUserConstants(sc, false);
 
     state->mLast.set(this);
     rsc->checkError("ProgramVertex::setupGL2");
@@ -356,24 +262,6 @@
     mvp.vectorMultiply(v4out, v3in);
 }
 
-void ProgramVertex::initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix)
-{
-    rsAssert(e->getFieldCount());
-    for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
-        const Element *ce = e->getField(ct);
-        if (ce->getFieldCount()) {
-            initAddUserElement(ce, names, count, prefix);
-        }
-        else if(e->getFieldName(ct)[0] != '#') {
-            String8 tmp(prefix);
-            tmp.append(e->getFieldName(ct));
-            names[*count].setTo(tmp.string());
-            (*count)++;
-        }
-    }
-}
-
-
 void ProgramVertex::init(Context *rsc)
 {
     mAttribCount = 0;
diff --git a/rsProgramVertex.h b/rsProgramVertex.h
index a17c9ea..59fd319 100644
--- a/rsProgramVertex.h
+++ b/rsProgramVertex.h
@@ -63,9 +63,6 @@
 
     // Hacks to create a program for now
     bool mTextureMatrixEnable;
-
-private:
-    void initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix);
 };