Move texture bindings to base program object.  Change ProgramFragment creation to require a texture format in 1.0 mode.
diff --git a/RenderScript.h b/RenderScript.h
index 44ff901..d10eeda 100644
--- a/RenderScript.h
+++ b/RenderScript.h
@@ -158,6 +158,7 @@
 };
 
 enum RsTexEnvMode {
+    RS_TEX_ENV_MODE_NONE,
     RS_TEX_ENV_MODE_REPLACE,
     RS_TEX_ENV_MODE_MODULATE,
     RS_TEX_ENV_MODE_DECAL
diff --git a/java/Film/src/com/android/film/FilmRS.java b/java/Film/src/com/android/film/FilmRS.java
index 3b93c18..dccc1d2 100644
--- a/java/Film/src/com/android/film/FilmRS.java
+++ b/java/Film/src/com/android/film/FilmRS.java
@@ -121,13 +121,13 @@
         bs.setWrapT(Sampler.Value.WRAP);
         mSampler = bs.create();
 
-        ProgramFragment.Builder b = new ProgramFragment.Builder(mRS, null, null);
-
+        ProgramFragment.Builder b = new ProgramFragment.Builder(mRS);
         mPFBackground = b.create();
         mPFBackground.setName("PFBackground");
 
-        b.setTexEnable(true, 0);
-        b.setTexEnvMode(ProgramFragment.EnvMode.REPLACE, 0);
+        b = new ProgramFragment.Builder(mRS);
+        b.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
+                     ProgramFragment.Builder.Format.RGBA, 0);
         mPFImages = b.create();
         mPFImages.bindSampler(mSampler, 0);
         mPFImages.setName("PFImages");
diff --git a/rs.spec b/rs.spec
index 5de76b2..df41568 100644
--- a/rs.spec
+++ b/rs.spec
@@ -372,37 +372,22 @@
 	param RsAllocation constants
 	}
 
-ProgramFragmentBegin {
-	param RsElement in
-	param RsElement out
-	param bool pointSpriteEnable
-	}
 
-ProgramFragmentSetShader {
-	param const char * text
-	param uint32_t length
-	}
-
-ProgramFragmentBindTexture {
+ProgramBindTexture {
 	param RsProgramFragment pf
 	param uint32_t slot
 	param RsAllocation a
 	}
 
-ProgramFragmentBindSampler {
+ProgramBindSampler {
 	param RsProgramFragment pf
 	param uint32_t slot
 	param RsSampler s
 	}
 
-ProgramFragmentSetSlot {
-	param uint32_t slot
-	param bool enable
-	param RsTexEnvMode env
-	param RsType t
-	}
-
 ProgramFragmentCreate {
+	param const uint32_t * params
+	param uint32_t paramLength
 	ret RsProgramFragment
 	}
 
diff --git a/rsProgram.cpp b/rsProgram.cpp
index e6d1e36..ede8c86 100644
--- a/rsProgram.cpp
+++ b/rsProgram.cpp
@@ -121,6 +121,30 @@
     mDirty = true;
 }
 
+void Program::bindTexture(uint32_t slot, Allocation *a)
+{
+    if (slot >= MAX_TEXTURE) {
+        LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
+        return;
+    }
+
+    //LOGE("bindtex %i %p", slot, a);
+    mTextures[slot].set(a);
+    mDirty = true;
+}
+
+void Program::bindSampler(uint32_t slot, Sampler *s)
+{
+    if (slot >= MAX_TEXTURE) {
+        LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
+        return;
+    }
+
+    mSamplers[slot].set(s);
+    mDirty = true;
+}
+
+
 void Program::createShader()
 {
 }
@@ -182,6 +206,17 @@
     p->bindAllocation(static_cast<Allocation *>(constants));
 }
 
+void rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a)
+{
+    Program *p = static_cast<Program *>(vpf);
+    p->bindTexture(slot, static_cast<Allocation *>(a));
+}
+
+void rsi_ProgramBindSampler(Context *rsc, RsProgram vpf, uint32_t slot, RsSampler s)
+{
+    Program *p = static_cast<Program *>(vpf);
+    p->bindSampler(slot, static_cast<Sampler *>(s));
+}
 
 }
 }
diff --git a/rsProgram.h b/rsProgram.h
index 003498e..25a5434 100644
--- a/rsProgram.h
+++ b/rsProgram.h
@@ -32,6 +32,7 @@
 public:
     const static uint32_t MAX_ATTRIBS = 8;
     const static uint32_t MAX_UNIFORMS = 16;
+    const static uint32_t MAX_TEXTURE = 2;
 
     Program(Context *);
     Program(Context *, const char * shaderText, uint32_t shaderLength,
@@ -41,6 +42,9 @@
     void bindAllocation(Allocation *);
     virtual void createShader();
 
+    void bindTexture(uint32_t slot, Allocation *);
+    void bindSampler(uint32_t slot, Sampler *);
+
     uint32_t getShaderID() const {return mShaderID;}
     void setShader(const char *, uint32_t len);
 
@@ -72,6 +76,15 @@
     String8 mAttribNames[MAX_ATTRIBS];
     String8 mUniformNames[MAX_UNIFORMS];
 
+    // The difference between Textures and Constants is how they are accessed
+    // Texture lookups go though a sampler which in effect converts normalized
+    // coordinates into type specific.  Multiple samples may also be taken
+    // and filtered.
+    //
+    // Constants are strictly accessed by programetic loads.
+    ObjectBaseRef<Allocation> mTextures[MAX_TEXTURE];
+    ObjectBaseRef<Sampler> mSamplers[MAX_TEXTURE];
+
     bool loadShader(Context *, uint32_t type);
 
 public:
diff --git a/rsProgramFragment.cpp b/rsProgramFragment.cpp
index c353301..05672e5 100644
--- a/rsProgramFragment.cpp
+++ b/rsProgramFragment.cpp
@@ -26,18 +26,28 @@
 using namespace android::renderscript;
 
 
-ProgramFragment::ProgramFragment(Context *rsc, Element *in, Element *out, bool pointSpriteEnable) :
+ProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params,
+                                 uint32_t paramLength) :
     Program(rsc)
 {
     mAllocFile = __FILE__;
     mAllocLine = __LINE__;
-    for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
-        mEnvModes[ct] = RS_TEX_ENV_MODE_REPLACE;
-        mTextureDimensions[ct] = 2;
-    }
+    rsAssert(paramLength = 5);
+
+    mEnvModes[0] = (RsTexEnvMode)params[0];
+    mTextureFormats[0] = params[1];
+    mEnvModes[1] = (RsTexEnvMode)params[2];
+    mTextureFormats[1] = params[3];
+    mPointSpriteEnable = params[4] != 0;
+
     mTextureEnableMask = 0;
-    mPointSpriteEnable = pointSpriteEnable;
-    mEnvModes[1] = RS_TEX_ENV_MODE_DECAL;
+    if (mEnvModes[0]) {
+        mTextureEnableMask |= 1;
+    }
+    if (mEnvModes[1]) {
+        mTextureEnableMask |= 2;
+    }
+    init(rsc);
 }
 
 ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
@@ -84,6 +94,9 @@
         glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
 
         switch(mEnvModes[ct]) {
+        case RS_TEX_ENV_MODE_NONE:
+            rsAssert(0);
+            break;
         case RS_TEX_ENV_MODE_REPLACE:
             glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
             break;
@@ -211,6 +224,9 @@
         while (mask) {
             if (mask & 1) {
                 switch(mEnvModes[texNum]) {
+                case RS_TEX_ENV_MODE_NONE:
+                    rsAssert(0);
+                    break;
                 case RS_TEX_ENV_MODE_REPLACE:
                     mShader.append("  col = texture2D(uni_Tex0, tex0);\n");
                     break;
@@ -235,69 +251,6 @@
     }
 }
 
-void ProgramFragment::bindTexture(uint32_t slot, Allocation *a)
-{
-    if (slot >= MAX_TEXTURE) {
-        LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
-        return;
-    }
-
-    //LOGE("bindtex %i %p", slot, a);
-    mTextures[slot].set(a);
-    mDirty = true;
-}
-
-void ProgramFragment::bindSampler(uint32_t slot, Sampler *s)
-{
-    if (slot >= MAX_TEXTURE) {
-        LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
-        return;
-    }
-
-    mSamplers[slot].set(s);
-    mDirty = true;
-}
-
-void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
-{
-    if (slot >= MAX_TEXTURE) {
-        LOGE("Attempt to setType to a slot > MAX_TEXTURE");
-        return;
-    }
-
-    if (dim >= 4) {
-        LOGE("Attempt to setType to a dimension > 3");
-        return;
-    }
-
-    mTextureFormats[slot].set(e);
-    mTextureDimensions[slot] = dim;
-}
-
-void ProgramFragment::setEnvMode(uint32_t slot, RsTexEnvMode env)
-{
-    if (slot >= MAX_TEXTURE) {
-        LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
-        return;
-    }
-
-    mEnvModes[slot] = env;
-}
-
-void ProgramFragment::setTexEnable(uint32_t slot, bool enable)
-{
-    if (slot >= MAX_TEXTURE) {
-        LOGE("Attempt to setEnvMode to a slot > MAX_TEXTURE");
-        return;
-    }
-
-    uint32_t bit = 1 << slot;
-    mTextureEnableMask &= ~bit;
-    if (enable) {
-        mTextureEnableMask |= bit;
-    }
-}
-
 void ProgramFragment::init(Context *rsc)
 {
     mUniformCount = 2;
@@ -320,7 +273,12 @@
 
 void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
 {
-    ProgramFragment *pf = new ProgramFragment(rsc, NULL, NULL, false);
+    uint32_t tmp[5] = {
+        RS_TEX_ENV_MODE_NONE, 0,
+        RS_TEX_ENV_MODE_NONE, 0,
+        0
+    };
+    ProgramFragment *pf = new ProgramFragment(rsc, tmp, 5);
     mDefault.set(pf);
     pf->init(rsc);
 }
@@ -335,52 +293,12 @@
 namespace android {
 namespace renderscript {
 
-void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out, bool pointSpriteEnable)
+RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
+                                            const uint32_t * params,
+                                            uint32_t paramLength)
 {
-    delete rsc->mStateFragment.mPF;
-    rsc->mStateFragment.mPF = new ProgramFragment(rsc, (Element *)in, (Element *)out, pointSpriteEnable);
-}
-
-void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
-{
-    ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
-    pf->bindTexture(slot, static_cast<Allocation *>(a));
-}
-
-void rsi_ProgramFragmentBindSampler(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsSampler s)
-{
-    ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
-    pf->bindSampler(slot, static_cast<Sampler *>(s));
-}
-
-void rsi_ProgramFragmentSetSlot(Context *rsc, uint32_t slot, bool enable, RsTexEnvMode env, RsType vt)
-{
-    const Type *t = static_cast<const Type *>(vt);
-    if (t) {
-        uint32_t dim = 1;
-        if (t->getDimY()) {
-            dim ++;
-            if (t->getDimZ()) {
-                dim ++;
-            }
-        }
-        rsc->mStateFragment.mPF->setType(slot, t->getElement(), dim);
-    }
-    rsc->mStateFragment.mPF->setEnvMode(slot, env);
-    rsc->mStateFragment.mPF->setTexEnable(slot, enable);
-}
-
-void rsi_ProgramFragmentSetShader(Context *rsc, const char *txt, uint32_t len)
-{
-    rsc->mStateFragment.mPF->setShader(txt, len);
-}
-
-RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
-{
-    ProgramFragment *pf = rsc->mStateFragment.mPF;
+    ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
     pf->incUserRef();
-    pf->init(rsc);
-    rsc->mStateFragment.mPF = 0;
     return pf;
 }
 
diff --git a/rsProgramFragment.h b/rsProgramFragment.h
index 14b4ec3..9fa565d 100644
--- a/rsProgramFragment.h
+++ b/rsProgramFragment.h
@@ -28,11 +28,7 @@
 class ProgramFragment : public Program
 {
 public:
-    const static uint32_t MAX_TEXTURE = 2;
-
-
-
-    ProgramFragment(Context *, Element *in, Element *out, bool pointSpriteEnable);
+    ProgramFragment(Context *, const uint32_t * params, uint32_t paramLength);
     ProgramFragment(Context *rsc, const char * shaderText,
                              uint32_t shaderLength, const uint32_t * params,
                              uint32_t paramLength);
@@ -41,33 +37,14 @@
     virtual void setupGL(const Context *, ProgramFragmentState *);
     virtual void setupGL2(const Context *, ProgramFragmentState *, ShaderCache *sc);
 
-
-    void bindTexture(uint32_t slot, Allocation *);
-    void bindSampler(uint32_t slot, Sampler *);
-    void setType(uint32_t slot, const Element *, uint32_t dim);
-
-    void setEnvMode(uint32_t slot, RsTexEnvMode);
-    void setTexEnable(uint32_t slot, bool);
-
     virtual void createShader();
     virtual void loadShader(Context *rsc);
     virtual void init(Context *rsc);
 
-
 protected:
-    // The difference between Textures and Constants is how they are accessed
-    // Texture lookups go though a sampler which in effect converts normalized
-    // coordinates into type specific.  Multiple samples may also be taken
-    // and filtered.
-    //
-    // Constants are strictly accessed by programetic loads.
-    ObjectBaseRef<Allocation> mTextures[MAX_TEXTURE];
-    ObjectBaseRef<Sampler> mSamplers[MAX_TEXTURE];
-    ObjectBaseRef<const Element> mTextureFormats[MAX_TEXTURE];
-    uint32_t mTextureDimensions[MAX_TEXTURE];
-
-
     // Hacks to create a program for now
+    uint32_t mTextureFormats[MAX_TEXTURE];
+    uint32_t mTextureDimensions[MAX_TEXTURE];
     RsTexEnvMode mEnvModes[MAX_TEXTURE];
     uint32_t mTextureEnableMask;
     bool mPointSpriteEnable;
diff --git a/rsScriptC_Lib.cpp b/rsScriptC_Lib.cpp
index ade136c..e9f47d6 100644
--- a/rsScriptC_Lib.cpp
+++ b/rsScriptC_Lib.cpp
@@ -619,20 +619,20 @@
 static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
 {
     GET_TLS();
-    rsi_ProgramFragmentBindTexture(rsc,
-                                   static_cast<ProgramFragment *>(vpf),
-                                   slot,
-                                   static_cast<Allocation *>(va));
+    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_ProgramFragmentBindSampler(rsc,
-                                   static_cast<ProgramFragment *>(vpf),
-                                   slot,
-                                   static_cast<Sampler *>(vs));
+    rsi_ProgramBindSampler(rsc,
+                           static_cast<ProgramFragment *>(vpf),
+                           slot,
+                           static_cast<Sampler *>(vs));
 
 }
 
@@ -846,9 +846,7 @@
     rsc->mStateVertex.color[1] = g;
     rsc->mStateVertex.color[2] = b;
     rsc->mStateVertex.color[3] = a;
-    if (rsc->checkVersion2_0()) {
-        glVertexAttrib4f(1, r, g, b, a);
-    } else {
+    if (!rsc->checkVersion2_0()) {
         glColor4f(r, g, b, a);
     }
 }