Element restructuring.  Add support for new basic Element types including the RS objects and vectors(2-4).  In theory this paves the way for maintaining type info for RS objects, passing elements for GLSL uiforms/attribs/varyings, and supporting nested structures.

This will break some apps, checkings for other projects will follow to unbreak them.
diff --git a/Android.mk b/Android.mk
index 111bdd4..3080ab0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -76,6 +76,7 @@
 LOCAL_SRC_FILES:= \
 	rsAdapter.cpp \
 	rsAllocation.cpp \
+	rsComponent.cpp \
 	rsContext.cpp \
 	rsDevice.cpp \
 	rsElement.cpp \
diff --git a/RenderScript.h b/RenderScript.h
index d10eeda..bb2c06a 100644
--- a/RenderScript.h
+++ b/RenderScript.h
@@ -66,32 +66,50 @@
 #define RS_MAX_TEXTURE 2
 
 enum RsDataType {
-    RS_TYPE_FLOAT,
-    RS_TYPE_UNSIGNED,
-    RS_TYPE_SIGNED
+    RS_TYPE_NONE,
+    RS_TYPE_FLOAT_16,
+    RS_TYPE_FLOAT_32,
+    RS_TYPE_FLOAT_64,
+    RS_TYPE_SIGNED_8,
+    RS_TYPE_SIGNED_16,
+    RS_TYPE_SIGNED_32,
+    RS_TYPE_SIGNED_64,
+    RS_TYPE_UNSIGNED_8,
+    RS_TYPE_UNSIGNED_16,
+    RS_TYPE_UNSIGNED_32,
+    RS_TYPE_UNSIGNED_64,
+
+    RS_TYPE_UNSIGNED_5_6_5,
+    RS_TYPE_UNSIGNED_5_5_5_1,
+    RS_TYPE_UNSIGNED_4_4_4_4,
+
+    RS_TYPE_ELEMENT,
+    RS_TYPE_TYPE,
+    RS_TYPE_ALLOCATION,
+    RS_TYPE_SAMPLER,
+    RS_TYPE_SCRIPT,
+    RS_TYPE_MESH,
+    RS_TYPE_PROGRAM_FRAGMENT,
+    RS_TYPE_PROGRAM_VERTEX,
+    RS_TYPE_PROGRAM_RASTER,
+    RS_TYPE_PROGRAM_STORE
 };
 
 enum RsDataKind {
     RS_KIND_USER,
-    RS_KIND_RED,
-    RS_KIND_GREEN,
-    RS_KIND_BLUE,
-    RS_KIND_ALPHA,
-    RS_KIND_LUMINANCE,
-    RS_KIND_INTENSITY,
-    RS_KIND_X,
-    RS_KIND_Y,
-    RS_KIND_Z,
-    RS_KIND_W,
-    RS_KIND_S,
-    RS_KIND_T,
-    RS_KIND_Q,
-    RS_KIND_R,
-    RS_KIND_NX,
-    RS_KIND_NY,
-    RS_KIND_NZ,
+    RS_KIND_COLOR,
+    RS_KIND_POSITION,
+    RS_KIND_TEXTURE,
+    RS_KIND_NORMAL,
     RS_KIND_INDEX,
-    RS_KIND_POINT_SIZE
+    RS_KIND_POINT_SIZE,
+
+    RS_KIND_PIXEL_L,
+    RS_KIND_PIXEL_A,
+    RS_KIND_PIXEL_LA,
+    RS_KIND_PIXEL_RGB,
+    RS_KIND_PIXEL_RGBA,
+
 };
 
 enum RsSamplerParam {
diff --git a/java/Film/src/com/android/film/FilmRS.java b/java/Film/src/com/android/film/FilmRS.java
index dccc1d2..fcf487c 100644
--- a/java/Film/src/com/android/film/FilmRS.java
+++ b/java/Film/src/com/android/film/FilmRS.java
@@ -152,10 +152,13 @@
         mBufferIDs = new int[13];
         mImages = new Allocation[13];
         mAllocIDs = Allocation.createSized(mRS,
-            Element.USER_F32(mRS), mBufferIDs.length);
+            Element.createUser(mRS, Element.DataType.FLOAT_32),
+            mBufferIDs.length);
 
-        Element ie = Element.RGB_565(mRS);
+        Element ie = Element.createPixel(mRS, Element.DataType.UNSIGNED_5_6_5, Element.DataKind.PIXEL_RGB);
+        android.util.Log.e("rs", "load 1");
         mImages[0] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p01, ie, true);
+        android.util.Log.e("rs", "load 2");
         mImages[1] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p02, ie, true);
         mImages[2] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p03, ie, true);
         mImages[3] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p04, ie, true);
@@ -195,7 +198,8 @@
     {
         mBufferState = new int[10];
         mAllocState = Allocation.createSized(mRS,
-            Element.USER_F32(mRS), mBufferState.length);
+            Element.createUser(mRS, Element.DataType.FLOAT_32),
+            mBufferState.length);
         mBufferState[STATE_LAST_FOCUS] = -1;
         mAllocState.data(mBufferState);
     }
@@ -238,12 +242,12 @@
 
 
         mAllocOffsets = Allocation.createSized(mRS,
-            Element.USER_I32(mRS), mFSM.mTriangleOffsets.length);
+            Element.createUser(mRS, Element.DataType.SIGNED_32), mFSM.mTriangleOffsets.length);
         mAllocOffsets.data(mFSM.mTriangleOffsets);
         mScriptStrip.bindAllocation(mAllocOffsets, 4);
 
         mAllocOffsetsTex = Allocation.createSized(mRS,
-            Element.USER_F32(mRS), mFSM.mTriangleOffsetsTex.length);
+            Element.createUser(mRS, Element.DataType.FLOAT_32), mFSM.mTriangleOffsetsTex.length);
         mAllocOffsetsTex.data(mFSM.mTriangleOffsetsTex);
         mScriptStrip.bindAllocation(mAllocOffsetsTex, 5);
 
diff --git a/java/Fountain/res/raw/fountain.c b/java/Fountain/res/raw/fountain.c
index f218f9b..73b819b 100644
--- a/java/Fountain/res/raw/fountain.c
+++ b/java/Fountain/res/raw/fountain.c
@@ -14,19 +14,17 @@
         float rMax = ((float)rate) * 0.005f;
         int x = Control->x;
         int y = Control->y;
-        char r = Control->r * 255.f;
-        char g = Control->g * 255.f;
-        char b = Control->b * 255.f;
+        int color = ((int)(Control->r * 255.f)) |
+                    ((int)(Control->g * 255.f)) << 8 |
+                    ((int)(Control->b * 255.f)) << 16 |
+                    (0xf0 << 24);
         struct point_s * np = &p[newPart];
 
         while (rate--) {
-            vec2Rand((float *)np, rMax);
-            np->x = x;
-            np->y = y;
-            np->r = r;
-            np->g = g;
-            np->b = b;
-            np->a = 0xf0;
+            vec2Rand((float *)&np->delta.x, rMax);
+            np->position.x = x;
+            np->position.y = y;
+            np->color = color;
             newPart++;
             np++;
             if (newPart >= count) {
@@ -37,14 +35,14 @@
     }
 
     for (ct=0; ct < count; ct++) {
-        float dy = p->dy + 0.15f;
-        float posy = p->y + dy;
+        float dy = p->delta.y + 0.15f;
+        float posy = p->position.y + dy;
         if ((posy > height) && (dy > 0)) {
             dy *= -0.3f;
         }
-        p->dy = dy;
-        p->x += p->dx;
-        p->y = posy;
+        p->delta.y = dy;
+        p->position.x += p->delta.x;
+        p->position.y = posy;
         p++;
     }
 
diff --git a/java/Fountain/src/com/android/fountain/FountainRS.java b/java/Fountain/src/com/android/fountain/FountainRS.java
index f4f9b0c..71f95a7 100644
--- a/java/Fountain/src/com/android/fountain/FountainRS.java
+++ b/java/Fountain/src/com/android/fountain/FountainRS.java
@@ -79,10 +79,9 @@
         mIntAlloc.data(mSD);
 
         Element.Builder eb = new Element.Builder(mRS);
-        eb.addFloat(Element.DataKind.USER, "dx");
-        eb.addFloat(Element.DataKind.USER, "dy");
-        eb.addFloatXY("");
-        eb.addUNorm8RGBA("");
+        eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 2), "delta");
+        eb.add(Element.createAttrib(mRS, Element.DataType.FLOAT_32, Element.DataKind.POSITION, 2), "position");
+        eb.add(Element.createAttrib(mRS, Element.DataType.UNSIGNED_8, Element.DataKind.COLOR, 4), "color");
         Element primElement = eb.create();
 
 
diff --git a/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 334fd9c..0ca00b3 100644
--- a/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -62,7 +62,7 @@
 
         public float threshold;
     }
-    
+
     static class Pixel {
         public byte a;
         public byte r;
@@ -78,7 +78,7 @@
                         mParams.outWidth, mParams.outHeight);
                 mDisplayView.invalidate();
             }
-        };        
+        };
 
         @Override
         public void run() {
@@ -131,7 +131,7 @@
 
     public void surfaceDestroyed(SurfaceHolder holder) {
     }
-        
+
     private Script.Invokable createScript() {
         mRS = new RenderScript(false, false);
         mRS.mMessageCallback = new FilterCallback();
@@ -143,9 +143,11 @@
         final int pixelCount = mParams.inWidth * mParams.inHeight;
 
         mPixelType = Type.createFromClass(mRS, Pixel.class, 1, "Pixel");
-        mInPixelsAllocation = Allocation.createSized(mRS, Element.USER_I32(mRS),
+        mInPixelsAllocation = Allocation.createSized(mRS,
+                Element.createUser(mRS, Element.DataType.SIGNED_32),
                 pixelCount);
-        mOutPixelsAllocation = Allocation.createSized(mRS, Element.USER_I32(mRS),
+        mOutPixelsAllocation = Allocation.createSized(mRS,
+                Element.createUser(mRS, Element.DataType.SIGNED_32),
                 pixelCount);
 
         final int[] data = new int[pixelCount];
@@ -154,7 +156,7 @@
 
         mOutData = new int[pixelCount];
         mOutPixelsAllocation.data(mOutData);
-        
+
         ScriptC.Builder sb = new ScriptC.Builder(mRS);
         sb.setType(mParamsType, "Params", 0);
         sb.setType(mPixelType, "InPixel", 1);
diff --git a/rs.spec b/rs.spec
index df41568..d12431f 100644
--- a/rs.spec
+++ b/rs.spec
@@ -60,18 +60,19 @@
 	param void *obj
 	}
 
-ElementBegin {
-}
-
-ElementAdd {
-	param RsDataKind dataKind
-	param RsDataType dataType
-	param bool isNormalized
-	param size_t bits
-	param const char * name
+ElementCreate {
+	param RsDataType mType
+	param RsDataKind mKind
+	param bool mNormalized
+	param uint32_t mVectorSize
+	ret RsElement
 	}
 
-ElementCreate {
+ElementCreate2 {
+	param size_t count
+	param const RsElement * elements
+	param const char ** names
+	param const size_t * nameLengths
 	ret RsElement
 	}
 
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index 7f76390..19699dc 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -106,8 +106,8 @@
         return;
     }
 
-    GLenum type = mType->getElement()->getGLType();
-    GLenum format = mType->getElement()->getGLFormat();
+    GLenum type = mType->getElement()->getComponent().getGLType();
+    GLenum format = mType->getElement()->getComponent().getGLFormat();
 
     if (!type || !format) {
         return;
@@ -422,10 +422,10 @@
 
 static ElementConverter_t pickConverter(const Element *dst, const Element *src)
 {
-    GLenum srcGLType = src->getGLType();
-    GLenum srcGLFmt = src->getGLFormat();
-    GLenum dstGLType = dst->getGLType();
-    GLenum dstGLFmt = dst->getGLFormat();
+    GLenum srcGLType = src->getComponent().getGLType();
+    GLenum srcGLFmt = src->getComponent().getGLFormat();
+    GLenum dstGLType = dst->getComponent().getGLType();
+    GLenum dstGLFmt = dst->getComponent().getGLFormat();
 
     if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) {
         switch(dst->getSizeBytes()) {
diff --git a/rsComponent.cpp b/rsComponent.cpp
new file mode 100644
index 0000000..0574343
--- /dev/null
+++ b/rsComponent.cpp
@@ -0,0 +1,316 @@
+/*
+ * 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()
+{
+    set(RS_TYPE_NONE, RS_KIND_USER, false, 1);
+}
+
+Component::~Component()
+{
+}
+
+void Component::set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize)
+{
+    mType = dt;
+    mKind = dk;
+    mNormalized = norm;
+    mVectorSize = vecSize;
+    rsAssert(vecSize <= 4);
+
+    mBits = 0;
+    mTypeBits = 0;
+    mIsFloat = false;
+    mIsSigned = false;
+    mIsPixel = false;
+
+    switch(mKind) {
+    case RS_KIND_PIXEL_L:
+    case RS_KIND_PIXEL_A:
+        mIsPixel = true;
+        rsAssert(mVectorSize == 1);
+        rsAssert(mNormalized == true);
+        break;
+    case RS_KIND_PIXEL_LA:
+        mIsPixel = true;
+        rsAssert(mVectorSize == 2);
+        rsAssert(mNormalized == true);
+        break;
+    case RS_KIND_PIXEL_RGB:
+        mIsPixel = true;
+        rsAssert(mVectorSize == 3);
+        rsAssert(mNormalized == true);
+        break;
+    case RS_KIND_PIXEL_RGBA:
+        mIsPixel = true;
+        rsAssert(mVectorSize == 4);
+        rsAssert(mNormalized == true);
+        break;
+    default:
+        break;
+    }
+
+    switch(mType) {
+    case RS_TYPE_NONE:
+        return;
+    case RS_TYPE_UNSIGNED_5_6_5:
+        mVectorSize = 3;
+        mBits = 16;
+        mNormalized = true;
+        rsAssert(mKind == RS_KIND_PIXEL_RGB);
+        return;
+    case RS_TYPE_UNSIGNED_5_5_5_1:
+        mVectorSize = 4;
+        mBits = 16;
+        mNormalized = true;
+        rsAssert(mKind == RS_KIND_PIXEL_RGBA);
+        return;
+    case RS_TYPE_UNSIGNED_4_4_4_4:
+        mVectorSize = 4;
+        mBits = 16;
+        mNormalized = true;
+        rsAssert(mKind == RS_KIND_PIXEL_RGBA);
+        return;
+    case RS_TYPE_ELEMENT:
+    case RS_TYPE_TYPE:
+    case RS_TYPE_ALLOCATION:
+    case RS_TYPE_SAMPLER:
+    case RS_TYPE_SCRIPT:
+    case RS_TYPE_MESH:
+    case RS_TYPE_PROGRAM_FRAGMENT:
+    case RS_TYPE_PROGRAM_VERTEX:
+    case RS_TYPE_PROGRAM_RASTER:
+    case RS_TYPE_PROGRAM_STORE:
+        rsAssert(mVectorSize == 1);
+        rsAssert(mNormalized == false);
+        rsAssert(mKind == RS_KIND_USER);
+        mBits = 32;
+        mTypeBits = 32;
+        return;
+
+    case RS_TYPE_FLOAT_16:
+        mTypeBits = 16;
+        mIsFloat = true;
+        break;
+    case RS_TYPE_FLOAT_32:
+        mTypeBits = 32;
+        mIsFloat = true;
+        break;
+    case RS_TYPE_FLOAT_64:
+        mTypeBits = 64;
+        mIsFloat = true;
+        break;
+    case RS_TYPE_SIGNED_8:
+        mTypeBits = 8;
+        mIsSigned = true;
+        break;
+    case RS_TYPE_SIGNED_16:
+        mTypeBits = 16;
+        mIsSigned = true;
+        break;
+    case RS_TYPE_SIGNED_32:
+        mTypeBits = 32;
+        mIsSigned = true;
+        break;
+    case RS_TYPE_SIGNED_64:
+        mTypeBits = 64;
+        mIsSigned = true;
+        break;
+    case RS_TYPE_UNSIGNED_8:
+        mTypeBits = 8;
+        break;
+    case RS_TYPE_UNSIGNED_16:
+        mTypeBits = 16;
+        break;
+    case RS_TYPE_UNSIGNED_32:
+        mTypeBits = 32;
+        break;
+    case RS_TYPE_UNSIGNED_64:
+        mTypeBits = 64;
+        break;
+    }
+
+    mBits = mTypeBits * mVectorSize;
+}
+
+
+
+
+uint32_t Component::getGLType() const
+{
+    switch (mType) {
+    case RS_TYPE_UNSIGNED_5_6_5:    return GL_UNSIGNED_SHORT_5_6_5;
+    case RS_TYPE_UNSIGNED_5_5_5_1:  return GL_UNSIGNED_SHORT_5_5_5_1;
+    case RS_TYPE_UNSIGNED_4_4_4_4:  return GL_UNSIGNED_SHORT_4_4_4_4;
+
+    //case RS_TYPE_FLOAT_16:      return GL_HALF_FLOAT;
+    case RS_TYPE_FLOAT_32:      return GL_FLOAT;
+    case RS_TYPE_UNSIGNED_8:    return GL_UNSIGNED_BYTE;
+    case RS_TYPE_UNSIGNED_16:   return GL_UNSIGNED_SHORT;
+    case RS_TYPE_SIGNED_8:      return GL_BYTE;
+    case RS_TYPE_SIGNED_16:     return GL_SHORT;
+    default:    break;
+    }
+
+    return 0;
+}
+
+uint32_t Component::getGLFormat() const
+{
+    switch (mKind) {
+    case RS_KIND_PIXEL_L: return GL_LUMINANCE;
+    case RS_KIND_PIXEL_A: return GL_ALPHA;
+    case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
+    case RS_KIND_PIXEL_RGB: return GL_RGB;
+    case RS_KIND_PIXEL_RGBA: return GL_RGBA;
+    default: break;
+    }
+    return 0;
+}
+
+static const char * gCTypeStrings[] = {
+    0,
+    0,//"F16",
+    "float",
+    "double",
+    "char",
+    "short",
+    "int",
+    0,//"S64",
+    "char",//U8",
+    "short",//U16",
+    "int",//U32",
+    0,//"U64",
+    0,//"UP_565",
+    0,//"UP_5551",
+    0,//"UP_4444",
+    0,//"ELEMENT",
+    0,//"TYPE",
+    0,//"ALLOCATION",
+    0,//"SAMPLER",
+    0,//"SCRIPT",
+    0,//"MESH",
+    0,//"PROGRAM_FRAGMENT",
+    0,//"PROGRAM_VERTEX",
+    0,//"PROGRAM_RASTER",
+    0,//"PROGRAM_STORE",
+};
+
+static const char * gCVecTypeStrings[] = {
+    0,
+    0,//"F16",
+    "vecF32",
+    "vecF64",
+    "vecI8",
+    "vecI16",
+    "vecI32",
+    0,//"S64",
+    "vecU8",//U8",
+    "vecU16",//U16",
+    "vecU32",//U32",
+    0,//"U64",
+    0,//"UP_565",
+    0,//"UP_5551",
+    0,//"UP_4444",
+    0,//"ELEMENT",
+    0,//"TYPE",
+    0,//"ALLOCATION",
+    0,//"SAMPLER",
+    0,//"SCRIPT",
+    0,//"MESH",
+    0,//"PROGRAM_FRAGMENT",
+    0,//"PROGRAM_VERTEX",
+    0,//"PROGRAM_RASTER",
+    0,//"PROGRAM_STORE",
+};
+
+String8 Component::getCType() const
+{
+    char buf[64];
+    if (mVectorSize == 1) {
+        return String8(gCTypeStrings[mType]);
+    }
+
+    // Yuck, acc WAR
+    // Appears to have problems packing chars
+    if (mVectorSize == 4 && mType == RS_TYPE_UNSIGNED_8) {
+        return String8("int");
+    }
+
+
+    String8 s(gCVecTypeStrings[mType]);
+    sprintf(buf, "_%i_t", mVectorSize);
+    s.append(buf);
+    return s;
+}
+
+static const char * gTypeStrings[] = {
+    "NONE",
+    "F16",
+    "F32",
+    "F64",
+    "S8",
+    "S16",
+    "S32",
+    "S64",
+    "U8",
+    "U16",
+    "U32",
+    "U64",
+    "UP_565",
+    "UP_5551",
+    "UP_4444",
+    "ELEMENT",
+    "TYPE",
+    "ALLOCATION",
+    "SAMPLER",
+    "SCRIPT",
+    "MESH",
+    "PROGRAM_FRAGMENT",
+    "PROGRAM_VERTEX",
+    "PROGRAM_RASTER",
+    "PROGRAM_STORE",
+};
+
+static const char * gKindStrings[] = {
+    "USER",
+    "COLOR",
+    "POSITION",
+    "TEXTURE",
+    "NORMAL",
+    "INDEX",
+    "POINT_SIZE",
+    "PIXEL_L",
+    "PIXEL_A",
+    "PIXEL_LA",
+    "PIXEL_RGB",
+    "PIXEL_RGBA",
+};
+
+void Component::dumpLOGV(const char *prefix) const
+{
+    LOGV("%s   Component: %s, %s, vectorSize=%i, bits=%i",
+         prefix, gTypeStrings[mType], gKindStrings[mKind], mVectorSize, mBits);
+}
+
+
diff --git a/rsComponent.h b/rsComponent.h
new file mode 100644
index 0000000..c122c8e
--- /dev/null
+++ b/rsComponent.h
@@ -0,0 +1,68 @@
+/*
+ * 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_COMPONENT_H
+#define ANDROID_COMPONENT_H
+
+#include "rsUtils.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+
+// An element is a group of Components that occupies one cell in a structure.
+class Component
+{
+public:
+    Component();
+    ~Component();
+
+    void set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize=1);
+
+    uint32_t getGLType() const;
+    uint32_t getGLFormat() const;
+    String8 getCType() const;
+    void dumpLOGV(const char *prefix) const;
+
+
+    RsDataType getType() const {return mType;}
+    RsDataKind getKind() const {return mKind;}
+    bool getIsNormalized() const {return mNormalized;}
+    uint32_t getVectorSize() const {return mVectorSize;}
+    bool getIsFloat() const {return mIsFloat;}
+    bool getIsSigned() const {return mIsSigned;}
+    uint32_t getBits() const {return mBits;}
+
+protected:
+    RsDataType mType;
+    RsDataKind mKind;
+    bool mNormalized;
+    uint32_t mVectorSize;
+
+    // derived
+    uint32_t mBits;
+    uint32_t mTypeBits;
+    bool mIsFloat;
+    bool mIsSigned;
+    bool mIsPixel;
+};
+
+}
+}
+
+#endif
+
diff --git a/rsContext.cpp b/rsContext.cpp
index 8f56efa..11f26b9 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -142,6 +142,13 @@
     return ret;
 }
 
+void Context::checkError(const char *msg) const
+{
+    GLenum err = glGetError();
+    if (err != GL_NO_ERROR) {
+        LOGE("GL Error, 0x%x, from %s", err, msg);
+    }
+}
 
 uint32_t Context::runRootScript()
 {
@@ -169,11 +176,7 @@
     mStateFragmentStore.mLast.clear();
     uint32_t ret = runScript(mRootScript.get(), 0);
 
-    GLenum err = glGetError();
-    if (err != GL_NO_ERROR) {
-        LOGE("Pending GL Error, 0x%x", err);
-    }
-
+    checkError("runRootScript");
     return ret;
 }
 
@@ -340,10 +343,6 @@
      rsc->mObjDestroy.mNeedToEmpty = true;
      rsc->objDestroyOOBRun();
 
-     glClearColor(0,0,0,0);
-     glClear(GL_COLOR_BUFFER_BIT);
-     eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
-
      pthread_mutex_lock(&gInitMutex);
      rsc->deinitEGL();
      pthread_mutex_unlock(&gInitMutex);
diff --git a/rsContext.h b/rsContext.h
index dd0423e..aa7436d 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -168,6 +168,7 @@
     } props;
 
     void dumpDebug() const;
+    void checkError(const char *) const;
 
     mutable const ObjectBase * mObjHead;
 
diff --git a/rsElement.cpp b/rsElement.cpp
index e796556..79ff35a 100644
--- a/rsElement.cpp
+++ b/rsElement.cpp
@@ -24,9 +24,6 @@
 
 Element::Element(Context *rsc) : ObjectBase(rsc)
 {
-    mType = RS_TYPE_FLOAT;
-    mIsNormalized = false;
-    mKind = RS_KIND_USER;
     mBits = 0;
     mAllocFile = __FILE__;
     mAllocLine = __LINE__;
@@ -80,161 +77,6 @@
     return offset;
 }
 
-uint32_t Element::getGLType() const
-{
-    int bits[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 < mFieldCount; ct++) {
-        bits[ct] = mFields[ct].e->mBits;
-        if (mFields[ct].e->mFieldCount) {
-            return 0;
-        }
-        if (mFields[ct].e->mType != RS_TYPE_UNSIGNED) {
-            return 0;
-        }
-        if (!mFields[ct].e->mIsNormalized) {
-            return 0;
-        }
-    }
-
-    switch(mFieldCount) {
-    case 1:
-        if (bits[0] == 8) {
-            return GL_UNSIGNED_BYTE;
-        }
-        return 0;
-    case 2:
-        if ((bits[0] == 8) &&
-            (bits[1] == 8)) {
-            return GL_UNSIGNED_BYTE;
-        }
-        return 0;
-    case 3:
-        if ((bits[0] == 8) &&
-            (bits[1] == 8) &&
-            (bits[2] == 8)) {
-            return GL_UNSIGNED_BYTE;
-        }
-        if ((bits[0] == 5) &&
-            (bits[1] == 6) &&
-            (bits[2] == 5)) {
-            return GL_UNSIGNED_SHORT_5_6_5;
-        }
-        return 0;
-    case 4:
-        if ((bits[0] == 8) &&
-            (bits[1] == 8) &&
-            (bits[2] == 8) &&
-            (bits[3] == 8)) {
-            return GL_UNSIGNED_BYTE;
-        }
-        if ((bits[0] == 4) &&
-            (bits[1] == 4) &&
-            (bits[2] == 4) &&
-            (bits[3] == 4)) {
-            return GL_UNSIGNED_SHORT_4_4_4_4;
-        }
-        if ((bits[0] == 5) &&
-            (bits[1] == 5) &&
-            (bits[2] == 5) &&
-            (bits[3] == 1)) {
-            return GL_UNSIGNED_SHORT_5_5_5_1;
-        }
-    }
-    return 0;
-}
-
-uint32_t Element::getGLFormat() const
-{
-    if (!mFieldCount) {
-        if (mKind == RS_KIND_ALPHA) {
-            return GL_ALPHA;
-        }
-        if (mKind == RS_KIND_LUMINANCE) {
-            return GL_LUMINANCE;
-        }
-    }
-
-    switch(mFieldCount) {
-    case 2:
-        if ((mFields[0].e->mKind == RS_KIND_LUMINANCE) &&
-            (mFields[1].e->mKind == RS_KIND_ALPHA)) {
-            return GL_LUMINANCE_ALPHA;
-        }
-        break;
-    case 3:
-        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 ((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;
-    }
-    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);
@@ -246,19 +88,18 @@
     }
 }
 
-Element * Element::create(Context *rsc, RsDataKind dk, RsDataType dt,
-                          bool isNorm, size_t bits)
+
+Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
+                            bool isNorm, uint32_t vecSize)
 {
     Element *e = new Element(rsc);
-    e->mKind = dk;
-    e->mType = dt;
-    e->mIsNormalized = isNorm;
-    e->mBits = bits;
+    e->mComponent.set(dt, dk, isNorm, vecSize);
+    e->mBits = e->mComponent.getBits();
     return e;
 }
 
-Element * Element::create(Context *rsc, Element **ein, const char **nin,
-                          const size_t * lengths, size_t count)
+Element * Element::create(Context *rsc, size_t count, const Element **ein,
+                            const char **nin, const size_t * lengths)
 {
     Element *e = new Element(rsc);
     e->mFields = new ElementField_t [count];
@@ -267,11 +108,53 @@
     for (size_t ct=0; ct < count; ct++) {
         e->mFields[ct].e.set(ein[ct]);
         e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
+        LOGE("element %p %s", ein[ct], e->mFields[ct].name.string());
     }
 
     return e;
 }
 
+String8 Element::getCStructBody(uint32_t indent) const
+{
+    String8 si;
+    for (uint32_t ct=0; ct < indent; ct++) {
+        si.append(" ");
+    }
+
+    String8 s(si);
+    s.append("{\n");
+    for (uint32_t ct = 0; ct < mFieldCount; ct++) {
+        s.append(si);
+        s.append(mFields[ct].e->getCType(indent+4));
+        s.append(" ");
+        s.append(mFields[ct].name);
+        s.append(";\n");
+    }
+    s.append(si);
+    s.append("}");
+    return s;
+}
+
+String8 Element::getCType(uint32_t indent) const
+{
+    String8 s;
+    for (uint32_t ct=0; ct < indent; ct++) {
+        s.append(" ");
+    }
+
+    if (!mFieldCount) {
+        // Basic component.
+        s.append(mComponent.getCType());
+    } else {
+        s.append("struct ");
+        s.append(getCStructBody(indent));
+    }
+
+    return s;
+}
+
+
+
 
 ElementState::ElementState()
 {
@@ -288,14 +171,31 @@
 namespace android {
 namespace renderscript {
 
-void rsi_ElementBegin(Context *rsc)
+RsElement rsi_ElementCreate(Context *rsc,
+                            RsDataType dt,
+                            RsDataKind dk,
+                            bool norm,
+                            uint32_t vecSize)
 {
-    ElementState * sec = &rsc->mStateElement;
-
-    sec->mBuildList.clear();
-    sec->mNames.clear();
+    //LOGE("rsi_ElementCreate %i %i %i %i", dt, dk, norm, vecSize);
+    Element *e = Element::create(rsc, dt, dk, norm, vecSize);
+    e->incUserRef();
+    return e;
 }
 
+RsElement rsi_ElementCreate2(Context *rsc,
+                             size_t count,
+                             const RsElement * ein,
+                             const char ** names,
+                             const size_t * nameLengths)
+{
+    //LOGE("rsi_ElementCreate2 %i", count);
+    Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths);
+    e->incUserRef();
+    return e;
+}
+
+/*
 void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits, const char *name)
 {
     ElementState * sec = &rsc->mStateElement;
@@ -345,6 +245,7 @@
     free(tmpLengths);
     return se;
 }
+*/
 
 
 }
diff --git a/rsElement.h b/rsElement.h
index 43e2820..c46922c 100644
--- a/rsElement.h
+++ b/rsElement.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_STRUCTURED_ELEMENT_H
 #define ANDROID_STRUCTURED_ELEMENT_H
 
-//#include "rsComponent.h"
+#include "rsComponent.h"
 #include "rsUtils.h"
 #include "rsObjectBase.h"
 
@@ -53,20 +53,22 @@
     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;}
+    const Component & getComponent() const {return mComponent;}
+    RsDataType getType() const {return mComponent.getType();}
+    //bool getIsNormalized() const {return mIsNormalized;}
+    RsDataKind getKind() const {return mComponent.getKind();}
     uint32_t getBits() const {return mBits;}
     //uint32_t getGLType() const;
-    const char * getCType() const;
+
+    String8 getCType(uint32_t indent=0) const;
+    String8 getCStructBody(uint32_t indent=0) 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);
+    static Element * create(Context *rsc, RsDataType dt, RsDataKind dk,
+                            bool isNorm, uint32_t vecSize);
+    static Element * create(Context *rsc, size_t count, const Element **,
+                            const char **, const size_t * lengths);
 
 protected:
     // deallocate any components that are part of this element.
@@ -74,7 +76,7 @@
 
     typedef struct {
         String8 name;
-        ObjectBaseRef<Element> e;
+        ObjectBaseRef<const Element> e;
     } ElementField_t;
     ElementField_t *mFields;
     size_t mFieldCount;
@@ -82,12 +84,8 @@
 
     Element(Context *);
 
-
-    RsDataType mType;
-    bool mIsNormalized;
-    RsDataKind mKind;
+    Component mComponent;
     uint32_t mBits;
-    //String8 mName;
 };
 
 
diff --git a/rsFileA3D.cpp b/rsFileA3D.cpp
index c566665..e3272c5 100644
--- a/rsFileA3D.cpp
+++ b/rsFileA3D.cpp
@@ -324,6 +324,7 @@
 
 void FileA3D::processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie)
 {
+    /*
     rsi_ElementBegin(rsc);
 
     uint32_t count = io->loadU32();
@@ -338,6 +339,7 @@
     }
     LOGE("processChunk_Element create");
     ie->mRsObj = rsi_ElementCreate(rsc);
+    */
 }
 
 void FileA3D::processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie)
diff --git a/rsProgramFragment.cpp b/rsProgramFragment.cpp
index 05672e5..f7394a6 100644
--- a/rsProgramFragment.cpp
+++ b/rsProgramFragment.cpp
@@ -213,9 +213,9 @@
 
         if (mTextureEnableMask) {
             if (mPointSpriteEnable) {
-                mShader.append("  vec2 tex0 = gl_PointCoord;\n");
+                mShader.append("  vec2 t0 = gl_PointCoord;\n");
             } else {
-                mShader.append("  vec2 tex0 = varTex0.xy;\n");
+                mShader.append("  vec2 t0 = varTex0.xy;\n");
             }
         }
 
@@ -228,13 +228,39 @@
                     rsAssert(0);
                     break;
                 case RS_TEX_ENV_MODE_REPLACE:
-                    mShader.append("  col = texture2D(uni_Tex0, tex0);\n");
+                    switch(mTextureFormats[texNum]) {
+                    case 1:
+                        mShader.append("  col.a = texture2D(uni_Tex0, t0).a;\n");
+                        break;
+                    case 2:
+                        mShader.append("  col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
+                        break;
+                    case 3:
+                        mShader.append("  col.rgb = texture2D(uni_Tex0, t0).rgb;\n");
+                        break;
+                    case 4:
+                        mShader.append("  col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
+                        break;
+                    }
                     break;
                 case RS_TEX_ENV_MODE_MODULATE:
-                    mShader.append("  col *= texture2D(uni_Tex0, tex0);\n");
+                    switch(mTextureFormats[texNum]) {
+                    case 1:
+                        mShader.append("  col.a *= texture2D(uni_Tex0, t0).a;\n");
+                        break;
+                    case 2:
+                        mShader.append("  col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
+                        break;
+                    case 3:
+                        mShader.append("  col.rgb *= texture2D(uni_Tex0, t0).rgb;\n");
+                        break;
+                    case 4:
+                        mShader.append("  col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
+                        break;
+                    }
                     break;
                 case RS_TEX_ENV_MODE_DECAL:
-                    mShader.append("  col = texture2D(uni_Tex0, tex0);\n");
+                    mShader.append("  col = texture2D(uni_Tex0, t0);\n");
                     break;
                 }
 
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
index 153e2d6..fe628ca 100644
--- a/rsProgramVertex.cpp
+++ b/rsProgramVertex.cpp
@@ -246,9 +246,7 @@
 
 void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h)
 {
-    rsi_ElementBegin(rsc);
-    rsi_ElementAdd(rsc, RS_KIND_USER, RS_TYPE_FLOAT, false, 32, NULL);
-    RsElement e = rsi_ElementCreate(rsc);
+    RsElement e = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
 
     rsi_TypeBegin(rsc, e);
     rsi_TypeAdd(rsc, RS_DIMENSION_X, 48);
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index 3fa9813..9db3127 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -311,9 +311,15 @@
     char buf[256];
     String8 tmp;
 
-    str->append("struct vec2_s {float x; float y;};");
-    str->append("struct vec3_s {float x; float y; float z;};");
-    str->append("struct vec4_s {float x; float y; float z; float w;};");
+    str->append("struct vecF32_2_s {float x; float y;};\n");
+    str->append("struct vecF32_3_s {float x; float y; float z;};\n");
+    str->append("struct vecF32_4_s {float x; float y; float z; float w;};\n");
+    str->append("struct vecU8_4_s {char r; char g; char b; char a;};\n");
+    str->append("#define vecF32_2_t struct vecF32_2_s\n");
+    str->append("#define vecF32_3_t struct vecF32_3_s\n");
+    str->append("#define vecF32_4_t struct vecF32_4_s\n");
+    str->append("#define vecU8_4_t struct vecU8_4_s\n");
+    str->append("#define vecI8_4_t struct vecU8_4_s\n");
 
     for (size_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
         const Type *t = mConstantBufferTypes[ct].get();
@@ -324,8 +330,9 @@
         if (e->getName() && (e->getFieldCount() > 1)) {
             String8 s("struct struct_");
             s.append(e->getName());
-            appendElementBody(&s, e);
+            s.append(e->getCStructBody());
             s.append(";\n");
+
             s.append("#define ");
             s.append(e->getName());
             s.append("_t struct struct_");
@@ -337,45 +344,25 @@
             str->append(s);
         }
 
-        if (t->getName()) {
-            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(e->getFieldName(ct2));
-                sprintf(buf, " %i\n", ct2);
-                tmp.append(buf);
-                if (rsc->props.mLogScripts) {
-                    LOGV(tmp);
-                }
-                str->append(tmp);
-            }
-        }
-
         if (mSlotNames[ct].length() > 0) {
             String8 s;
-            if (e->getFieldCount() > 1) {
-                if (e->getName()) {
-                    // Use the named struct
-                    s.setTo(e->getName());
-                    s.append("_t *");
-                } else {
-                    // create an struct named from the slot.
-                    s.setTo("struct ");
-                    s.append(mSlotNames[ct]);
-                    s.append("_s");
-                    appendElementBody(&s, e);
-                    s.append(";\n");
-                    s.append("struct ");
-                    s.append(mSlotNames[ct]);
-                    s.append("_s * ");
-                }
+            if (e->getName()) {
+                // Use the named struct
+                s.setTo(e->getName());
             } else {
-                // Just make an array
-                s.setTo(e->getField(0)->getCType());
-                s.append("_t *");
+                // create an struct named from the slot.
+                s.setTo("struct ");
+                s.append(mSlotNames[ct]);
+                s.append("_s");
+                s.append(e->getCStructBody());
+                //appendElementBody(&s, e);
+                s.append(";\n");
+                s.append("struct ");
+                s.append(mSlotNames[ct]);
+                s.append("_s");
             }
+
+            s.append(" * ");
             s.append(mSlotNames[ct]);
             s.append(";\n");
             if (rsc->props.mLogScripts) {
diff --git a/rsScriptC_Lib.cpp b/rsScriptC_Lib.cpp
index e9f47d6..917f294 100644
--- a/rsScriptC_Lib.cpp
+++ b/rsScriptC_Lib.cpp
@@ -689,9 +689,9 @@
     VertexArray va;
     va.setPosition(2, GL_FLOAT, 12, (uint32_t)&vtx);
     if (rsc->checkVersion2_0()) {
-        va.setupGL2(&rsc->mStateVertexArray, &rsc->mShaderCache);
+        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
     } else {
-        va.setupGL(&rsc->mStateVertexArray);
+        va.setupGL(rsc, &rsc->mStateVertexArray);
     }
 
     glDrawArrays(GL_LINES, 0, 2);
@@ -707,9 +707,9 @@
     VertexArray va;
     va.setPosition(1, GL_FLOAT, 12, (uint32_t)&vtx);
     if (rsc->checkVersion2_0()) {
-        va.setupGL2(&rsc->mStateVertexArray, &rsc->mShaderCache);
+        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
     } else {
-        va.setupGL(&rsc->mStateVertexArray);
+        va.setupGL(rsc, &rsc->mStateVertexArray);
     }
 
     glDrawArrays(GL_POINTS, 0, 1);
@@ -742,9 +742,9 @@
     //va.setTexture(2, GL_FLOAT, 8, (uint32_t)&tex, 1);
     //
     if (rsc->checkVersion2_0()) {
-        va.setupGL2(&rsc->mStateVertexArray, &rsc->mShaderCache);
+        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
     } else {
-        va.setupGL(&rsc->mStateVertexArray);
+        va.setupGL(rsc, &rsc->mStateVertexArray);
     }
 
 
@@ -1223,33 +1223,33 @@
 
     // vec3
     { "vec3Norm", (void *)&SC_vec3Norm,
-        "void", "(struct vec3_s *)" },
+        "void", "(struct vecF32_3_s *)" },
     { "vec3Length", (void *)&SC_vec3Length,
-        "float", "(struct vec3_s *)" },
+        "float", "(struct vecF32_3_s *)" },
     { "vec3Add", (void *)&SC_vec3Add,
-        "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
+        "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
     { "vec3Sub", (void *)&SC_vec3Sub,
-        "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
+        "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
     { "vec3Cross", (void *)&SC_vec3Cross,
-        "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
+        "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
     { "vec3Dot", (void *)&SC_vec3Dot,
-        "float", "(struct vec3_s *lhs, struct vec3_s *rhs)" },
+        "float", "(struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
     { "vec3Scale", (void *)&SC_vec3Scale,
-        "void", "(struct vec3_s *lhs, float scale)" },
+        "void", "(struct vecF32_3_s *lhs, float scale)" },
 
     // vec4
     { "vec4Norm", (void *)&SC_vec4Norm,
-        "void", "(struct vec4_s *)" },
+        "void", "(struct vecF32_4_s *)" },
     { "vec4Length", (void *)&SC_vec4Length,
-        "float", "(struct vec4_s *)" },
+        "float", "(struct vecF32_4_s *)" },
     { "vec4Add", (void *)&SC_vec4Add,
-        "void", "(struct vec4_s *dest, struct vec4_s *lhs, struct vec4_s *rhs)" },
+        "void", "(struct vecF32_4_s *dest, struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
     { "vec4Sub", (void *)&SC_vec4Sub,
-        "void", "(struct vec4_s *dest, struct vec4_s *lhs, struct vec4_s *rhs)" },
+        "void", "(struct vecF32_4_s *dest, struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
     { "vec4Dot", (void *)&SC_vec4Dot,
-        "float", "(struct vec4_s *lhs, struct vec4_s *rhs)" },
+        "float", "(struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
     { "vec4Scale", (void *)&SC_vec4Scale,
-        "void", "(struct vec4_s *lhs, float scale)" },
+        "void", "(struct vecF32_4_s *lhs, float scale)" },
 
     // context
     { "bindProgramFragment", (void *)&SC_bindProgramFragment,
diff --git a/rsShaderCache.cpp b/rsShaderCache.cpp
index 8e2af34..311e3f5 100644
--- a/rsShaderCache.cpp
+++ b/rsShaderCache.cpp
@@ -93,7 +93,10 @@
 
         glBindAttribLocation(pgm, VertexArray::POSITION, "attrib_Position");
         glBindAttribLocation(pgm, VertexArray::COLOR, "attrib_Color");
-
+        //glBindAttribLocation(pgm, VertexArray::NORMAL, "attrib_Normal");
+        //glBindAttribLocation(pgm, VertexArray::POINT_SIZE, "attrib_PointSize");
+        //glBindAttribLocation(pgm, VertexArray::TEXTURE_0, "attrib_T0");
+        //glBindAttribLocation(pgm, VertexArray::TEXTURE_1, "attrib_T1");
 
         //LOGE("e2 %x", glGetError());
         glLinkProgram(pgm);
diff --git a/rsSimpleMesh.cpp b/rsSimpleMesh.cpp
index f7d14a5..5f5622d 100644
--- a/rsSimpleMesh.cpp
+++ b/rsSimpleMesh.cpp
@@ -62,9 +62,9 @@
         mVertexTypes[ct]->enableGLVertexBuffer(&va);
     }
     if (rsc->checkVersion2_0()) {
-        va.setupGL2(0, &rsc->mShaderCache);
+        va.setupGL2(rsc, 0, &rsc->mShaderCache);
     } else {
-        va.setupGL(0);
+        va.setupGL(rsc, 0);
     }
 
     if (mIndexType.get()) {
@@ -74,6 +74,8 @@
     } else {
         glDrawArrays(mGLPrimitive, start, len);
     }
+
+    rsc->checkError("SimpleMesh::renderRange");
 }
 
 void SimpleMesh::uploadAll(Context *rsc)
@@ -89,6 +91,7 @@
     if (mPrimitiveBuffer.get()) {
         mPrimitiveBuffer->deferedUploadToBufferObject(rsc);
     }
+    rsc->checkError("SimpleMesh::uploadAll");
 }
 
 
diff --git a/rsType.cpp b/rsType.cpp
index 5eac0b5..e7bcb08 100644
--- a/rsType.cpp
+++ b/rsType.cpp
@@ -137,106 +137,44 @@
     memset(&mGL, 0, sizeof(mGL));
 
     for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
-        const Element *c = getElement()->getField(ct);
+        const Component &c = getElement()->getField(ct)->getComponent();
 
-        switch(c->getKind()) {
-        case RS_KIND_X:
+        switch(c.getKind()) {
+        case RS_KIND_POSITION:
             rsAssert(mGL.mVtx.size == 0);
-            mGL.mVtx.size = 1;
+            mGL.mVtx.size = c.getVectorSize();
             mGL.mVtx.offset = mElement->getFieldOffsetBytes(ct);
-            mGL.mVtx.type = c->getGLType();
+            mGL.mVtx.type = c.getGLType();
             break;
-        case RS_KIND_Y:
-            rsAssert(mGL.mVtx.size == 1);
-            rsAssert(mGL.mVtx.type == c->getGLType());
-            mGL.mVtx.size = 2;
-            break;
-        case RS_KIND_Z:
-            rsAssert(mGL.mVtx.size == 2);
-            rsAssert(mGL.mVtx.type == c->getGLType());
-            mGL.mVtx.size = 3;
-            break;
-        case RS_KIND_W:
-            rsAssert(mGL.mVtx.size == 4);
-            rsAssert(mGL.mVtx.type == c->getGLType());
-            mGL.mVtx.size = 4;
-        break;
 
-        case RS_KIND_RED:
+        case RS_KIND_COLOR:
             rsAssert(mGL.mColor.size == 0);
-            mGL.mColor.size = 1;
+            mGL.mColor.size = c.getVectorSize();
             mGL.mColor.offset = mElement->getFieldOffsetBytes(ct);
-            mGL.mColor.type = c->getGLType();
+            mGL.mColor.type = c.getGLType();
             break;
-        case RS_KIND_GREEN:
-            rsAssert(mGL.mColor.size == 1);
-            rsAssert(mGL.mColor.type == c->getGLType());
-            mGL.mColor.size = 2;
-            break;
-        case RS_KIND_BLUE:
-            rsAssert(mGL.mColor.size == 2);
-            rsAssert(mGL.mColor.type == c->getGLType());
-            mGL.mColor.size = 3;
-            break;
-        case RS_KIND_ALPHA:
-            // Can be RGBA or A at this point
-            if (mGL.mColor.size > 0) {
-                rsAssert(mGL.mColor.size == 3);
-                rsAssert(mGL.mColor.type == c->getGLType());
-                mGL.mColor.size = 4;
-            } else {
-                mGL.mColor.size = 1;
-                mGL.mColor.offset = mElement->getFieldOffsetBytes(ct);
-                mGL.mColor.type = c->getGLType();
-            }
-        break;
 
-        case RS_KIND_NX:
+        case RS_KIND_NORMAL:
             rsAssert(mGL.mNorm.size == 0);
-            mGL.mNorm.size = 1;
+            mGL.mNorm.size = c.getVectorSize();
             mGL.mNorm.offset = mElement->getFieldOffsetBytes(ct);
-            mGL.mNorm.type = c->getGLType();
-        break;
-        case RS_KIND_NY:
-            rsAssert(mGL.mNorm.size == 1);
-            rsAssert(mGL.mNorm.type == c->getGLType());
-            mGL.mNorm.size = 2;
-        break;
-        case RS_KIND_NZ:
-            rsAssert(mGL.mNorm.size == 2);
-            rsAssert(mGL.mNorm.type == c->getGLType());
-            mGL.mNorm.size = 3;
-        break;
+            mGL.mNorm.type = c.getGLType();
+            break;
 
-        case RS_KIND_S:
+        case RS_KIND_TEXTURE:
             if (mGL.mTex[texNum].size) {
                 texNum++;
             }
-            mGL.mTex[texNum].size = 1;
+            mGL.mTex[texNum].size = c.getVectorSize();
             mGL.mTex[texNum].offset = mElement->getFieldOffsetBytes(ct);
-            mGL.mTex[texNum].type = c->getGLType();
-        break;
-        case RS_KIND_T:
-            rsAssert(mGL.mTex[texNum].size == 1);
-            rsAssert(mGL.mTex[texNum].type == c->getGLType());
-            mGL.mTex[texNum].size = 2;
-        break;
-        case RS_KIND_R:
-            rsAssert(mGL.mTex[texNum].size == 2);
-            rsAssert(mGL.mTex[texNum].type == c->getGLType());
-            mGL.mTex[texNum].size = 3;
-        break;
-        case RS_KIND_Q:
-            rsAssert(mGL.mTex[texNum].size == 3);
-            rsAssert(mGL.mTex[texNum].type == c->getGLType());
-            mGL.mTex[texNum].size = 4;
-        break;
+            mGL.mTex[texNum].type = c.getGLType();
+            break;
 
         case RS_KIND_POINT_SIZE:
             rsAssert(!mGL.mPointSize.size);
-            mGL.mPointSize.size = 1;
+            mGL.mPointSize.size = c.getVectorSize();
             mGL.mPointSize.offset = mElement->getFieldOffsetBytes(ct);
-            mGL.mPointSize.type = c->getGLType();
+            mGL.mPointSize.type = c.getGLType();
         break;
 
         default:
diff --git a/rsVertexArray.cpp b/rsVertexArray.cpp
index 34d42ed..2ba0ef9 100644
--- a/rsVertexArray.cpp
+++ b/rsVertexArray.cpp
@@ -96,15 +96,16 @@
 }
 
 void VertexArray::logAttrib(uint32_t idx) const {
-    LOGE("va %i: buf=%i  size=%i  type=0x%x  stride=0x%x  offset=0x%x", idx,
+    LOGE("va %i: buf=%i  size=%i  type=0x%x  stride=0x%x  norm=%i  offset=0x%x", idx,
          mAttribs[idx].buffer,
          mAttribs[idx].size,
          mAttribs[idx].type,
          mAttribs[idx].stride,
+         mAttribs[idx].normalized,
          mAttribs[idx].offset);
 }
 
-void VertexArray::setupGL(class VertexArrayState *state) const
+void VertexArray::setupGL(const Context *rsc, class VertexArrayState *state) const
 {
     if (mAttribs[POSITION].size) {
         //logAttrib(POSITION);
@@ -168,9 +169,10 @@
     } else {
         glDisableClientState(GL_POINT_SIZE_ARRAY_OES);
     }
+    rsc->checkError("VertexArray::setupGL");
 }
 
-void VertexArray::setupGL2(class VertexArrayState *state, ShaderCache *sc) const
+void VertexArray::setupGL2(const Context *rsc, class VertexArrayState *state, ShaderCache *sc) const
 {
     for (int ct=1; ct < _LAST; ct++) {
         glDisableVertexAttribArray(ct);
@@ -194,6 +196,7 @@
             rsAssert(ct);
         }
     }
+    rsc->checkError("VertexArray::setupGL2");
 }
 ////////////////////////////////////////////
 
diff --git a/rsVertexArray.h b/rsVertexArray.h
index 235ffef..f97813f 100644
--- a/rsVertexArray.h
+++ b/rsVertexArray.h
@@ -64,8 +64,8 @@
     void setPointSize(uint32_t type, uint32_t stride, uint32_t offset);
     void setTexture(uint32_t size, uint32_t type, uint32_t stride, uint32_t offset, uint32_t num);
 
-    void setupGL(class VertexArrayState *) const;
-    void setupGL2(class VertexArrayState *, ShaderCache *) const;
+    void setupGL(const Context *rsc, class VertexArrayState *) const;
+    void setupGL2(const Context *rsc, class VertexArrayState *, ShaderCache *) const;
     void logAttrib(uint32_t idx) const;
 
 protected: