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/Android.mk b/Android.mk
index 3080ab0..111bdd4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -76,7 +76,6 @@
 LOCAL_SRC_FILES:= \
 	rsAdapter.cpp \
 	rsAllocation.cpp \
-	rsComponent.cpp \
 	rsContext.cpp \
 	rsDevice.cpp \
 	rsElement.cpp \
diff --git a/RenderScript.h b/RenderScript.h
index 3ca8b15..12ae6e1 100644
--- a/RenderScript.h
+++ b/RenderScript.h
@@ -36,11 +36,11 @@
 typedef void * RsFile;
 typedef void * RsSampler;
 typedef void * RsScript;
-typedef void * RsScriptBasicTemp;
 typedef void * RsSimpleMesh;
 typedef void * RsType;
 typedef void * RsLight;
 
+typedef void * RsProgram;
 typedef void * RsProgramVertex;
 typedef void * RsProgramFragment;
 typedef void * RsProgramFragmentStore;
@@ -163,6 +163,12 @@
     RS_TEX_ENV_MODE_DECAL
 };
 
+enum RsProgramParam {
+    RS_PROGRAM_PARAM_INPUT,
+    RS_PROGRAM_PARAM_OUTPUT,
+    RS_PROGRAM_PARAM_CONSTANT,
+};
+
 enum RsPrimitive {
     RS_PRIMITIVE_POINT,
     RS_PRIMITIVE_LINE,
diff --git a/RenderScriptEnv.h b/RenderScriptEnv.h
index ff0a7b1..99b8c04 100644
--- a/RenderScriptEnv.h
+++ b/RenderScriptEnv.h
@@ -9,7 +9,6 @@
 typedef void * RsElement;
 typedef void * RsSampler;
 typedef void * RsScript;
-typedef void * RsScriptBasicTemp;
 typedef void * RsSimpleMesh;
 typedef void * RsType;
 typedef void * RsProgramFragment;
diff --git a/java/Film/src/com/android/film/FilmRS.java b/java/Film/src/com/android/film/FilmRS.java
index b5b6723..3b93c18 100644
--- a/java/Film/src/com/android/film/FilmRS.java
+++ b/java/Film/src/com/android/film/FilmRS.java
@@ -138,7 +138,7 @@
         mLight.setPosition(0, -0.5f, -1.0f);
 
         ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
-        pvb.addLight(mLight);
+        //pvb.addLight(mLight);
         mPVBackground = pvb.create();
         mPVBackground.setName("PVBackground");
 
diff --git a/rs.spec b/rs.spec
index c7ae18a..6ce6b35 100644
--- a/rs.spec
+++ b/rs.spec
@@ -366,6 +366,12 @@
 }
 
 
+ProgramBindConstants {
+	param RsProgram vp
+	param uint32_t slot
+	param RsAllocation constants
+	}
+
 ProgramFragmentBegin {
 	param RsElement in
 	param RsElement out
@@ -400,32 +406,17 @@
 	ret RsProgramFragment
 	}
 
-
-ProgramVertexBegin {
-	param RsElement in
-	param RsElement out
-	}
-
 ProgramVertexCreate {
+	param bool texMat
 	ret RsProgramVertex
 	}
 
-ProgramVertexBindAllocation {
-	param RsProgramVertex vpgm
-	param RsAllocation constants
-	}
-
-ProgramVertexSetTextureMatrixEnable {
-	param bool enable
-	}
-
-ProgramVertexSetShader {
-	param const char * text
-	param uint32_t length
-	}
-
-ProgramVertexAddLight {
-	param RsLight light
+ProgramVertexCreate2 {
+	param const char * shaderText
+	param uint32_t shaderLength
+	param const uint32_t * params
+	param uint32_t paramLength
+	ret RsProgramFragment
 	}
 
 LightBegin {
diff --git a/rsComponent.cpp b/rsComponent.cpp
deleted file mode 100644
index de074c8..0000000
--- a/rsComponent.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-#include "rsComponent.h"
-#include <GLES/gl.h>
-
-using namespace android;
-using namespace android::renderscript;
-
-
-Component::Component(Context *rsc) : ObjectBase(rsc)
-{
-    mAllocFile = __FILE__;
-    mAllocLine = __LINE__;
-    mType = FLOAT;
-    mKind = USER;
-    mIsNormalized = false;
-    mBits = 0;
-}
-
-Component::Component(Context *rsc,
-    DataKind dk, DataType dt,
-    bool isNormalized, uint32_t bits, const char * name) : ObjectBase(rsc)
-{
-    mAllocFile = __FILE__;
-    mAllocLine = __LINE__;
-    mType = dt;
-    mKind = dk;
-    mIsNormalized = isNormalized;
-    mBits = bits;
-    if (name) {
-        mName = name;
-    }
-}
-
-const char * Component::getCType() const
-{
-    switch(mType) {
-    case FLOAT:
-        return "float";
-    case SIGNED:
-    case UNSIGNED:
-        switch(mBits) {
-        case 32:
-            return "int";
-        case 16:
-            return "short";
-        case 8:
-            return "char";
-        }
-        break;
-    }
-    return NULL;
-}
-
-Component::~Component()
-{
-}
-
-uint32_t Component::getGLType() const
-{
-    switch(mType) {
-    case RS_TYPE_FLOAT:
-        rsAssert(mBits == 32);
-        return GL_FLOAT;
-    case RS_TYPE_SIGNED:
-        switch(mBits) {
-        case 32:
-            return 0;//GL_INT;
-        case 16:
-            return GL_SHORT;
-        case 8:
-            return GL_BYTE;
-        }
-        break;
-    case RS_TYPE_UNSIGNED:
-        switch(mBits) {
-        case 32:
-            return 0;//GL_UNSIGNED_INT;
-        case 16:
-            return GL_UNSIGNED_SHORT;
-        case 8:
-            return GL_UNSIGNED_BYTE;
-        }
-        break;
-    }
-    //rsAssert(!"Bad type");
-    //LOGE("mType %i, mKind %i, mBits %i, mIsNormalized %i", mType, mKind, mBits, mIsNormalized);
-    return 0;
-}
-
-void Component::dumpLOGV(const char *prefix) const
-{
-    ObjectBase::dumpLOGV(prefix);
-    LOGV("%s   component: %i %i %i %i", prefix, mType, mKind, mIsNormalized, mBits);
-}
-
diff --git a/rsComponent.h b/rsComponent.h
deleted file mode 100644
index 5366cc4..0000000
--- a/rsComponent.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-#ifndef ANDROID_RS_STRUCTURED_COMPONENT_H
-#define ANDROID_RS_STRUCTURED_COMPONENT_H
-
-#include "rsUtils.h"
-#include "rsObjectBase.h"
-
-// ---------------------------------------------------------------------------
-namespace android {
-namespace renderscript {
-
-class Component : public ObjectBase
-{
-public:
-    enum DataType {
-        FLOAT,
-        UNSIGNED,
-        SIGNED
-    };
-
-    enum DataKind {
-        USER,
-        RED, GREEN, BLUE, ALPHA, LUMINANCE, INTENSITY,
-        X, Y, Z, W,
-        S, T, Q, R,
-        NX, NY, NZ,
-        INDEX,
-        POINT_SIZE
-    };
-
-
-    Component(Context *rsc, DataKind dk, DataType dt, bool isNorm, uint32_t bits, const char *);
-    virtual ~Component();
-
-    DataType getType() const {return mType;}
-    bool getIsNormalized() const {return mIsNormalized;}
-    DataKind getKind() const {return mKind;}
-    uint32_t getBits() const {return mBits;}
-
-    uint32_t getGLType() const;
-    const char * getCType() const;
-
-    const char * getComponentName() const {return mName.string();}
-    virtual void dumpLOGV(const char *prefix) const;
-
-protected:
-
-    DataType mType;
-    bool mIsNormalized;
-    DataKind mKind;
-    uint32_t mBits;
-    String8 mName;
-
-private:
-    Component(Context *rsc);
-};
-
-
-}
-}
-
-#endif //ANDROID_RS_STRUCTURED_COMPONENT_H
-
diff --git a/rsContext.cpp b/rsContext.cpp
index f815bad..96c289e 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -27,6 +27,8 @@
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 
 #include <cutils/sched_policy.h>
 
@@ -525,6 +527,16 @@
             } else {
                 sscanf(verptr, " %i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion);
             }
+
+            glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mGL.mMaxVertexAttribs);
+            glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &mGL.mMaxVertexUniformVectors);
+            glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGL.mMaxVertexTextureUnits);
+
+            glGetIntegerv(GL_MAX_VARYING_VECTORS, &mGL.mMaxVaryingVectors);
+            glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGL.mMaxTextureImageUnits);
+
+            glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mGL.mMaxFragmentTextureImageUnits);
+            glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGL.mMaxFragmentUniformVectors);
         }
 
     }
@@ -771,6 +783,10 @@
     LOGE(" RS running %i, exit %i, useDepth %i, paused %i", mRunning, mExit, mUseDepth, mPaused);
     LOGE(" RS pThreadID %li, nativeThreadID %i", mThreadId, mNativeThreadId);
 
+    LOGV("MAX Textures %i, %i  %i", mGL.mMaxVertexTextureUnits, mGL.mMaxFragmentTextureImageUnits, mGL.mMaxTextureImageUnits);
+    LOGV("MAX Attribs %i", mGL.mMaxVertexAttribs);
+    LOGV("MAX Uniforms %i, %i", mGL.mMaxVertexUniformVectors, mGL.mMaxFragmentUniformVectors);
+    LOGV("MAX Varyings %i", mGL.mMaxVaryingVectors);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/rsContext.h b/rsContext.h
index 426f921..790aca6 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -194,6 +194,15 @@
         uint32_t mMajorVersion;
         uint32_t mMinorVersion;
 
+        int32_t mMaxVaryingVectors;
+        int32_t mMaxTextureImageUnits;
+
+        int32_t mMaxFragmentTextureImageUnits;
+        int32_t mMaxFragmentUniformVectors;
+
+        int32_t mMaxVertexAttribs;
+        int32_t mMaxVertexUniformVectors;
+        int32_t mMaxVertexTextureUnits;
     } mGL;
 
     uint32_t mWidth;
diff --git a/rsElement.cpp b/rsElement.cpp
index 67e4f14..e796556 100644
--- a/rsElement.cpp
+++ b/rsElement.cpp
@@ -24,19 +24,16 @@
 
 Element::Element(Context *rsc) : ObjectBase(rsc)
 {
+    mType = RS_TYPE_FLOAT;
+    mIsNormalized = false;
+    mKind = RS_KIND_USER;
+    mBits = 0;
     mAllocFile = __FILE__;
     mAllocLine = __LINE__;
-    mComponents = NULL;
-    mComponentCount = 0;
+    mFields = NULL;
+    mFieldCount = 0;
 }
 
-Element::Element(Context *rsc, uint32_t count) : ObjectBase(rsc)
-{
-    mAllocFile = __FILE__;
-    mAllocLine = __LINE__;
-    mComponents = new ObjectBaseRef<Component> [count];
-    mComponentCount = count;
-}
 
 Element::~Element()
 {
@@ -45,11 +42,11 @@
 
 void Element::clear()
 {
-    delete [] mComponents;
-    mComponents = NULL;
-    mComponentCount = 0;
+    delete [] mFields;
+    mFields = NULL;
+    mFieldCount = 0;
 }
-
+/*
 void Element::setComponent(uint32_t idx, Component *c)
 {
     rsAssert(!mComponents[idx].get());
@@ -59,22 +56,26 @@
 // Fixme: This should probably not be here
     c->incUserRef();
 }
-
+*/
 
 size_t Element::getSizeBits() const
 {
+    if (!mFieldCount) {
+        return mBits;
+    }
+
     size_t total = 0;
-    for (size_t ct=0; ct < mComponentCount; ct++) {
-        total += mComponents[ct]->getBits();
+    for (size_t ct=0; ct < mFieldCount; ct++) {
+        total += mFields[ct].e->mBits;
     }
     return total;
 }
 
-size_t Element::getComponentOffsetBits(uint32_t componentNumber) const
+size_t Element::getFieldOffsetBits(uint32_t componentNumber) const
 {
     size_t offset = 0;
     for (uint32_t ct = 0; ct < componentNumber; ct++) {
-        offset += mComponents[ct]->getBits();
+        offset += mFields[ct].e->mBits;
     }
     return offset;
 }
@@ -83,21 +84,54 @@
 {
     int bits[4];
 
-    if (mComponentCount > 4) {
+    if (!mFieldCount) {
+        switch (mType) {
+        case RS_TYPE_FLOAT:
+            if (mBits == 32) {
+                return GL_FLOAT;
+            }
+            return 0;
+        case RS_TYPE_SIGNED:
+            switch (mBits) {
+            case 8:
+                return GL_BYTE;
+            case 16:
+                return GL_SHORT;
+            //case 32:
+                //return GL_INT;
+            }
+            return 0;
+        case RS_TYPE_UNSIGNED:
+            switch (mBits) {
+            case 8:
+                return GL_UNSIGNED_BYTE;
+            case 16:
+                return GL_UNSIGNED_SHORT;
+            //case 32:
+                //return GL_UNSIGNED_INT;
+            }
+            return 0;
+        }
+    }
+
+    if (mFieldCount > 4) {
         return 0;
     }
 
-    for (uint32_t ct=0; ct < mComponentCount; ct++) {
-        bits[ct] = mComponents[ct]->getBits();
-        if (mComponents[ct]->getType() != Component::UNSIGNED) {
+    for (uint32_t ct=0; ct < mFieldCount; ct++) {
+        bits[ct] = mFields[ct].e->mBits;
+        if (mFields[ct].e->mFieldCount) {
             return 0;
         }
-        if (!mComponents[ct]->getIsNormalized()) {
+        if (mFields[ct].e->mType != RS_TYPE_UNSIGNED) {
+            return 0;
+        }
+        if (!mFields[ct].e->mIsNormalized) {
             return 0;
         }
     }
 
-    switch(mComponentCount) {
+    switch(mFieldCount) {
     case 1:
         if (bits[0] == 8) {
             return GL_UNSIGNED_BYTE;
@@ -146,33 +180,34 @@
 
 uint32_t Element::getGLFormat() const
 {
-    switch(mComponentCount) {
-    case 1:
-        if (mComponents[0]->getKind() == Component::ALPHA) {
+    if (!mFieldCount) {
+        if (mKind == RS_KIND_ALPHA) {
             return GL_ALPHA;
         }
-        if (mComponents[0]->getKind() == Component::LUMINANCE) {
+        if (mKind == RS_KIND_LUMINANCE) {
             return GL_LUMINANCE;
         }
-        break;
+    }
+
+    switch(mFieldCount) {
     case 2:
-        if ((mComponents[0]->getKind() == Component::LUMINANCE) &&
-            (mComponents[1]->getKind() == Component::ALPHA)) {
+        if ((mFields[0].e->mKind == RS_KIND_LUMINANCE) &&
+            (mFields[1].e->mKind == RS_KIND_ALPHA)) {
             return GL_LUMINANCE_ALPHA;
         }
         break;
     case 3:
-        if ((mComponents[0]->getKind() == Component::RED) &&
-            (mComponents[1]->getKind() == Component::GREEN) &&
-            (mComponents[2]->getKind() == Component::BLUE)) {
+        if ((mFields[0].e->mKind == RS_KIND_RED) &&
+            (mFields[1].e->mKind == RS_KIND_GREEN) &&
+            (mFields[2].e->mKind == RS_KIND_BLUE)) {
             return GL_RGB;
         }
         break;
     case 4:
-        if ((mComponents[0]->getKind() == Component::RED) &&
-            (mComponents[1]->getKind() == Component::GREEN) &&
-            (mComponents[2]->getKind() == Component::BLUE) &&
-            (mComponents[3]->getKind() == Component::ALPHA)) {
+        if ((mFields[0].e->mKind == RS_KIND_RED) &&
+            (mFields[1].e->mKind == RS_KIND_GREEN) &&
+            (mFields[2].e->mKind == RS_KIND_BLUE) &&
+            (mFields[3].e->mKind == RS_KIND_ALPHA)) {
             return GL_RGBA;
         }
         break;
@@ -180,18 +215,64 @@
     return 0;
 }
 
+const char * Element::getCType() const
+{
+    switch(mType) {
+    case RS_TYPE_FLOAT:
+        return "float";
+    case RS_TYPE_SIGNED:
+    case RS_TYPE_UNSIGNED:
+        switch(mBits) {
+        case 32:
+            return "int";
+        case 16:
+            return "short";
+        case 8:
+            return "char";
+        }
+        break;
+    }
+    return NULL;
+}
 
 void Element::dumpLOGV(const char *prefix) const
 {
     ObjectBase::dumpLOGV(prefix);
-    LOGV("%s   Element: components %i,  size %i", prefix, mComponentCount, getSizeBytes());
-    for (uint32_t ct = 0; ct < mComponentCount; ct++) {
+    LOGV("%s   Element: components %i,  size %i", prefix, mFieldCount, mBits);
+    for (uint32_t ct = 0; ct < mFieldCount; ct++) {
         char buf[1024];
         sprintf(buf, "%s component %i: ", prefix, ct);
-        mComponents[ct]->dumpLOGV(buf);
+        //mComponents[ct]->dumpLOGV(buf);
     }
 }
 
+Element * Element::create(Context *rsc, RsDataKind dk, RsDataType dt,
+                          bool isNorm, size_t bits)
+{
+    Element *e = new Element(rsc);
+    e->mKind = dk;
+    e->mType = dt;
+    e->mIsNormalized = isNorm;
+    e->mBits = bits;
+    return e;
+}
+
+Element * Element::create(Context *rsc, Element **ein, const char **nin,
+                          const size_t * lengths, size_t count)
+{
+    Element *e = new Element(rsc);
+    e->mFields = new ElementField_t [count];
+    e->mFieldCount = count;
+
+    for (size_t ct=0; ct < count; ct++) {
+        e->mFields[ct].e.set(ein[ct]);
+        e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
+    }
+
+    return e;
+}
+
+
 ElementState::ElementState()
 {
 }
@@ -200,6 +281,7 @@
 {
 }
 
+
 /////////////////////////////////////////
 //
 
@@ -208,7 +290,10 @@
 
 void rsi_ElementBegin(Context *rsc)
 {
-    rsc->mStateElement.mComponentBuildList.clear();
+    ElementState * sec = &rsc->mStateElement;
+
+    sec->mBuildList.clear();
+    sec->mNames.clear();
 }
 
 void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits, const char *name)
@@ -217,28 +302,47 @@
 
     rsAssert(bits > 0);
 
-    Component *c = new Component(rsc,
-                                 static_cast<Component::DataKind>(dk),
-                                 static_cast<Component::DataType>(dt),
-                                 isNormalized,
-                                 bits,
-                                 name);
-    sec->mComponentBuildList.add(c);
+    Element *c = Element::create(rsc, dk, dt, isNormalized, bits);
+    sec->mBuildList.add(c);
+    if (name)
+        sec->mNames.add(String8(name));
+    else
+        sec->mNames.add(String8(""));
 }
 
 RsElement rsi_ElementCreate(Context *rsc)
 {
     ElementState * sec = &rsc->mStateElement;
-    Element *se = new Element(rsc, sec->mComponentBuildList.size());
 
-    rsAssert(se->getComponentCount() > 0);
+    size_t count = sec->mBuildList.size();
+    rsAssert(count > 0);
 
-    for (size_t ct = 0; ct < se->getComponentCount(); ct++) {
-        se->setComponent(ct, sec->mComponentBuildList[ct]);
+    if (count == 1) {
+        Element *se = sec->mBuildList[0];
+        se->incUserRef();
+        sec->mBuildList.clear();
+        sec->mNames.clear();
+        return se;
     }
 
-    rsc->mStateElement.mComponentBuildList.clear();
+    Element ** tmpElements = (Element **)calloc(count, sizeof(Element *));
+    const char ** tmpNames = (const char **)calloc(count, sizeof(char *));
+    size_t * tmpLengths = (size_t *)calloc(count, sizeof(size_t));
+
+
+    for (size_t ct = 0; ct < count; ct++) {
+        tmpElements[ct] = sec->mBuildList[ct];
+        tmpNames[ct] = sec->mNames[ct].string();
+        tmpLengths[ct] = sec->mNames[ct].length();
+    }
+    Element *se = Element::create(rsc, tmpElements, tmpNames, tmpLengths, count);
+
+    sec->mBuildList.clear();
+    sec->mNames.clear();
     se->incUserRef();
+    free(tmpElements);
+    free(tmpNames);
+    free(tmpLengths);
     return se;
 }
 
diff --git a/rsElement.h b/rsElement.h
index b41c552..43e2820 100644
--- a/rsElement.h
+++ b/rsElement.h
@@ -17,7 +17,9 @@
 #ifndef ANDROID_STRUCTURED_ELEMENT_H
 #define ANDROID_STRUCTURED_ELEMENT_H
 
-#include "rsComponent.h"
+//#include "rsComponent.h"
+#include "rsUtils.h"
+#include "rsObjectBase.h"
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -28,11 +30,10 @@
 class Element : public ObjectBase
 {
 public:
-    Element(Context *, uint32_t count);
     ~Element();
 
 
-    void setComponent(uint32_t idx, Component *c);
+    //void setComponent(uint32_t idx, Component *c);
 
     uint32_t getGLType() const;
     uint32_t getGLFormat() const;
@@ -43,26 +44,50 @@
         return (getSizeBits() + 7) >> 3;
     }
 
-    size_t getComponentOffsetBits(uint32_t componentNumber) const;
-    size_t getComponentOffsetBytes(uint32_t componentNumber) const {
-        return (getComponentOffsetBits(componentNumber) + 7) >> 3;
+    size_t getFieldOffsetBits(uint32_t componentNumber) const;
+    size_t getFieldOffsetBytes(uint32_t componentNumber) const {
+        return (getFieldOffsetBits(componentNumber) + 7) >> 3;
     }
 
-    uint32_t getComponentCount() const {return mComponentCount;}
-    Component * getComponent(uint32_t idx) const {return mComponents[idx].get();}
+    uint32_t getFieldCount() const {return mFieldCount;}
+    const Element * getField(uint32_t idx) const {return mFields[idx].e.get();}
+    const char * getFieldName(uint32_t idx) const {return mFields[idx].name.string();}
 
+    RsDataType getType() const {return mType;}
+    bool getIsNormalized() const {return mIsNormalized;}
+    RsDataKind getKind() const {return mKind;}
+    uint32_t getBits() const {return mBits;}
+    //uint32_t getGLType() const;
+    const char * getCType() const;
 
     void dumpLOGV(const char *prefix) const;
 
+
+    static Element * create(Context *rsc, RsDataKind dk, RsDataType dt,
+                            bool isNorm, size_t bits);
+    static Element * create(Context *rsc, Element **, const char **,
+                            const size_t * lengths, size_t count);
+
 protected:
     // deallocate any components that are part of this element.
     void clear();
 
-    size_t mComponentCount;
-    ObjectBaseRef<Component> * mComponents;
-    //uint32_t *mOffsetTable;
+    typedef struct {
+        String8 name;
+        ObjectBaseRef<Element> e;
+    } ElementField_t;
+    ElementField_t *mFields;
+    size_t mFieldCount;
+
 
     Element(Context *);
+
+
+    RsDataType mType;
+    bool mIsNormalized;
+    RsDataKind mKind;
+    uint32_t mBits;
+    //String8 mName;
 };
 
 
@@ -71,7 +96,8 @@
     ElementState();
     ~ElementState();
 
-    Vector<Component *> mComponentBuildList;
+    Vector<Element *> mBuildList;
+    Vector<String8> mNames;
 };
 
 
diff --git a/rsProgram.cpp b/rsProgram.cpp
index db40f16..ba27fd4 100644
--- a/rsProgram.cpp
+++ b/rsProgram.cpp
@@ -24,7 +24,7 @@
 using namespace android::renderscript;
 
 
-Program::Program(Context *rsc, Element *in, Element *out) : ObjectBase(rsc)
+Program::Program(Context *rsc) : ObjectBase(rsc)
 {
     mAllocFile = __FILE__;
     mAllocLine = __LINE__;
@@ -33,13 +33,72 @@
     mAttribCount = 0;
     mUniformCount = 0;
 
-    mElementIn.set(in);
-    mElementOut.set(out);
+    mInputElements = NULL;
+    mOutputElements = NULL;
+    mConstantTypes = NULL;
+    mInputCount = 0;
+    mOutputCount = 0;
+    mConstantCount = 0;
+}
+
+Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
+                 const uint32_t * params, uint32_t paramLength) :
+    ObjectBase(rsc)
+{
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
+    mDirty = true;
+    mShaderID = 0;
+    mAttribCount = 0;
+    mUniformCount = 0;
+
+    mInputCount = 0;
+    mOutputCount = 0;
+    mConstantCount = 0;
+
+    for (uint32_t ct=0; ct < paramLength; ct+=2) {
+        if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
+            mInputCount++;
+        }
+        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
+            mOutputCount++;
+        }
+        if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
+            mConstantCount++;
+        }
+    }
+
+    mInputElements = new ObjectBaseRef<Element>[mInputCount];
+    mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
+    mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
+
+    uint32_t input = 0;
+    uint32_t output = 0;
+    uint32_t constant = 0;
+    for (uint32_t ct=0; ct < paramLength; ct+=2) {
+        if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
+            mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
+        }
+        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
+            mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1]));
+        }
+        if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
+            mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
+        }
+    }
+    mUserShader.setTo(shaderText, shaderLength);
 }
 
 Program::~Program()
 {
     bindAllocation(NULL);
+
+    delete[] mInputElements;
+    delete[] mOutputElements;
+    delete[] mConstantTypes;
+    mInputCount = 0;
+    mOutputCount = 0;
+    mConstantCount = 0;
 }
 
 
@@ -102,3 +161,19 @@
     mUserShader.setTo(txt, len);
 }
 
+
+
+namespace android {
+namespace renderscript {
+
+
+void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants)
+{
+    Program *p = static_cast<Program *>(vp);
+    p->bindAllocation(static_cast<Allocation *>(constants));
+}
+
+
+}
+}
+
diff --git a/rsProgram.h b/rsProgram.h
index abd461b..01b4c88 100644
--- a/rsProgram.h
+++ b/rsProgram.h
@@ -33,7 +33,9 @@
     const static uint32_t MAX_ATTRIBS = 8;
     const static uint32_t MAX_UNIFORMS = 16;
 
-    Program(Context *, Element *in, Element *out);
+    Program(Context *);
+    Program(Context *, const char * shaderText, uint32_t shaderLength,
+                       const uint32_t * params, uint32_t paramLength);
     virtual ~Program();
 
     void bindAllocation(Allocation *);
@@ -50,8 +52,12 @@
 protected:
     // Components not listed in "in" will be passed though
     // unless overwritten by components in out.
-    ObjectBaseRef<Element> mElementIn;
-    ObjectBaseRef<Element> mElementOut;
+    ObjectBaseRef<Element> *mInputElements;
+    ObjectBaseRef<Element> *mOutputElements;
+    ObjectBaseRef<Type> *mConstantTypes;
+    uint32_t mInputCount;
+    uint32_t mOutputCount;
+    uint32_t mConstantCount;
 
     ObjectBaseRef<Allocation> mConstants;
 
diff --git a/rsProgramFragment.cpp b/rsProgramFragment.cpp
index 1225ff3..3ddaa37 100644
--- a/rsProgramFragment.cpp
+++ b/rsProgramFragment.cpp
@@ -27,7 +27,7 @@
 
 
 ProgramFragment::ProgramFragment(Context *rsc, Element *in, Element *out, bool pointSpriteEnable) :
-    Program(rsc, in, out)
+    Program(rsc)
 {
     mAllocFile = __FILE__;
     mAllocLine = __LINE__;
@@ -174,7 +174,6 @@
 
 
     mShader.append("void main() {\n");
-    //mShader.append("  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n");
     mShader.append("  vec4 col = varColor;\n");
 
     if (mTextureEnableMask) {
diff --git a/rsProgramFragmentStore.cpp b/rsProgramFragmentStore.cpp
index d7d5c75..8a2157f 100644
--- a/rsProgramFragmentStore.cpp
+++ b/rsProgramFragmentStore.cpp
@@ -24,8 +24,8 @@
 using namespace android::renderscript;
 
 
-ProgramFragmentStore::ProgramFragmentStore(Context *rsc, Element *in, Element *out) :
-    Program(rsc, in, out)
+ProgramFragmentStore::ProgramFragmentStore(Context *rsc) :
+    Program(rsc)
 {
     mAllocFile = __FILE__;
     mAllocLine = __LINE__;
@@ -249,7 +249,7 @@
 
 void ProgramFragmentStoreState::init(Context *rsc, int32_t w, int32_t h)
 {
-    ProgramFragmentStore *pfs = new ProgramFragmentStore(rsc, NULL, NULL);
+    ProgramFragmentStore *pfs = new ProgramFragmentStore(rsc);
     mDefault.set(pfs);
 }
 
@@ -266,7 +266,7 @@
 void rsi_ProgramFragmentStoreBegin(Context * rsc, RsElement in, RsElement out)
 {
     delete rsc->mStateFragmentStore.mPFS;
-    rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore(rsc, (Element *)in, (Element *)out);
+    rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore(rsc);
 
 }
 
diff --git a/rsProgramFragmentStore.h b/rsProgramFragmentStore.h
index 3f9d8c9..3412c99 100644
--- a/rsProgramFragmentStore.h
+++ b/rsProgramFragmentStore.h
@@ -28,7 +28,7 @@
 class ProgramFragmentStore : public Program
 {
 public:
-    ProgramFragmentStore(Context *, Element *in, Element *out);
+    ProgramFragmentStore(Context *);
     virtual ~ProgramFragmentStore();
 
     virtual void setupGL(const Context *, ProgramFragmentStoreState *);
diff --git a/rsProgramRaster.cpp b/rsProgramRaster.cpp
index f0039f7..13887d1 100644
--- a/rsProgramRaster.cpp
+++ b/rsProgramRaster.cpp
@@ -25,12 +25,10 @@
 
 
 ProgramRaster::ProgramRaster(Context *rsc,
-                             Element *in,
-                             Element *out,
                              bool pointSmooth,
                              bool lineSmooth,
                              bool pointSprite) :
-    Program(rsc, in, out)
+    Program(rsc)
 {
     mAllocFile = __FILE__;
     mAllocLine = __LINE__;
@@ -106,7 +104,7 @@
 
 void ProgramRasterState::init(Context *rsc, int32_t w, int32_t h)
 {
-    ProgramRaster *pr = new ProgramRaster(rsc, NULL, NULL, false, false, false);
+    ProgramRaster *pr = new ProgramRaster(rsc, false, false, false);
     mDefault.set(pr);
 }
 
@@ -126,8 +124,6 @@
                                       bool pointSprite)
 {
     ProgramRaster *pr = new ProgramRaster(rsc,
-                                          static_cast<Element *>(in),
-                                          static_cast<Element *>(out),
                                           pointSmooth,
                                           lineSmooth,
                                           pointSprite);
diff --git a/rsProgramRaster.h b/rsProgramRaster.h
index 4efecb4..c3a9c90 100644
--- a/rsProgramRaster.h
+++ b/rsProgramRaster.h
@@ -29,8 +29,6 @@
 {
 public:
     ProgramRaster(Context *rsc,
-                  Element *in,
-                  Element *out,
                   bool pointSmooth,
                   bool lineSmooth,
                   bool pointSprite);
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
index 482739c..9a2edfc 100644
--- a/rsProgramVertex.cpp
+++ b/rsProgramVertex.cpp
@@ -26,13 +26,27 @@
 using namespace android::renderscript;
 
 
-ProgramVertex::ProgramVertex(Context *rsc, Element *in, Element *out) :
-    Program(rsc, in, out)
+ProgramVertex::ProgramVertex(Context *rsc, bool texMat) :
+    Program(rsc)
+{
+    mAllocFile = __FILE__;
+    mAllocLine = __LINE__;
+    mTextureMatrixEnable = texMat;
+    mLightCount = 0;
+    init(rsc);
+}
+
+ProgramVertex::ProgramVertex(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__;
     mTextureMatrixEnable = false;
     mLightCount = 0;
+
+    init(rsc);
 }
 
 ProgramVertex::~ProgramVertex()
@@ -217,16 +231,15 @@
     createShader();
 }
 
+
 ///////////////////////////////////////////////////////////////////////
 
 ProgramVertexState::ProgramVertexState()
 {
-    mPV = NULL;
 }
 
 ProgramVertexState::~ProgramVertexState()
 {
-    delete mPV;
 }
 
 void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h)
@@ -239,7 +252,7 @@
     rsi_TypeAdd(rsc, RS_DIMENSION_X, 48);
     mAllocType.set((Type *)rsi_TypeCreate(rsc));
 
-    ProgramVertex *pv = new ProgramVertex(rsc, NULL, NULL);
+    ProgramVertex *pv = new ProgramVertex(rsc, false);
     Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get());
     mDefaultAlloc.set(alloc);
     mDefault.set(pv);
@@ -265,48 +278,27 @@
     mDefault.clear();
     mAllocType.clear();
     mLast.clear();
-    delete mPV;
-    mPV = NULL;
 }
 
 
 namespace android {
 namespace renderscript {
 
-void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out)
-{
-    delete rsc->mStateVertex.mPV;
-    rsc->mStateVertex.mPV = new ProgramVertex(rsc, (Element *)in, (Element *)out);
-}
 
-RsProgramVertex rsi_ProgramVertexCreate(Context *rsc)
+RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, bool texMat)
 {
-    ProgramVertex *pv = rsc->mStateVertex.mPV;
+    ProgramVertex *pv = new ProgramVertex(rsc, texMat);
     pv->incUserRef();
-    pv->init(rsc);
-    rsc->mStateVertex.mPV = 0;
     return pv;
 }
 
-void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, RsAllocation constants)
+RsProgramVertex rsi_ProgramVertexCreate2(Context *rsc, const char * shaderText,
+                             uint32_t shaderLength, const uint32_t * params,
+                             uint32_t paramLength)
 {
-    ProgramVertex *pv = static_cast<ProgramVertex *>(vpgm);
-    pv->bindAllocation(static_cast<Allocation *>(constants));
-}
-
-void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable)
-{
-    rsc->mStateVertex.mPV->setTextureMatrixEnable(enable);
-}
-
-void rsi_ProgramVertexSetShader(Context *rsc, const char *txt, uint32_t len)
-{
-    rsc->mStateVertex.mPV->setShader(txt, len);
-}
-
-void rsi_ProgramVertexAddLight(Context *rsc, RsLight light)
-{
-    rsc->mStateVertex.mPV->addLight(static_cast<const Light *>(light));
+    ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength);
+    pv->incUserRef();
+    return pv;
 }
 
 
diff --git a/rsProgramVertex.h b/rsProgramVertex.h
index aa626da..b3115a3 100644
--- a/rsProgramVertex.h
+++ b/rsProgramVertex.h
@@ -30,7 +30,9 @@
 public:
     const static uint32_t MAX_LIGHTS = 8;
 
-    ProgramVertex(Context *, Element *in, Element *out);
+    ProgramVertex(Context *,const char * shaderText, uint32_t shaderLength,
+                  const uint32_t * params, uint32_t paramLength);
+    ProgramVertex(Context *, bool texMat);
     virtual ~ProgramVertex();
 
     virtual void setupGL(const Context *rsc, ProgramVertexState *state);
@@ -76,10 +78,6 @@
 
     ObjectBaseRef<Type> mAllocType;
 
-    ProgramVertex *mPV;
-
-    //ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE];
-
 
 };
 
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index f11b862..3fa9813 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -270,12 +270,12 @@
 static void appendElementBody(String8 *s, const Element *e)
 {
     s->append(" {\n");
-    for (size_t ct2=0; ct2 < e->getComponentCount(); ct2++) {
-        const Component *c = e->getComponent(ct2);
+    for (size_t ct2=0; ct2 < e->getFieldCount(); ct2++) {
+        const Element *c = e->getField(ct2);
         s->append("    ");
         s->append(c->getCType());
         s->append(" ");
-        s->append(c->getComponentName());
+        s->append(e->getFieldName(ct2));
         s->append(";\n");
     }
     s->append("}");
@@ -321,7 +321,7 @@
             continue;
         }
         const Element *e = t->getElement();
-        if (e->getName() && (e->getComponentCount() > 1)) {
+        if (e->getName() && (e->getFieldCount() > 1)) {
             String8 s("struct struct_");
             s.append(e->getName());
             appendElementBody(&s, e);
@@ -338,12 +338,12 @@
         }
 
         if (t->getName()) {
-            for (size_t ct2=0; ct2 < e->getComponentCount(); ct2++) {
-                const Component *c = e->getComponent(ct2);
+            for (size_t ct2=0; ct2 < e->getFieldCount(); ct2++) {
+                const Element *c = e->getField(ct2);
                 tmp.setTo("#define OFFSETOF_");
                 tmp.append(t->getName());
                 tmp.append("_");
-                tmp.append(c->getComponentName());
+                tmp.append(e->getFieldName(ct2));
                 sprintf(buf, " %i\n", ct2);
                 tmp.append(buf);
                 if (rsc->props.mLogScripts) {
@@ -355,7 +355,7 @@
 
         if (mSlotNames[ct].length() > 0) {
             String8 s;
-            if (e->getComponentCount() > 1) {
+            if (e->getFieldCount() > 1) {
                 if (e->getName()) {
                     // Use the named struct
                     s.setTo(e->getName());
@@ -373,7 +373,7 @@
                 }
             } else {
                 // Just make an array
-                s.setTo(e->getComponent(0)->getCType());
+                s.setTo(e->getField(0)->getCType());
                 s.append("_t *");
             }
             s.append(mSlotNames[ct]);
diff --git a/rsType.cpp b/rsType.cpp
index 044ec46..5eac0b5 100644
--- a/rsType.cpp
+++ b/rsType.cpp
@@ -136,49 +136,49 @@
     uint32_t texNum = 0;
     memset(&mGL, 0, sizeof(mGL));
 
-    for (uint32_t ct=0; ct < getElement()->getComponentCount(); ct++) {
-        const Component *c = getElement()->getComponent(ct);
+    for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
+        const Element *c = getElement()->getField(ct);
 
         switch(c->getKind()) {
-        case Component::X:
+        case RS_KIND_X:
             rsAssert(mGL.mVtx.size == 0);
             mGL.mVtx.size = 1;
-            mGL.mVtx.offset = mElement->getComponentOffsetBytes(ct);
+            mGL.mVtx.offset = mElement->getFieldOffsetBytes(ct);
             mGL.mVtx.type = c->getGLType();
             break;
-        case Component::Y:
+        case RS_KIND_Y:
             rsAssert(mGL.mVtx.size == 1);
             rsAssert(mGL.mVtx.type == c->getGLType());
             mGL.mVtx.size = 2;
             break;
-        case Component::Z:
+        case RS_KIND_Z:
             rsAssert(mGL.mVtx.size == 2);
             rsAssert(mGL.mVtx.type == c->getGLType());
             mGL.mVtx.size = 3;
             break;
-        case Component::W:
+        case RS_KIND_W:
             rsAssert(mGL.mVtx.size == 4);
             rsAssert(mGL.mVtx.type == c->getGLType());
             mGL.mVtx.size = 4;
         break;
 
-        case Component::RED:
+        case RS_KIND_RED:
             rsAssert(mGL.mColor.size == 0);
             mGL.mColor.size = 1;
-            mGL.mColor.offset = mElement->getComponentOffsetBytes(ct);
+            mGL.mColor.offset = mElement->getFieldOffsetBytes(ct);
             mGL.mColor.type = c->getGLType();
             break;
-        case Component::GREEN:
+        case RS_KIND_GREEN:
             rsAssert(mGL.mColor.size == 1);
             rsAssert(mGL.mColor.type == c->getGLType());
             mGL.mColor.size = 2;
             break;
-        case Component::BLUE:
+        case RS_KIND_BLUE:
             rsAssert(mGL.mColor.size == 2);
             rsAssert(mGL.mColor.type == c->getGLType());
             mGL.mColor.size = 3;
             break;
-        case Component::ALPHA:
+        case RS_KIND_ALPHA:
             // Can be RGBA or A at this point
             if (mGL.mColor.size > 0) {
                 rsAssert(mGL.mColor.size == 3);
@@ -186,56 +186,56 @@
                 mGL.mColor.size = 4;
             } else {
                 mGL.mColor.size = 1;
-                mGL.mColor.offset = mElement->getComponentOffsetBytes(ct);
+                mGL.mColor.offset = mElement->getFieldOffsetBytes(ct);
                 mGL.mColor.type = c->getGLType();
             }
         break;
 
-        case Component::NX:
+        case RS_KIND_NX:
             rsAssert(mGL.mNorm.size == 0);
             mGL.mNorm.size = 1;
-            mGL.mNorm.offset = mElement->getComponentOffsetBytes(ct);
+            mGL.mNorm.offset = mElement->getFieldOffsetBytes(ct);
             mGL.mNorm.type = c->getGLType();
         break;
-        case Component::NY:
+        case RS_KIND_NY:
             rsAssert(mGL.mNorm.size == 1);
             rsAssert(mGL.mNorm.type == c->getGLType());
             mGL.mNorm.size = 2;
         break;
-        case Component::NZ:
+        case RS_KIND_NZ:
             rsAssert(mGL.mNorm.size == 2);
             rsAssert(mGL.mNorm.type == c->getGLType());
             mGL.mNorm.size = 3;
         break;
 
-        case Component::S:
+        case RS_KIND_S:
             if (mGL.mTex[texNum].size) {
                 texNum++;
             }
             mGL.mTex[texNum].size = 1;
-            mGL.mTex[texNum].offset = mElement->getComponentOffsetBytes(ct);
+            mGL.mTex[texNum].offset = mElement->getFieldOffsetBytes(ct);
             mGL.mTex[texNum].type = c->getGLType();
         break;
-        case Component::T:
+        case RS_KIND_T:
             rsAssert(mGL.mTex[texNum].size == 1);
             rsAssert(mGL.mTex[texNum].type == c->getGLType());
             mGL.mTex[texNum].size = 2;
         break;
-        case Component::R:
+        case RS_KIND_R:
             rsAssert(mGL.mTex[texNum].size == 2);
             rsAssert(mGL.mTex[texNum].type == c->getGLType());
             mGL.mTex[texNum].size = 3;
         break;
-        case Component::Q:
+        case RS_KIND_Q:
             rsAssert(mGL.mTex[texNum].size == 3);
             rsAssert(mGL.mTex[texNum].type == c->getGLType());
             mGL.mTex[texNum].size = 4;
         break;
 
-        case Component::POINT_SIZE:
+        case RS_KIND_POINT_SIZE:
             rsAssert(!mGL.mPointSize.size);
             mGL.mPointSize.size = 1;
-            mGL.mPointSize.offset = mElement->getComponentOffsetBytes(ct);
+            mGL.mPointSize.offset = mElement->getFieldOffsetBytes(ct);
             mGL.mPointSize.type = c->getGLType();
         break;