diff --git a/rsProgram.cpp b/rsProgram.cpp
index 4ef05bf..28fa061 100644
--- a/rsProgram.cpp
+++ b/rsProgram.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -15,11 +15,6 @@
  */
 
 #include "rsContext.h"
-#ifndef ANDROID_RS_SERIALIZE
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#endif //ANDROID_RS_SERIALIZE
-
 #include "rsProgram.h"
 
 using namespace android;
@@ -36,26 +31,22 @@
     initMemberVars();
     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++;
+            mHal.state.inputElementsCount++;
         }
         if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
-            mConstantCount++;
+            mHal.state.constantsCount++;
         }
         if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
-            mTextureCount++;
+            mHal.state.texturesCount++;
         }
     }
 
-    mTextures = new ObjectBaseRef<Allocation>[mTextureCount];
-    mSamplers = new ObjectBaseRef<Sampler>[mTextureCount];
-    mTextureTargets = new RsTextureTarget[mTextureCount];
-    mInputElements = new ObjectBaseRef<Element>[mInputCount];
-    mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
-    mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
-    mConstants = new ObjectBaseRef<Allocation>[mConstantCount];
+    mHal.state.textures = new ObjectBaseRef<Allocation>[mHal.state.texturesCount];
+    mHal.state.samplers = new ObjectBaseRef<Sampler>[mHal.state.texturesCount];
+    mHal.state.textureTargets = new RsTextureTarget[mHal.state.texturesCount];
+    mHal.state.inputElements = new ObjectBaseRef<Element>[mHal.state.inputElementsCount];
+    mHal.state.constantTypes = new ObjectBaseRef<Type>[mHal.state.constantsCount];
+    mHal.state.constants = new ObjectBaseRef<Allocation>[mHal.state.constantsCount];
 
     uint32_t input = 0;
     uint32_t output = 0;
@@ -63,16 +54,13 @@
     uint32_t texture = 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]));
+            mHal.state.inputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
         }
         if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
-            mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
+            mHal.state.constantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
         }
         if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
-            mTextureTargets[texture++] = (RsTextureTarget)params[ct+1];
+            mHal.state.textureTargets[texture++] = (RsTextureTarget)params[ct+1];
         }
     }
     mIsInternal = false;
@@ -84,88 +72,69 @@
         shaderLength -= internalTokenLen;
     }
     mUserShader.setTo(shaderText, shaderLength);
-
-    initAttribAndUniformArray();
 }
 
 Program::~Program() {
-    if (mRSC->props.mLogShaders) {
-        LOGV("Program::~Program with shader id %u", mShaderID);
-    }
 
-    if (mShaderID) {
-        glDeleteShader(mShaderID);
-    }
-
-    for (uint32_t ct=0; ct < mConstantCount; ct++) {
+    for (uint32_t ct=0; ct < mHal.state.constantsCount; ct++) {
         bindAllocation(NULL, NULL, ct);
     }
 
-    for (uint32_t ct=0; ct < mTextureCount; ct++) {
+    for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) {
         bindTexture(NULL, ct, NULL);
         bindSampler(NULL, ct, NULL);
     }
-    delete[] mTextures;
-    delete[] mSamplers;
-    delete[] mTextureTargets;
-    delete[] mInputElements;
-    delete[] mOutputElements;
-    delete[] mConstantTypes;
-    delete[] mConstants;
-    delete[] mAttribNames;
-    delete[] mUniformNames;
-    delete[] mUniformArraySizes;
-    mInputCount = 0;
-    mOutputCount = 0;
-    mConstantCount = 0;
+    delete[] mHal.state.textures;
+    delete[] mHal.state.samplers;
+    delete[] mHal.state.textureTargets;
+    delete[] mHal.state.inputElements;
+    delete[] mHal.state.constantTypes;
+    delete[] mHal.state.constants;
+    mHal.state.inputElementsCount = 0;
+    mHal.state.constantsCount = 0;
+    mHal.state.texturesCount = 0;
 }
 
 void Program::initMemberVars() {
     mDirty = true;
-    mShaderID = 0;
-    mAttribCount = 0;
-    mUniformCount = 0;
-    mTextureCount = 0;
 
-    mTextures = NULL;
-    mSamplers = NULL;
-    mTextureTargets = NULL;
-    mInputElements = NULL;
-    mOutputElements = NULL;
-    mConstantTypes = NULL;
-    mConstants = NULL;
-    mAttribNames = NULL;
-    mUniformNames = NULL;
-    mUniformArraySizes = NULL;
-    mInputCount = 0;
-    mOutputCount = 0;
-    mConstantCount = 0;
-    mIsValid = false;
+    mHal.drv = NULL;
+    mHal.state.textures = NULL;
+    mHal.state.samplers = NULL;
+    mHal.state.textureTargets = NULL;
+    mHal.state.inputElements = NULL;
+    mHal.state.constantTypes = NULL;
+    mHal.state.constants = NULL;
+
+    mHal.state.inputElementsCount = 0;
+    mHal.state.constantsCount = 0;
+    mHal.state.texturesCount = 0;
+
     mIsInternal = false;
 }
 
 void Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot) {
     if (alloc != NULL) {
-        if (slot >= mConstantCount) {
+        if (slot >= mHal.state.constantsCount) {
             LOGE("Attempt to bind alloc at slot %u, on shader id %u, but const count is %u",
-                 slot, (uint32_t)this, mConstantCount);
+                 slot, (uint32_t)this, mHal.state.constantsCount);
             rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
             return;
         }
-        if (!alloc->getType()->isEqual(mConstantTypes[slot].get())) {
+        if (!alloc->getType()->isEqual(mHal.state.constantTypes[slot].get())) {
             LOGE("Attempt to bind alloc at slot %u, on shader id %u, but types mismatch",
                  slot, (uint32_t)this);
             rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
             return;
         }
     }
-    if (mConstants[slot].get() == alloc) {
+    if (mHal.state.constants[slot].get() == alloc) {
         return;
     }
-    if (mConstants[slot].get()) {
-        mConstants[slot].get()->removeProgramToDirty(this);
+    if (mHal.state.constants[slot].get()) {
+        mHal.state.constants[slot].get()->removeProgramToDirty(this);
     }
-    mConstants[slot].set(alloc);
+    mHal.state.constants[slot].set(alloc);
     if (alloc) {
         alloc->addProgramToDirty(this);
     }
@@ -173,327 +142,38 @@
 }
 
 void Program::bindTexture(Context *rsc, uint32_t slot, Allocation *a) {
-    if (slot >= mTextureCount) {
-        LOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mTextureCount);
+    if (slot >= mHal.state.texturesCount) {
+        LOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mHal.state.texturesCount);
         rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind texture");
         return;
     }
 
-    if (a && a->getType()->getDimFaces() && mTextureTargets[slot] != RS_TEXTURE_CUBE) {
+    if (a && a->getType()->getDimFaces() && mHal.state.textureTargets[slot] != RS_TEXTURE_CUBE) {
         LOGE("Attempt to bind cubemap to slot %u but 2d texture needed", slot);
         rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind cubemap to 2d texture slot");
         return;
     }
 
     //LOGE("bindtex %i %p", slot, a);
-    mTextures[slot].set(a);
+    mHal.state.textures[slot].set(a);
     mDirty = true;
 }
 
 void Program::bindSampler(Context *rsc, uint32_t slot, Sampler *s) {
-    if (slot >= mTextureCount) {
-        LOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mTextureCount);
+    if (slot >= mHal.state.texturesCount) {
+        LOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mHal.state.texturesCount);
         rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind sampler");
         return;
     }
 
-    mSamplers[slot].set(s);
+    mHal.state.samplers[slot].set(s);
     mDirty = true;
 }
 
-String8 Program::getGLSLInputString() const {
-    String8 s;
-    for (uint32_t ct=0; ct < mInputCount; ct++) {
-        const Element *e = mInputElements[ct].get();
-        for (uint32_t field=0; field < e->getFieldCount(); field++) {
-            const Element *f = e->getField(field);
-
-            // Cannot be complex
-            rsAssert(!f->getFieldCount());
-            switch (f->getComponent().getVectorSize()) {
-            case 1: s.append("attribute float ATTRIB_"); break;
-            case 2: s.append("attribute vec2 ATTRIB_"); break;
-            case 3: s.append("attribute vec3 ATTRIB_"); break;
-            case 4: s.append("attribute vec4 ATTRIB_"); break;
-            default:
-                rsAssert(0);
-            }
-
-            s.append(e->getFieldName(field));
-            s.append(";\n");
-        }
-    }
-    return s;
-}
-
-String8 Program::getGLSLOutputString() const {
-    return String8();
-}
-
-String8 Program::getGLSLConstantString() const {
-    return String8();
-}
-
-void Program::createShader() {
-}
-
-bool Program::loadShader(Context *rsc, uint32_t type) {
-    mShaderID = glCreateShader(type);
-    rsAssert(mShaderID);
-
-    if (rsc->props.mLogShaders) {
-        LOGV("Loading shader type %x, ID %i", type, mShaderID);
-        LOGV("%s", mShader.string());
-    }
-
-    if (mShaderID) {
-        const char * ss = mShader.string();
-        glShaderSource(mShaderID, 1, &ss, NULL);
-        glCompileShader(mShaderID);
-
-        GLint compiled = 0;
-        glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
-        if (!compiled) {
-            GLint infoLen = 0;
-            glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
-            if (infoLen) {
-                char* buf = (char*) malloc(infoLen);
-                if (buf) {
-                    glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
-                    LOGE("Could not compile shader \n%s\n", buf);
-                    free(buf);
-                }
-                glDeleteShader(mShaderID);
-                mShaderID = 0;
-                rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,");
-                return false;
-            }
-        }
-    }
-
-    if (rsc->props.mLogShaders) {
-        LOGV("--Shader load result %x ", glGetError());
-    }
-    mIsValid = true;
-    return true;
-}
-
 void Program::setShader(const char *txt, uint32_t len) {
     mUserShader.setTo(txt, len);
 }
 
-void Program::appendUserConstants() {
-    for (uint32_t ct=0; ct < mConstantCount; ct++) {
-        const Element *e = mConstantTypes[ct]->getElement();
-        for (uint32_t field=0; field < e->getFieldCount(); field++) {
-            const Element *f = e->getField(field);
-            const char *fn = e->getFieldName(field);
-
-            if (fn[0] == '#') {
-                continue;
-            }
-
-            // Cannot be complex
-            rsAssert(!f->getFieldCount());
-            if (f->getType() == RS_TYPE_MATRIX_4X4) {
-                mShader.append("uniform mat4 UNI_");
-            } else if (f->getType() == RS_TYPE_MATRIX_3X3) {
-                mShader.append("uniform mat3 UNI_");
-            } else if (f->getType() == RS_TYPE_MATRIX_2X2) {
-                mShader.append("uniform mat2 UNI_");
-            } else {
-                switch (f->getComponent().getVectorSize()) {
-                case 1: mShader.append("uniform float UNI_"); break;
-                case 2: mShader.append("uniform vec2 UNI_"); break;
-                case 3: mShader.append("uniform vec3 UNI_"); break;
-                case 4: mShader.append("uniform vec4 UNI_"); break;
-                default:
-                    rsAssert(0);
-                }
-            }
-
-            mShader.append(fn);
-            if (e->getFieldArraySize(field) > 1) {
-                mShader.appendFormat("[%d]", e->getFieldArraySize(field));
-            }
-            mShader.append(";\n");
-        }
-    }
-}
-
-void Program::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
-    RsDataType dataType = field->getType();
-    uint32_t elementSize = field->getSizeBytes() / sizeof(float);
-    for (uint32_t i = 0; i < arraySize; i ++) {
-        if (arraySize > 1) {
-            LOGV("Array Element [%u]", i);
-        }
-        if (dataType == RS_TYPE_MATRIX_4X4) {
-            LOGV("Matrix4x4");
-            LOGV("{%f, %f, %f, %f",  fd[0], fd[4], fd[8], fd[12]);
-            LOGV(" %f, %f, %f, %f",  fd[1], fd[5], fd[9], fd[13]);
-            LOGV(" %f, %f, %f, %f",  fd[2], fd[6], fd[10], fd[14]);
-            LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
-        } else if (dataType == RS_TYPE_MATRIX_3X3) {
-            LOGV("Matrix3x3");
-            LOGV("{%f, %f, %f",  fd[0], fd[3], fd[6]);
-            LOGV(" %f, %f, %f",  fd[1], fd[4], fd[7]);
-            LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
-        } else if (dataType == RS_TYPE_MATRIX_2X2) {
-            LOGV("Matrix2x2");
-            LOGV("{%f, %f",  fd[0], fd[2]);
-            LOGV(" %f, %f}", fd[1], fd[3]);
-        } else {
-            switch (field->getComponent().getVectorSize()) {
-            case 1:
-                LOGV("Uniform 1 = %f", fd[0]);
-                break;
-            case 2:
-                LOGV("Uniform 2 = %f %f", fd[0], fd[1]);
-                break;
-            case 3:
-                LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
-                break;
-            case 4:
-                LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
-                break;
-            default:
-                rsAssert(0);
-            }
-        }
-        LOGE("Element size %u data=%p", elementSize, fd);
-        fd += elementSize;
-        LOGE("New data=%p", fd);
-    }
-}
-
-void Program::setUniform(Context *rsc, const Element *field, const float *fd,
-                         int32_t slot, uint32_t arraySize ) {
-    RsDataType dataType = field->getType();
-    if (dataType == RS_TYPE_MATRIX_4X4) {
-        glUniformMatrix4fv(slot, arraySize, GL_FALSE, fd);
-    } else if (dataType == RS_TYPE_MATRIX_3X3) {
-        glUniformMatrix3fv(slot, arraySize, GL_FALSE, fd);
-    } else if (dataType == RS_TYPE_MATRIX_2X2) {
-        glUniformMatrix2fv(slot, arraySize, GL_FALSE, fd);
-    } else {
-        switch (field->getComponent().getVectorSize()) {
-        case 1:
-            glUniform1fv(slot, arraySize, fd);
-            break;
-        case 2:
-            glUniform2fv(slot, arraySize, fd);
-            break;
-        case 3:
-            glUniform3fv(slot, arraySize, fd);
-            break;
-        case 4:
-            glUniform4fv(slot, arraySize, fd);
-            break;
-        default:
-            rsAssert(0);
-        }
-    }
-}
-
-void Program::setupUserConstants(Context *rsc, ShaderCache *sc, bool isFragment) {
-    uint32_t uidx = 0;
-    for (uint32_t ct=0; ct < mConstantCount; ct++) {
-        Allocation *alloc = mConstants[ct].get();
-        if (!alloc) {
-            LOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set", (uint32_t)this, ct);
-            rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
-            continue;
-        }
-
-        const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
-        const Element *e = mConstantTypes[ct]->getElement();
-        for (uint32_t field=0; field < e->getFieldCount(); field++) {
-            const Element *f = e->getField(field);
-            const char *fieldName = e->getFieldName(field);
-            // If this field is padding, skip it
-            if (fieldName[0] == '#') {
-                continue;
-            }
-
-            uint32_t offset = e->getFieldOffsetBytes(field);
-            const float *fd = reinterpret_cast<const float *>(&data[offset]);
-
-            int32_t slot = -1;
-            uint32_t arraySize = 1;
-            if (!isFragment) {
-                slot = sc->vtxUniformSlot(uidx);
-                arraySize = sc->vtxUniformSize(uidx);
-            } else {
-                slot = sc->fragUniformSlot(uidx);
-                arraySize = sc->fragUniformSize(uidx);
-            }
-            if (rsc->props.mLogShadersUniforms) {
-                LOGV("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
-            }
-            uidx ++;
-            if (slot < 0) {
-                continue;
-            }
-
-            if (rsc->props.mLogShadersUniforms) {
-                logUniform(f, fd, arraySize);
-            }
-            setUniform(rsc, f, fd, slot, arraySize);
-        }
-    }
-}
-
-void Program::initAttribAndUniformArray() {
-    mAttribCount = 0;
-    for (uint32_t ct=0; ct < mInputCount; ct++) {
-        const Element *elem = mInputElements[ct].get();
-        for (uint32_t field=0; field < elem->getFieldCount(); field++) {
-            if (elem->getFieldName(field)[0] != '#') {
-                mAttribCount ++;
-            }
-        }
-    }
-
-    mUniformCount = 0;
-    for (uint32_t ct=0; ct < mConstantCount; ct++) {
-        const Element *elem = mConstantTypes[ct]->getElement();
-
-        for (uint32_t field=0; field < elem->getFieldCount(); field++) {
-            if (elem->getFieldName(field)[0] != '#') {
-                mUniformCount ++;
-            }
-        }
-    }
-    mUniformCount += mTextureCount;
-
-    if (mAttribCount) {
-        mAttribNames = new String8[mAttribCount];
-    }
-    if (mUniformCount) {
-        mUniformNames = new String8[mUniformCount];
-        mUniformArraySizes = new uint32_t[mUniformCount];
-    }
-}
-
-void Program::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix) {
-    rsAssert(e->getFieldCount());
-    for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
-        const Element *ce = e->getField(ct);
-        if (ce->getFieldCount()) {
-            initAddUserElement(ce, names, arrayLengths, count, prefix);
-        } else if (e->getFieldName(ct)[0] != '#') {
-            String8 tmp(prefix);
-            tmp.append(e->getFieldName(ct));
-            names[*count].setTo(tmp.string());
-            if (arrayLengths) {
-                arrayLengths[*count] = e->getFieldArraySize(ct);
-            }
-            (*count)++;
-        }
-    }
-}
-
 namespace android {
 namespace renderscript {
 
