Beging GL2 user shaders.  Switch master to using GL2 by default.
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index 392d93d..f8625e8 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -69,6 +69,7 @@
         Element mIn;
         Element mOut;
         boolean mPointSpriteEnable;
+        String mShader;
 
         private class Slot {
             Type mType;
@@ -92,6 +93,10 @@
             }
         }
 
+        public void setShader(String s) {
+            mShader = s;
+        }
+
         public void setType(int slot, Type t)
             throws IllegalArgumentException {
             if((slot < 0) || (slot >= MAX_SLOT)) {
@@ -144,6 +149,10 @@
                 }
             }
 
+            if (b.mShader != null) {
+                rs.nProgramFragmentSetShader(b.mShader);
+            }
+
             int id = rs.nProgramFragmentCreate();
             return new ProgramFragment(id, rs);
         }
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index ddb23ac..8a22138 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -45,6 +45,7 @@
         Light[] mLights;
         int mLightCount;
         boolean mTextureMatrixEnable;
+        String mShader;
 
 
         public Builder(RenderScript rs, Element in, Element out) {
@@ -59,6 +60,10 @@
             mTextureMatrixEnable = enable;
         }
 
+        public void setShader(String s) {
+            mShader = s;
+        }
+
         public void addLight(Light l) throws IllegalStateException {
             if(mLightCount >= MAX_LIGHT) {
                 throw new IllegalArgumentException("Max light count exceeded.");
@@ -79,10 +84,14 @@
                 outID = b.mOut.mID;
             }
             rs.nProgramVertexBegin(inID, outID);
-            for(int ct=0; ct < b.mLightCount; ct++) {
-                rs.nProgramVertexAddLight(b.mLights[ct].mID);
+            if (b.mShader != null) {
+                rs.nProgramVertexSetShader(b.mShader);
+            } else {
+                for(int ct=0; ct < b.mLightCount; ct++) {
+                    rs.nProgramVertexAddLight(b.mLights[ct].mID);
+                }
+                rs.nProgramVertexSetTextureMatrixEnable(b.mTextureMatrixEnable);
             }
-            rs.nProgramVertexSetTextureMatrixEnable(b.mTextureMatrixEnable);
             int id = rs.nProgramVertexCreate();
             return new ProgramVertex(id, rs);
         }
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index c42f647..22bfa69 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -171,12 +171,14 @@
     native void nProgramFragmentBindTexture(int vpf, int slot, int a);
     native void nProgramFragmentBindSampler(int vpf, int slot, int s);
     native void nProgramFragmentSetSlot(int slot, boolean enable, int env, int vt);
+    native void nProgramFragmentSetShader(String txt);
     native int  nProgramFragmentCreate();
 
     native void nProgramVertexBindAllocation(int pv, int mID);
     native void nProgramVertexBegin(int inID, int outID);
     native void nProgramVertexSetTextureMatrixEnable(boolean enable);
     native void nProgramVertexAddLight(int id);
+    native void nProgramVertexSetShader(String txt);
     native int  nProgramVertexCreate();
 
     native void nLightBegin();
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index af3bc74..ea5feb8 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -1053,9 +1053,20 @@
     return (jint)rsProgramFragmentStoreCreate(con);
 }
 
+
 // ---------------------------------------------------------------------------
 
 static void
+nProgramFragmentSetShader(JNIEnv *_env, jobject _this, jstring name)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    const char* n = _env->GetStringUTFChars(name, NULL);
+    LOG_API("nProgramFragmentSetShader, con(%p)", con);
+    rsProgramFragmentSetShader(con, n, _env->GetStringUTFLength(name));
+    _env->ReleaseStringUTFChars(name, n);
+}
+
+static void
 nProgramFragmentBegin(JNIEnv *_env, jobject _this, jint in, jint out, jboolean pointSpriteEnable)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
@@ -1098,6 +1109,17 @@
 // ---------------------------------------------------------------------------
 
 static void
+nProgramVertexSetShader(JNIEnv *_env, jobject _this, jstring name)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    const char* n = _env->GetStringUTFChars(name, NULL);
+    LOG_API("nProgramVertexSetShader, con(%p)", con);
+    rsProgramVertexSetShader(con, n, _env->GetStringUTFLength(name));
+    _env->ReleaseStringUTFChars(name, n);
+}
+
+
+static void
 nProgramVertexBegin(JNIEnv *_env, jobject _this, jint in, jint out)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
@@ -1436,6 +1458,7 @@
 {"nProgramFragmentBindTexture",    "(III)V",                               (void*)nProgramFragmentBindTexture },
 {"nProgramFragmentBindSampler",    "(III)V",                               (void*)nProgramFragmentBindSampler },
 {"nProgramFragmentSetSlot",        "(IZII)V",                              (void*)nProgramFragmentSetSlot },
+{"nProgramFragmentSetShader",      "(Ljava/lang/String;)V",                (void*)nProgramFragmentSetShader },
 {"nProgramFragmentCreate",         "()I",                                  (void*)nProgramFragmentCreate },
 
 {"nProgramRasterCreate",           "(IIZZZ)I",                             (void*)nProgramRasterCreate },
@@ -1446,6 +1469,7 @@
 {"nProgramVertexBegin",            "(II)V",                                (void*)nProgramVertexBegin },
 {"nProgramVertexSetTextureMatrixEnable",   "(Z)V",                         (void*)nProgramVertexSetTextureMatrixEnable },
 {"nProgramVertexAddLight",         "(I)V",                                 (void*)nProgramVertexAddLight },
+{"nProgramVertexSetShader",        "(Ljava/lang/String;)V",                (void*)nProgramVertexSetShader },
 {"nProgramVertexCreate",           "()I",                                  (void*)nProgramVertexCreate },
 
 {"nLightBegin",                    "()V",                                  (void*)nLightBegin },
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index a4e72d9..c7ae18a 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -372,6 +372,11 @@
 	param bool pointSpriteEnable
 	}
 
+ProgramFragmentSetShader {
+	param const char * text
+	param uint32_t length
+	}
+
 ProgramFragmentBindTexture {
 	param RsProgramFragment pf
 	param uint32_t slot
@@ -414,6 +419,11 @@
 	param bool enable
 	}
 
+ProgramVertexSetShader {
+	param const char * text
+	param uint32_t length
+	}
+
 ProgramVertexAddLight {
 	param RsLight light
 	}
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 427a6cc..3d2caff 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -467,7 +467,7 @@
         if (!mEGL.mContext) {
             first = true;
             pthread_mutex_lock(&gInitMutex);
-            initEGL(false);
+            initEGL(true);
             pthread_mutex_unlock(&gInitMutex);
         }
 
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index 8e9ba08..db40f16 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -67,7 +67,7 @@
     mShaderID = glCreateShader(type);
     rsAssert(mShaderID);
 
-    LOGV("Loading shader type %x", type);
+    LOGV("Loading shader type %x, ID %i", type, mShaderID);
     LOGE(mShader.string());
 
     if (mShaderID) {
@@ -96,3 +96,9 @@
     LOGV("--Shader load result %x ", glGetError());
     return true;
 }
+
+void Program::setShader(const char *txt, uint32_t len)
+{
+    mUserShader.setTo(txt, len);
+}
+
diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h
index 06c72f9..abd461b 100644
--- a/libs/rs/rsProgram.h
+++ b/libs/rs/rsProgram.h
@@ -40,6 +40,7 @@
     virtual void createShader();
 
     uint32_t getShaderID() const {return mShaderID;}
+    void setShader(const char *, uint32_t len);
 
     uint32_t getAttribCount() const {return mAttribCount;}
     uint32_t getUniformCount() const {return mUniformCount;}
@@ -56,6 +57,7 @@
 
     mutable bool mDirty;
     String8 mShader;
+    String8 mUserShader;
     uint32_t mShaderID;
 
     uint32_t mAttribCount;
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index daefc2c..b239ce8 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -175,19 +175,27 @@
     //mShader.append("  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n");
     mShader.append("  vec4 col = varColor;\n");
 
+    if (mTextureEnableMask) {
+        if (mPointSpriteEnable) {
+            mShader.append("  vec2 tex0 = gl_PointCoord;\n");
+        } else {
+            mShader.append("  vec2 tex0 = varTex0.xy;\n");
+        }
+    }
+
     mask = mTextureEnableMask;
     texNum = 0;
     while (mask) {
         if (mask & 1) {
             switch(mEnvModes[texNum]) {
             case RS_TEX_ENV_MODE_REPLACE:
-                mShader.append("  col = texture2D(uni_Tex0, varTex0.xy);\n");
+                mShader.append("  col = texture2D(uni_Tex0, tex0);\n");
                 break;
             case RS_TEX_ENV_MODE_MODULATE:
-                mShader.append("  col *= texture2D(uni_Tex0, varTex0.xy);\n");
+                mShader.append("  col *= texture2D(uni_Tex0, tex0);\n");
                 break;
             case RS_TEX_ENV_MODE_DECAL:
-                mShader.append("  col = texture2D(uni_Tex0, varTex0.xy);\n");
+                mShader.append("  col = texture2D(uni_Tex0, tex0);\n");
                 break;
             }
 
@@ -338,6 +346,11 @@
     rsc->mStateFragment.mPF->setTexEnable(slot, enable);
 }
 
+void rsi_ProgramFragmentSetShader(Context *rsc, const char *txt, uint32_t len)
+{
+    rsc->mStateFragment.mPF->setShader(txt, len);
+}
+
 RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
 {
     ProgramFragment *pf = rsc->mStateFragment.mPF;
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 1776b02b..482739c 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -117,18 +117,24 @@
     mShader.append("varying vec4 varColor;\n");
     mShader.append("varying vec4 varTex0;\n");
 
-    mShader.append("void main() {\n");
-    mShader.append("  gl_Position = uni_MVP * attrib_Position;\n");
-    mShader.append("  varColor = attrib_Color;\n");
-    if (mTextureMatrixEnable) {
-        mShader.append("  varTex0 = uni_TexMatrix * attrib_T0;\n");
+    if (mUserShader.length() > 1) {
+        mShader.append(mUserShader);
     } else {
-        mShader.append("  varTex0 = attrib_T0;\n");
+        mShader.append("void main() {\n");
+        mShader.append("  gl_Position = uni_MVP * attrib_Position;\n");
+        mShader.append("  gl_PointSize = attrib_PointSize.x;\n");
+
+        mShader.append("  varColor = attrib_Color;\n");
+        if (mTextureMatrixEnable) {
+            mShader.append("  varTex0 = uni_TexMatrix * attrib_T0;\n");
+        } else {
+            mShader.append("  varTex0 = attrib_T0;\n");
+        }
+        //mShader.append("  pos.x = pos.x / 480.0;\n");
+        //mShader.append("  pos.y = pos.y / 800.0;\n");
+        //mShader.append("  gl_Position = pos;\n");
+        mShader.append("}\n");
     }
-    //mShader.append("  pos.x = pos.x / 480.0;\n");
-    //mShader.append("  pos.y = pos.y / 800.0;\n");
-    //mShader.append("  gl_Position = pos;\n");
-    mShader.append("}\n");
 }
 
 void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, ShaderCache *sc)
@@ -211,7 +217,6 @@
     createShader();
 }
 
-
 ///////////////////////////////////////////////////////////////////////
 
 ProgramVertexState::ProgramVertexState()
@@ -294,6 +299,11 @@
     rsc->mStateVertex.mPV->setTextureMatrixEnable(enable);
 }
 
+void rsi_ProgramVertexSetShader(Context *rsc, const char *txt, uint32_t len)
+{
+    rsc->mStateVertex.mPV->setShader(txt, len);
+}
+
 void rsi_ProgramVertexAddLight(Context *rsc, RsLight light)
 {
     rsc->mStateVertex.mPV->addLight(static_cast<const Light *>(light));
diff --git a/libs/rs/rsShaderCache.cpp b/libs/rs/rsShaderCache.cpp
index 2727e6c..4b16677 100644
--- a/libs/rs/rsShaderCache.cpp
+++ b/libs/rs/rsShaderCache.cpp
@@ -49,6 +49,7 @@
     if (!frag->getShaderID()) {
         frag->loadShader();
     }
+    //LOGV("ShaderCache lookup  vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
 
     for (uint32_t ct=0; ct < mEntryCount; ct++) {
         if ((mEntries[ct].vtx == vtx->getShaderID()) &&
@@ -57,6 +58,7 @@
             //LOGV("SC using program %i", mEntries[ct].program);
             glUseProgram(mEntries[ct].program);
             mCurrent = &mEntries[ct];
+            //LOGV("ShaderCache hit, using %i", ct);
             return true;
         }
     }
@@ -75,8 +77,8 @@
         mEntries = e;
     }
 
-    LOGV("vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
-    LOGE("e0 %x", glGetError());
+    //LOGV("ShaderCache miss, using %i", mEntryCount);
+    //LOGE("e0 %x", glGetError());
 
     entry_t *e = &mEntries[mEntryCount];
     mCurrent = e;
@@ -125,7 +127,7 @@
         }
     }
 
-    LOGV("SC made program %i", e->program);
+    //LOGV("SC made program %i", e->program);
     glUseProgram(e->program);
     mEntryCount++;
     return true;