Piping texture names through shader builder.
Fixing uint size_t mismatch.

Change-Id: Ia7c8bd9f829deaa50e1cc381ccd50f29676bbdfb
diff --git a/driver/rsdProgram.cpp b/driver/rsdProgram.cpp
index 852b6bf..fa4cb0f 100644
--- a/driver/rsdProgram.cpp
+++ b/driver/rsdProgram.cpp
@@ -34,8 +34,11 @@
 using namespace android::renderscript;
 
 bool rsdProgramVertexInit(const Context *rsc, const ProgramVertex *pv,
-                          const char* shader, size_t shaderLen) {
-    RsdShader *drv = new RsdShader(pv, GL_VERTEX_SHADER, shader, shaderLen);
+                          const char* shader, size_t shaderLen,
+                          const char** textureNames, size_t textureNamesCount,
+                          const size_t *textureNamesLength) {
+    RsdShader *drv = new RsdShader(pv, GL_VERTEX_SHADER, shader, shaderLen,
+                                   textureNames, textureNamesCount, textureNamesLength);
     pv->mHal.drv = drv;
 
     return drv->createShader();
@@ -78,8 +81,11 @@
 }
 
 bool rsdProgramFragmentInit(const Context *rsc, const ProgramFragment *pf,
-                          const char* shader, size_t shaderLen) {
-    RsdShader *drv = new RsdShader(pf, GL_FRAGMENT_SHADER, shader, shaderLen);
+                            const char* shader, size_t shaderLen,
+                            const char** textureNames, size_t textureNamesCount,
+                            const size_t *textureNamesLength) {
+    RsdShader *drv = new RsdShader(pf, GL_FRAGMENT_SHADER, shader, shaderLen,
+                                   textureNames, textureNamesCount, textureNamesLength);
     pf->mHal.drv = drv;
 
     return drv->createShader();
diff --git a/driver/rsdProgramFragment.h b/driver/rsdProgramFragment.h
index 366cb40..b03a9fe 100644
--- a/driver/rsdProgramFragment.h
+++ b/driver/rsdProgramFragment.h
@@ -22,7 +22,9 @@
 
 bool rsdProgramFragmentInit(const android::renderscript::Context *rsc,
                             const android::renderscript::ProgramFragment *,
-                            const char* shader, uint32_t shaderLen);
+                            const char* shader, size_t shaderLen,
+                            const char** textureNames, size_t textureNamesCount,
+                            const size_t *textureNamesLength);
 void rsdProgramFragmentSetActive(const android::renderscript::Context *rsc,
                                  const android::renderscript::ProgramFragment *);
 void rsdProgramFragmentDestroy(const android::renderscript::Context *rsc,
diff --git a/driver/rsdProgramVertex.h b/driver/rsdProgramVertex.h
index e998572..f917a41 100644
--- a/driver/rsdProgramVertex.h
+++ b/driver/rsdProgramVertex.h
@@ -21,7 +21,9 @@
 
 bool rsdProgramVertexInit(const android::renderscript::Context *rsc,
                           const android::renderscript::ProgramVertex *,
-                          const char* shader, uint32_t shaderLen);
+                          const char* shader, size_t shaderLen,
+                          const char** textureNames, size_t textureNamesCount,
+                          const size_t *textureNamesLength);
 void rsdProgramVertexSetActive(const android::renderscript::Context *rsc,
                                const android::renderscript::ProgramVertex *);
 void rsdProgramVertexDestroy(const android::renderscript::Context *rsc,
diff --git a/driver/rsdShader.cpp b/driver/rsdShader.cpp
index 0e5b388..1e73b95 100644
--- a/driver/rsdShader.cpp
+++ b/driver/rsdShader.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 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.
@@ -30,14 +30,16 @@
 using namespace android::renderscript;
 
 RsdShader::RsdShader(const Program *p, uint32_t type,
-                       const char * shaderText, size_t shaderLength) {
-
+                     const char * shaderText, size_t shaderLength,
+                     const char** textureNames, size_t textureNamesCount,
+                     const size_t *textureNamesLength) {
     mUserShader.setTo(shaderText, shaderLength);
     mRSProgram = p;
     mType = type;
     initMemberVars();
     initAttribAndUniformArray();
-    init();
+    init(textureNames, textureNamesCount, textureNamesLength);
+    createTexturesString(textureNames, textureNamesCount, textureNamesLength);
 }
 
 RsdShader::~RsdShader() {
@@ -65,25 +67,26 @@
     mIsValid = false;
 }
 
-void RsdShader::init() {
+void RsdShader::init(const char** textureNames, size_t textureNamesCount,
+                     const size_t *textureNamesLength) {
     uint32_t attribCount = 0;
     uint32_t uniformCount = 0;
     for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
-        initAddUserElement(mRSProgram->mHal.state.inputElements[ct], mAttribNames, NULL, &attribCount, RS_SHADER_ATTR);
+        initAddUserElement(mRSProgram->mHal.state.inputElements[ct], mAttribNames,
+                           NULL, &attribCount, RS_SHADER_ATTR);
     }
     for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
-        initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
+        initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(),
+                           mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
     }
 
     mTextureUniformIndexStart = uniformCount;
-    char buf[256];
     for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
-        snprintf(buf, sizeof(buf), "UNI_Tex%i", ct);
-        mUniformNames[uniformCount].setTo(buf);
+        mUniformNames[uniformCount].setTo("UNI_");
+        mUniformNames[uniformCount].append(textureNames[ct], textureNamesLength[ct]);
         mUniformArraySizes[uniformCount] = 1;
         uniformCount++;
     }
-
 }
 
 String8 RsdShader::getGLSLInputString() const {
@@ -135,22 +138,25 @@
     }
 }
 
-void RsdShader::appendTextures() {
-    char buf[256];
-    for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
+void RsdShader::createTexturesString(const char** textureNames, size_t textureNamesCount,
+                                     const size_t *textureNamesLength) {
+    mShaderTextures.setTo("");
+    for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) {
         if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
             Allocation *a = mRSProgram->mHal.state.textures[ct];
             if (a && a->mHal.state.surfaceTextureID) {
-                snprintf(buf, sizeof(buf), "uniform samplerExternalOES UNI_Tex%i;\n", ct);
+                mShaderTextures.append("uniform samplerExternalOES UNI_");
             } else {
-                snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
+                mShaderTextures.append("uniform sampler2D UNI_");
             }
             mTextureTargets[ct] = GL_TEXTURE_2D;
         } else {
-            snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
+            mShaderTextures.append("uniform samplerCube UNI_");
             mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
         }
-        mShader.append(buf);
+
+        mShaderTextures.append(textureNames[ct], textureNamesLength[ct]);
+        mShaderTextures.append(";\n");
     }
 }
 
@@ -161,7 +167,7 @@
     }
     appendUserConstants();
     appendAttributes();
-    appendTextures();
+    mShader.append(mShaderTextures);
 
     mShader.append(mUserShader);
 
@@ -418,7 +424,8 @@
 
         DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv;
         if (drvTex->glTarget != GL_TEXTURE_2D && drvTex->glTarget != GL_TEXTURE_CUBE_MAP) {
-            ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct);
+            ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u",
+                  (uint)this, ct);
             rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
         }
         RSD_CALL_GL(glBindTexture, drvTex->glTarget, drvTex->textureID);
diff --git a/driver/rsdShader.h b/driver/rsdShader.h
index 3f0d6ea..e32145f 100644
--- a/driver/rsdShader.h
+++ b/driver/rsdShader.h
@@ -39,7 +39,9 @@
 public:
 
     RsdShader(const android::renderscript::Program *p, uint32_t type,
-               const char * shaderText, uint32_t shaderLength);
+              const char * shaderText, uint32_t shaderLength,
+              const char** textureNames, size_t textureNamesCount,
+              const size_t *textureNamesLength);
     virtual ~RsdShader();
 
     bool createShader();
@@ -67,19 +69,27 @@
 
     // Applies to vertex and fragment shaders only
     void appendUserConstants();
-    void setupUserConstants(const android::renderscript::Context *rsc, RsdShaderCache *sc, bool isFragment);
-    void initAddUserElement(const android::renderscript::Element *e, android::String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix);
+    void setupUserConstants(const android::renderscript::Context *rsc,
+                            RsdShaderCache *sc, bool isFragment);
+    void initAddUserElement(const android::renderscript::Element *e,
+                            android::String8 *names, uint32_t *arrayLengths,
+                            uint32_t *count, const char *prefix);
     void setupTextures(const android::renderscript::Context *rsc, RsdShaderCache *sc);
-    void setupSampler(const android::renderscript::Context *rsc, const android::renderscript::Sampler *s, const android::renderscript::Allocation *tex);
+    void setupSampler(const android::renderscript::Context *rsc,
+                      const android::renderscript::Sampler *s,
+                      const android::renderscript::Allocation *tex);
 
     void appendAttributes();
     void appendTextures();
+    void createTexturesString(const char** textureNames, size_t textureNamesCount,
+                              const size_t *textureNamesLength);
 
     void initAttribAndUniformArray();
 
     mutable bool mDirty;
     android::String8 mShader;
     android::String8 mUserShader;
+    android::String8 mShaderTextures;
     uint32_t mShaderID;
     uint32_t mType;
 
@@ -93,10 +103,14 @@
 
     int32_t mTextureUniformIndexStart;
 
-    void logUniform(const android::renderscript::Element *field, const float *fd, uint32_t arraySize );
-    void setUniform(const android::renderscript::Context *rsc, const android::renderscript::Element *field, const float *fd, int32_t slot, uint32_t arraySize );
+    void logUniform(const android::renderscript::Element *field,
+                    const float *fd, uint32_t arraySize);
+    void setUniform(const android::renderscript::Context *rsc,
+                    const android::renderscript::Element *field,
+                    const float *fd, int32_t slot, uint32_t arraySize );
     void initMemberVars();
-    void init();
+    void init(const char** textureNames, size_t textureNamesCount,
+              const size_t *textureNamesLength);
 };
 
 #endif //ANDROID_RSD_SHADER_H
diff --git a/rs.spec b/rs.spec
index 6759bc7..dc846aa 100644
--- a/rs.spec
+++ b/rs.spec
@@ -70,167 +70,167 @@
 }
 
 ContextFinish {
-	sync
-	}
+    sync
+    }
 
 ContextBindRootScript {
-	param RsScript sampler
-	}
+    param RsScript sampler
+    }
 
 ContextBindProgramStore {
-	param RsProgramStore pgm
-	}
+    param RsProgramStore pgm
+    }
 
 ContextBindProgramFragment {
-	param RsProgramFragment pgm
-	}
+    param RsProgramFragment pgm
+    }
 
 ContextBindProgramVertex {
-	param RsProgramVertex pgm
-	}
+    param RsProgramVertex pgm
+    }
 
 ContextBindProgramRaster {
-	param RsProgramRaster pgm
-	}
+    param RsProgramRaster pgm
+    }
 
 ContextBindFont {
-	param RsFont pgm
-	}
+    param RsFont pgm
+    }
 
 ContextPause {
-	}
+    }
 
 ContextResume {
-	}
+    }
 
 ContextSetSurface {
-	param uint32_t width
-	param uint32_t height
-	param RsNativeWindow sur
+    param uint32_t width
+    param uint32_t height
+    param RsNativeWindow sur
         sync
-	}
+    }
 
 ContextDump {
-	param int32_t bits
+    param int32_t bits
 }
 
 ContextSetPriority {
-	param int32_t priority
-	}
+    param int32_t priority
+    }
 
 ContextDestroyWorker {
         sync
 }
 
 AssignName {
-	param RsObjectBase obj
-	param const char *name
-	}
+    param RsObjectBase obj
+    param const char *name
+    }
 
 ObjDestroy {
-	param RsAsyncVoidPtr objPtr
-	}
+    param RsAsyncVoidPtr objPtr
+    }
 
 ElementCreate {
         direct
-	param RsDataType mType
-	param RsDataKind mKind
-	param bool mNormalized
-	param uint32_t mVectorSize
-	ret RsElement
-	}
+    param RsDataType mType
+    param RsDataKind mKind
+    param bool mNormalized
+    param uint32_t mVectorSize
+    ret RsElement
+    }
 
 ElementCreate2 {
         direct
-	param const RsElement * elements
-	param const char ** names
-	param const uint32_t * arraySize
-	ret RsElement
-	}
+    param const RsElement * elements
+    param const char ** names
+    param const uint32_t * arraySize
+    ret RsElement
+    }
 
 AllocationCopyToBitmap {
-	param RsAllocation alloc
-	param void * data
-	}
+    param RsAllocation alloc
+    param void * data
+    }
 
 
 Allocation1DData {
-	param RsAllocation va
-	param uint32_t xoff
-	param uint32_t lod
-	param uint32_t count
-	param const void *data
-	}
+    param RsAllocation va
+    param uint32_t xoff
+    param uint32_t lod
+    param uint32_t count
+    param const void *data
+    }
 
 Allocation1DElementData {
-	param RsAllocation va
-	param uint32_t x
-	param uint32_t lod
-	param const void *data
-	param size_t comp_offset
-	}
+    param RsAllocation va
+    param uint32_t x
+    param uint32_t lod
+    param const void *data
+    param size_t comp_offset
+    }
 
 Allocation2DData {
-	param RsAllocation va
-	param uint32_t xoff
-	param uint32_t yoff
-	param uint32_t lod
-	param RsAllocationCubemapFace face
-	param uint32_t w
-	param uint32_t h
-	param const void *data
-	}
+    param RsAllocation va
+    param uint32_t xoff
+    param uint32_t yoff
+    param uint32_t lod
+    param RsAllocationCubemapFace face
+    param uint32_t w
+    param uint32_t h
+    param const void *data
+    }
 
 Allocation2DElementData {
-	param RsAllocation va
-	param uint32_t x
-	param uint32_t y
-	param uint32_t lod
-	param RsAllocationCubemapFace face
-	param const void *data
-	param size_t element_offset
-	}
+    param RsAllocation va
+    param uint32_t x
+    param uint32_t y
+    param uint32_t lod
+    param RsAllocationCubemapFace face
+    param const void *data
+    param size_t element_offset
+    }
 
 AllocationGenerateMipmaps {
-	param RsAllocation va
+    param RsAllocation va
 }
 
 AllocationRead {
-	param RsAllocation va
-	param void * data
-	}
+    param RsAllocation va
+    param void * data
+    }
 
 AllocationSyncAll {
-	param RsAllocation va
-	param RsAllocationUsageType src
+    param RsAllocation va
+    param RsAllocationUsageType src
 }
 
 
 AllocationResize1D {
-	param RsAllocation va
-	param uint32_t dimX
-	}
+    param RsAllocation va
+    param uint32_t dimX
+    }
 
 AllocationResize2D {
-	param RsAllocation va
-	param uint32_t dimX
-	param uint32_t dimY
-	}
+    param RsAllocation va
+    param uint32_t dimX
+    param uint32_t dimY
+    }
 
 AllocationCopy2DRange {
-	param RsAllocation dest
-	param uint32_t destXoff
-	param uint32_t destYoff
-	param uint32_t destMip
-	param uint32_t destFace
-	param uint32_t width
-	param uint32_t height
-	param RsAllocation src
-	param uint32_t srcXoff
-	param uint32_t srcYoff
-	param uint32_t srcMip
-	param uint32_t srcFace
-	}
+    param RsAllocation dest
+    param uint32_t destXoff
+    param uint32_t destYoff
+    param uint32_t destMip
+    param uint32_t destFace
+    param uint32_t width
+    param uint32_t height
+    param RsAllocation src
+    param uint32_t srcXoff
+    param uint32_t srcYoff
+    param uint32_t srcMip
+    param uint32_t srcFace
+    }
 
 SamplerCreate {
     direct
@@ -244,26 +244,26 @@
 }
 
 ScriptBindAllocation {
-	param RsScript vtm
-	param RsAllocation va
-	param uint32_t slot
-	}
+    param RsScript vtm
+    param RsAllocation va
+    param uint32_t slot
+    }
 
 ScriptSetTimeZone {
-	param RsScript s
-	param const char * timeZone
-	}
+    param RsScript s
+    param const char * timeZone
+    }
 
 ScriptInvoke {
-	param RsScript s
-	param uint32_t slot
-	}
+    param RsScript s
+    param uint32_t slot
+    }
 
 ScriptInvokeV {
-	param RsScript s
-	param uint32_t slot
-	param const void * data
-	}
+    param RsScript s
+    param uint32_t slot
+    param const void * data
+    }
 
 ScriptForEach {
     param RsScript s
@@ -274,125 +274,127 @@
 }
 
 ScriptSetVarI {
-	param RsScript s
-	param uint32_t slot
-	param int value
-	}
+    param RsScript s
+    param uint32_t slot
+    param int value
+    }
 
 ScriptSetVarObj {
-	param RsScript s
-	param uint32_t slot
-	param RsObjectBase value
-	}
+    param RsScript s
+    param uint32_t slot
+    param RsObjectBase value
+    }
 
 ScriptSetVarJ {
-	param RsScript s
-	param uint32_t slot
-	param int64_t value
-	}
+    param RsScript s
+    param uint32_t slot
+    param int64_t value
+    }
 
 ScriptSetVarF {
-	param RsScript s
-	param uint32_t slot
-	param float value
-	}
+    param RsScript s
+    param uint32_t slot
+    param float value
+    }
 
 ScriptSetVarD {
-	param RsScript s
-	param uint32_t slot
-	param double value
-	}
+    param RsScript s
+    param uint32_t slot
+    param double value
+    }
 
 ScriptSetVarV {
-	param RsScript s
-	param uint32_t slot
-	param const void * data
-	}
+    param RsScript s
+    param uint32_t slot
+    param const void * data
+    }
 
 
 ScriptCCreate {
         param const char * resName
         param const char * cacheDir
-	param const char * text
-	ret RsScript
-	}
+    param const char * text
+    ret RsScript
+    }
 
 
 ProgramStoreCreate {
-	direct
-	param bool colorMaskR
-	param bool colorMaskG
-	param bool colorMaskB
-	param bool colorMaskA
+    direct
+    param bool colorMaskR
+    param bool colorMaskG
+    param bool colorMaskB
+    param bool colorMaskA
         param bool depthMask
         param bool ditherEnable
-	param RsBlendSrcFunc srcFunc
-	param RsBlendDstFunc destFunc
+    param RsBlendSrcFunc srcFunc
+    param RsBlendDstFunc destFunc
         param RsDepthFunc depthFunc
-	ret RsProgramStore
-	}
+    ret RsProgramStore
+    }
 
 ProgramRasterCreate {
-	direct
-	param bool pointSprite
-	param RsCullMode cull
-	ret RsProgramRaster
+    direct
+    param bool pointSprite
+    param RsCullMode cull
+    ret RsProgramRaster
 }
 
 ProgramBindConstants {
-	param RsProgram vp
-	param uint32_t slot
-	param RsAllocation constants
-	}
+    param RsProgram vp
+    param uint32_t slot
+    param RsAllocation constants
+    }
 
 
 ProgramBindTexture {
-	param RsProgramFragment pf
-	param uint32_t slot
-	param RsAllocation a
-	}
+    param RsProgramFragment pf
+    param uint32_t slot
+    param RsAllocation a
+    }
 
 ProgramBindSampler {
-	param RsProgramFragment pf
-	param uint32_t slot
-	param RsSampler s
-	}
+    param RsProgramFragment pf
+    param uint32_t slot
+    param RsSampler s
+    }
 
 ProgramFragmentCreate {
-	direct
-	param const char * shaderText
-	param const uint32_t * params
-	ret RsProgramFragment
-	}
+    direct
+    param const char * shaderText
+    param const char ** textureNames
+    param const uint32_t * params
+    ret RsProgramFragment
+    }
 
 ProgramVertexCreate {
-	direct
-	param const char * shaderText
-	param const uint32_t * params
-	ret RsProgramVertex
-	}
+    direct
+    param const char * shaderText
+    param const char ** textureNames
+    param const uint32_t * params
+    ret RsProgramVertex
+    }
 
 FontCreateFromFile {
-	param const char *name
-	param float fontSize
-	param uint32_t dpi
-	ret RsFont
-	}
+    param const char *name
+    param float fontSize
+    param uint32_t dpi
+    ret RsFont
+    }
 
 FontCreateFromMemory {
-	param const char *name
-	param float fontSize
-	param uint32_t dpi
-	param const void *data
-	ret RsFont
-	}
+    param const char *name
+    param float fontSize
+    param uint32_t dpi
+    param const void *data
+    ret RsFont
+    }
 
 MeshCreate {
-	param RsAllocation *vtx
-	param RsAllocation *idx
-	param uint32_t *primType
-	ret RsMesh
-	}
+    param RsAllocation *vtx
+    param RsAllocation *idx
+    param uint32_t *primType
+    ret RsMesh
+    }
 
 PathCreate {
     param RsPathPrimitive pp
@@ -402,4 +404,3 @@
     param float quality
     ret RsPath
     }
-
diff --git a/rsFont.cpp b/rsFont.cpp
index 4f21b3b..c4276cf 100644
--- a/rsFont.cpp
+++ b/rsFont.cpp
@@ -490,8 +490,14 @@
     shaderString.append("  gl_FragColor = col;\n");
     shaderString.append("}\n");
 
-    ObjectBaseRef<const Element> colorElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
-    ObjectBaseRef<const Element> gammaElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
+    const char *textureNames[] = { "Tex0" };
+    const size_t textureNamesLengths[] = { 4 };
+    size_t numTextures = sizeof(textureNamesLengths)/sizeof(*textureNamesLengths);
+
+    ObjectBaseRef<const Element> colorElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32,
+                                                                RS_KIND_USER, false, 4);
+    ObjectBaseRef<const Element> gammaElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32,
+                                                                RS_KIND_USER, false, 1);
     Element::Builder builder;
     builder.add(colorElem.get(), "Color", 1);
     builder.add(gammaElem.get(), "Gamma", 1);
@@ -506,14 +512,17 @@
     tmp[3] = RS_TEXTURE_2D;
 
     mFontShaderFConstant.set(Allocation::createAllocation(mRSC, inputType.get(),
-                                            RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS));
-    ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(),
-                                              shaderString.length(), tmp, 4);
+                                                          RS_ALLOCATION_USAGE_SCRIPT |
+                                                          RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS));
+    ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(), shaderString.length(),
+                                              textureNames, numTextures, textureNamesLengths,
+                                              tmp, 4);
     mFontShaderF.set(pf);
     mFontShaderF->bindAllocation(mRSC, mFontShaderFConstant.get(), 0);
 
     mFontSampler.set(Sampler::getSampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST,
-                                         RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP).get());
+                                         RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP,
+                                         RS_SAMPLER_CLAMP).get());
     mFontShaderF->bindSampler(mRSC, 0, mFontSampler.get());
 
     mFontProgramStore.set(ProgramStore::getProgramStore(mRSC, true, true, true, true,
@@ -525,10 +534,12 @@
 }
 
 void FontState::initTextTexture() {
-    ObjectBaseRef<const Element> alphaElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1);
+    ObjectBaseRef<const Element> alphaElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_8,
+                                                                RS_KIND_PIXEL_A, true, 1);
 
     // We will allocate a texture to initially hold 32 character bitmaps
-    ObjectBaseRef<Type> texType = Type::getTypeRef(mRSC, alphaElem.get(), 1024, 256, 0, false, false);
+    ObjectBaseRef<Type> texType = Type::getTypeRef(mRSC, alphaElem.get(),
+                                                   1024, 256, 0, false, false);
 
     Allocation *cacheAlloc = Allocation::createAllocation(mRSC, texType.get(),
                                 RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE);
diff --git a/rsProgram.cpp b/rsProgram.cpp
index 8061515..7114f29 100644
--- a/rsProgram.cpp
+++ b/rsProgram.cpp
@@ -20,8 +20,8 @@
 using namespace android;
 using namespace android::renderscript;
 
-Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
-                 const uint32_t * params, uint32_t paramLength)
+Program::Program(Context *rsc, const char * shaderText, size_t shaderLength,
+                 const uint32_t * params, size_t paramLength)
     : ProgramBase(rsc) {
 
     initMemberVars();
diff --git a/rsProgram.h b/rsProgram.h
index 06fc3ec..d032930 100644
--- a/rsProgram.h
+++ b/rsProgram.h
@@ -58,8 +58,8 @@
     };
     Hal mHal;
 
-    Program(Context *, const char * shaderText, uint32_t shaderLength,
-                       const uint32_t * params, uint32_t paramLength);
+    Program(Context *, const char * shaderText, size_t shaderLength,
+            const uint32_t * params, size_t paramLength);
     virtual ~Program();
     virtual bool freeChildren();
 
diff --git a/rsProgramFragment.cpp b/rsProgramFragment.cpp
index 4e73ca6..bebde1e 100644
--- a/rsProgramFragment.cpp
+++ b/rsProgramFragment.cpp
@@ -20,16 +20,18 @@
 using namespace android;
 using namespace android::renderscript;
 
-ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
-                                 uint32_t shaderLength, const uint32_t * params,
-                                 uint32_t paramLength)
+ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, size_t shaderLength,
+                                 const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength,
+
+                                 const uint32_t * params, size_t paramLength)
     : Program(rsc, shaderText, shaderLength, params, paramLength) {
     mConstantColor[0] = 1.f;
     mConstantColor[1] = 1.f;
     mConstantColor[2] = 1.f;
     mConstantColor[3] = 1.f;
 
-    mRSC->mHal.funcs.fragment.init(mRSC, this, mUserShader.string(), mUserShader.length());
+    mRSC->mHal.funcs.fragment.init(mRSC, this, mUserShader.string(), mUserShader.length(),
+                                   textureNames, textureNamesCount, textureNamesLength);
 }
 
 ProgramFragment::~ProgramFragment() {
@@ -110,8 +112,8 @@
 
     Allocation *constAlloc = Allocation::createAllocation(rsc, inputType.get(),
                               RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS);
-    ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(),
-                                              shaderString.length(), tmp, 2);
+    ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(), shaderString.length(),
+                                              NULL, 0, NULL, tmp, 2);
     pf->bindAllocation(rsc, constAlloc, 0);
     pf->setConstantColor(rsc, 1.0f, 1.0f, 1.0f, 1.0f);
 
@@ -127,9 +129,14 @@
 namespace renderscript {
 
 RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, const char * shaderText,
-                             size_t shaderLength, const uint32_t * params,
-                             size_t paramLength) {
-    ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
+                                            size_t shaderLength,
+                                            const char** textureNames,
+                                            size_t textureNamesCount,
+                                            const size_t *textureNamesLength,
+                                            const uint32_t * params, size_t paramLength) {
+    ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength,
+                                              textureNames, textureNamesCount, textureNamesLength,
+                                              params, paramLength);
     pf->incUserRef();
     //ALOGE("rsi_ProgramFragmentCreate %p", pf);
     return pf;
diff --git a/rsProgramFragment.h b/rsProgramFragment.h
index d6e20cd..4eb28e7 100644
--- a/rsProgramFragment.h
+++ b/rsProgramFragment.h
@@ -27,9 +27,9 @@
 
 class ProgramFragment : public Program {
 public:
-    ProgramFragment(Context *rsc, const char * shaderText,
-                             uint32_t shaderLength, const uint32_t * params,
-                             uint32_t paramLength);
+    ProgramFragment(Context *rsc, const char * shaderText, size_t shaderLength,
+                    const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength,
+                     const uint32_t * params, size_t paramLength);
     virtual ~ProgramFragment();
 
     virtual void setup(Context *, ProgramFragmentState *);
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
index 871caac..c8a53ea 100644
--- a/rsProgramVertex.cpp
+++ b/rsProgramVertex.cpp
@@ -21,11 +21,13 @@
 using namespace android::renderscript;
 
 
-ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText,
-                             uint32_t shaderLength, const uint32_t * params,
-                             uint32_t paramLength)
+ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText, size_t shaderLength,
+                             const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength,
+
+                             const uint32_t * params, size_t paramLength)
     : Program(rsc, shaderText, shaderLength, params, paramLength) {
-    mRSC->mHal.funcs.vertex.init(mRSC, this, mUserShader.string(), mUserShader.length());
+    mRSC->mHal.funcs.vertex.init(mRSC, this, mUserShader.string(), mUserShader.length(),
+                                 textureNames, textureNamesCount, textureNamesLength);
 }
 
 ProgramVertex::~ProgramVertex() {
@@ -191,8 +193,8 @@
     tmp[2] = RS_PROGRAM_PARAM_INPUT;
     tmp[3] = (uint32_t)attrElem.get();
 
-    ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(),
-                                          shaderString.length(), tmp, 4);
+    ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(), shaderString.length(),
+                                          NULL, 0, NULL, tmp, 4);
     Allocation *alloc = Allocation::createAllocation(rsc, inputType.get(),
                               RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS);
     pv->bindAllocation(rsc, alloc, 0);
@@ -229,10 +231,13 @@
 namespace android {
 namespace renderscript {
 
-RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, const char * shaderText,
-                             size_t shaderLength, const uint32_t * params,
-                             size_t paramLength) {
-    ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength);
+RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, const char * shaderText, size_t shaderLength,
+                                        const char** textureNames, size_t textureNamesCount,
+                                        const size_t *textureNamesLength,
+                                        const uint32_t * params, size_t paramLength) {
+    ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength,
+                                          textureNames, textureNamesCount, textureNamesLength,
+                                          params, paramLength);
     pv->incUserRef();
     return pv;
 }
diff --git a/rsProgramVertex.h b/rsProgramVertex.h
index 5cfdd8b..67c2a88 100644
--- a/rsProgramVertex.h
+++ b/rsProgramVertex.h
@@ -27,8 +27,9 @@
 
 class ProgramVertex : public Program {
 public:
-    ProgramVertex(Context *,const char * shaderText, uint32_t shaderLength,
-                  const uint32_t * params, uint32_t paramLength);
+    ProgramVertex(Context *,const char * shaderText, size_t shaderLength,
+                  const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength,
+                  const uint32_t * params, size_t paramLength);
     virtual ~ProgramVertex();
 
     virtual void setup(Context *rsc, ProgramVertexState *state);
diff --git a/rs_hal.h b/rs_hal.h
index 7c9618a..800053a 100644
--- a/rs_hal.h
+++ b/rs_hal.h
@@ -172,14 +172,18 @@
 
     struct {
         bool (*init)(const Context *rsc, const ProgramVertex *pv,
-                     const char* shader, size_t shaderLen);
+                     const char* shader, size_t shaderLen,
+                     const char** textureNames, size_t textureNamesCount,
+                     const size_t *textureNamesLength);
         void (*setActive)(const Context *rsc, const ProgramVertex *pv);
         void (*destroy)(const Context *rsc, const ProgramVertex *pv);
     } vertex;
 
     struct {
         bool (*init)(const Context *rsc, const ProgramFragment *pf,
-                     const char* shader, size_t shaderLen);
+                     const char* shader, size_t shaderLen,
+                     const char** textureNames, size_t textureNamesCount,
+                     const size_t *textureNamesLength);
         void (*setActive)(const Context *rsc, const ProgramFragment *pf);
         void (*destroy)(const Context *rsc, const ProgramFragment *pf);
     } fragment;