Merge "More work on the renderscript sample"
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index 08065cf..fd89b6e 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -67,17 +67,46 @@
         mRS.nProgramRasterSetCullMode(mID, m.mID);
     }
 
+    public static ProgramRaster CULL_BACK(RenderScript rs) {
+        if(rs.mProgramRaster_CULL_BACK == null) {
+            ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
+            builder.setCullMode(CullMode.BACK);
+            rs.mProgramRaster_CULL_BACK = builder.create();
+        }
+        return rs.mProgramRaster_CULL_BACK;
+    }
+
+    public static ProgramRaster CULL_FRONT(RenderScript rs) {
+        if(rs.mProgramRaster_CULL_FRONT == null) {
+            ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
+            builder.setCullMode(CullMode.FRONT);
+            rs.mProgramRaster_CULL_FRONT = builder.create();
+        }
+        return rs.mProgramRaster_CULL_FRONT;
+    }
+
+    public static ProgramRaster CULL_NONE(RenderScript rs) {
+        if(rs.mProgramRaster_CULL_NONE == null) {
+            ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
+            builder.setCullMode(CullMode.NONE);
+            rs.mProgramRaster_CULL_NONE = builder.create();
+        }
+        return rs.mProgramRaster_CULL_NONE;
+    }
+
     public static class Builder {
         RenderScript mRS;
         boolean mPointSprite;
         boolean mPointSmooth;
         boolean mLineSmooth;
+        CullMode mCullMode;
 
         public Builder(RenderScript rs) {
             mRS = rs;
             mPointSmooth = false;
             mLineSmooth = false;
             mPointSprite = false;
+            mCullMode = CullMode.BACK;
         }
 
         public Builder setPointSpriteEnable(boolean enable) {
@@ -95,9 +124,15 @@
             return this;
         }
 
+        public Builder setCullMode(CullMode m) {
+            mCullMode = m;
+            return this;
+        }
+
         static synchronized ProgramRaster internalCreate(RenderScript rs, Builder b) {
             int id = rs.nProgramRasterCreate(b.mPointSmooth, b.mLineSmooth, b.mPointSprite);
             ProgramRaster pr = new ProgramRaster(id, rs);
+            pr.setCullMode(b.mCullMode);
             return pr;
         }
 
diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java
index e249842..32c0d01 100644
--- a/graphics/java/android/renderscript/ProgramStore.java
+++ b/graphics/java/android/renderscript/ProgramStore.java
@@ -79,139 +79,139 @@
         super(id, rs);
     }
 
-    public static ProgramStore BlendNone_DepthTest(RenderScript rs) {
-        if(rs.mProgramStore_BlendNone_DepthTest == null) {
+    public static ProgramStore BLEND_NONE_DEPTH_TEST(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_NONE_DEPTH_TEST == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
             builder.setDitherEnable(false);
             builder.setDepthMask(true);
-            rs.mProgramStore_BlendNone_DepthTest = builder.create();
+            rs.mProgramStore_BLEND_NONE_DEPTH_TEST = builder.create();
         }
-        return rs.mProgramStore_BlendNone_DepthTest;
+        return rs.mProgramStore_BLEND_NONE_DEPTH_TEST;
     }
-    public static ProgramStore BlendNone_DepthNoDepth(RenderScript rs) {
-        if(rs.mProgramStore_BlendNone_DepthNoDepth == null) {
+    public static ProgramStore BLEND_NONE_DEPTH_NO_DEPTH(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
             builder.setDitherEnable(false);
             builder.setDepthMask(false);
-            rs.mProgramStore_BlendNone_DepthNoDepth = builder.create();
+            rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH = builder.create();
         }
-        return rs.mProgramStore_BlendNone_DepthNoDepth;
+        return rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
     }
-    public static ProgramStore BlendNone_DepthNoTest(RenderScript rs) {
-        if(rs.mProgramStore_BlendNone_DepthNoTest == null) {
+    public static ProgramStore BLEND_NONE_DEPTH_NO_TEST(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_TEST == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
             builder.setDitherEnable(false);
             builder.setDepthMask(true);
-            rs.mProgramStore_BlendNone_DepthNoTest = builder.create();
+            rs.mProgramStore_BLEND_NONE_DEPTH_NO_TEST = builder.create();
         }
-        return rs.mProgramStore_BlendNone_DepthNoTest;
+        return rs.mProgramStore_BLEND_NONE_DEPTH_NO_TEST;
     }
-    public static ProgramStore BlendNone_DepthNoWrite(RenderScript rs) {
-        if(rs.mProgramStore_BlendNone_DepthNoWrite == null) {
+    public static ProgramStore BLEND_NONE_DEPTH_NO_WRITE(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_WRITE == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
             builder.setDitherEnable(false);
             builder.setDepthMask(false);
-            rs.mProgramStore_BlendNone_DepthNoWrite = builder.create();
+            rs.mProgramStore_BLEND_NONE_DEPTH_NO_WRITE = builder.create();
         }
-        return rs.mProgramStore_BlendNone_DepthNoWrite;
+        return rs.mProgramStore_BLEND_NONE_DEPTH_NO_WRITE;
     }
 
-    public static ProgramStore BlendAlpha_DepthTest(RenderScript rs) {
-        if(rs.mProgramStore_BlendAlpha_DepthTest == null) {
+    public static ProgramStore BLEND_ALPHA_DEPTH_TEST(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
             builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
             builder.setDitherEnable(false);
             builder.setDepthMask(true);
-            rs.mProgramStore_BlendAlpha_DepthTest = builder.create();
+            rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST = builder.create();
         }
-        return rs.mProgramStore_BlendAlpha_DepthTest;
+        return rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST;
     }
-    public static ProgramStore BlendAlpha_DepthNoDepth(RenderScript rs) {
-        if(rs.mProgramStore_BlendAlpha_DepthNoDepth == null) {
+    public static ProgramStore BLEND_ALPHA_DEPTH_NO_DEPTH(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
             builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
             builder.setDitherEnable(false);
             builder.setDepthMask(false);
-            rs.mProgramStore_BlendAlpha_DepthNoDepth = builder.create();
+            rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH = builder.create();
         }
-        return rs.mProgramStore_BlendAlpha_DepthNoDepth;
+        return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
     }
-    public static ProgramStore BlendAlpha_DepthNoTest(RenderScript rs) {
-        if(rs.mProgramStore_BlendAlpha_DepthNoTest == null) {
+    public static ProgramStore BLEND_ALPHA_DEPTH_NO_TEST(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
             builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
             builder.setDitherEnable(false);
             builder.setDepthMask(true);
-            rs.mProgramStore_BlendAlpha_DepthNoTest = builder.create();
+            rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST = builder.create();
         }
-        return rs.mProgramStore_BlendAlpha_DepthNoTest;
+        return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST;
     }
-    public static ProgramStore BlendAlpha_DepthNoWrite(RenderScript rs) {
-        if(rs.mProgramStore_BlendAlpha_DepthNoWrite == null) {
+    public static ProgramStore BLEND_ALPHA_DEPTH_NO_WRITE(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
             builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
             builder.setDitherEnable(false);
             builder.setDepthMask(false);
-            rs.mProgramStore_BlendAlpha_DepthNoWrite = builder.create();
+            rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE = builder.create();
         }
-        return rs.mProgramStore_BlendAlpha_DepthNoWrite;
+        return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE;
     }
 
-    public static ProgramStore BlendAdd_DepthTest(RenderScript rs) {
-        if(rs.mProgramStore_BlendAdd_DepthTest == null) {
+    public static ProgramStore BLEND_ADD_DEPTH_TEST(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_ADD_DEPTH_TEST == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
             builder.setDitherEnable(false);
             builder.setDepthMask(true);
-            rs.mProgramStore_BlendAdd_DepthTest = builder.create();
+            rs.mProgramStore_BLEND_ADD_DEPTH_TEST = builder.create();
         }
-        return rs.mProgramStore_BlendAdd_DepthTest;
+        return rs.mProgramStore_BLEND_ADD_DEPTH_TEST;
     }
-    public static ProgramStore BlendAdd_DepthNoDepth(RenderScript rs) {
-        if(rs.mProgramStore_BlendAdd_DepthNoDepth == null) {
+    public static ProgramStore BLEND_ADD_DEPTH_NO_DEPTH(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
             builder.setDitherEnable(false);
             builder.setDepthMask(false);
-            rs.mProgramStore_BlendAdd_DepthNoDepth = builder.create();
+            rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH = builder.create();
         }
-        return rs.mProgramStore_BlendAdd_DepthNoDepth;
+        return rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH;
     }
-    public static ProgramStore BlendAdd_DepthNoTest(RenderScript rs) {
-        if(rs.mProgramStore_BlendAdd_DepthNoTest == null) {
+    public static ProgramStore BLEND_ADD_DEPTH_NO_TEST(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_ADD_DEPTH_NO_TEST == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
             builder.setDitherEnable(false);
             builder.setDepthMask(true);
-            rs.mProgramStore_BlendAdd_DepthNoDepth = builder.create();
+            rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH = builder.create();
         }
-        return rs.mProgramStore_BlendAdd_DepthNoTest;
+        return rs.mProgramStore_BLEND_ADD_DEPTH_NO_TEST;
     }
-    public static ProgramStore BlendAdd_DepthNoWrite(RenderScript rs) {
-        if(rs.mProgramStore_BlendAdd_DepthNoWrite == null) {
+    public static ProgramStore BLEND_ADD_DEPTH_NO_WRITE(RenderScript rs) {
+        if(rs.mProgramStore_BLEND_ADD_DEPTH_NO_WRITE == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
             builder.setDitherEnable(false);
             builder.setDepthMask(false);
-            rs.mProgramStore_BlendAdd_DepthNoWrite = builder.create();
+            rs.mProgramStore_BLEND_ADD_DEPTH_NO_WRITE = builder.create();
         }
-        return rs.mProgramStore_BlendAdd_DepthNoWrite;
+        return rs.mProgramStore_BLEND_ADD_DEPTH_NO_WRITE;
     }
 
     public static class Builder {
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 37c01f5..ab1d765 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -549,19 +549,22 @@
     Sampler mSampler_WRAP_LINEAR;
     Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
 
-    ProgramStore mProgramStore_BlendNone_DepthTest;
-    ProgramStore mProgramStore_BlendNone_DepthNoDepth;
-    ProgramStore mProgramStore_BlendNone_DepthNoTest;
-    ProgramStore mProgramStore_BlendNone_DepthNoWrite;
-    ProgramStore mProgramStore_BlendAlpha_DepthTest;
-    ProgramStore mProgramStore_BlendAlpha_DepthNoDepth;
-    ProgramStore mProgramStore_BlendAlpha_DepthNoTest;
-    ProgramStore mProgramStore_BlendAlpha_DepthNoWrite;
-    ProgramStore mProgramStore_BlendAdd_DepthTest;
-    ProgramStore mProgramStore_BlendAdd_DepthNoDepth;
-    ProgramStore mProgramStore_BlendAdd_DepthNoTest;
-    ProgramStore mProgramStore_BlendAdd_DepthNoWrite;
+    ProgramStore mProgramStore_BLEND_NONE_DEPTH_TEST;
+    ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
+    ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_TEST;
+    ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_WRITE;
+    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_TEST;
+    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
+    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST;
+    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE;
+    ProgramStore mProgramStore_BLEND_ADD_DEPTH_TEST;
+    ProgramStore mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH;
+    ProgramStore mProgramStore_BLEND_ADD_DEPTH_NO_TEST;
+    ProgramStore mProgramStore_BLEND_ADD_DEPTH_NO_WRITE;
 
+    ProgramRaster mProgramRaster_CULL_BACK;
+    ProgramRaster mProgramRaster_CULL_FRONT;
+    ProgramRaster mProgramRaster_CULL_NONE;
 
     ///////////////////////////////////////////////////////////////////////////////////
     //
diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java
index ccd46bd..343fcdb 100644
--- a/graphics/java/android/renderscript/Sampler.java
+++ b/graphics/java/android/renderscript/Sampler.java
@@ -78,7 +78,7 @@
         if(rs.mSampler_CLAMP_LINEAR_MIP_LINEAR == null) {
             Builder b = new Builder(rs);
             b.setMin(Value.LINEAR_MIP_LINEAR);
-            b.setMag(Value.LINEAR_MIP_LINEAR);
+            b.setMag(Value.LINEAR);
             b.setWrapS(Value.CLAMP);
             b.setWrapT(Value.CLAMP);
             rs.mSampler_CLAMP_LINEAR_MIP_LINEAR = b.create();
@@ -114,7 +114,7 @@
         if(rs.mSampler_WRAP_LINEAR_MIP_LINEAR == null) {
             Builder b = new Builder(rs);
             b.setMin(Value.LINEAR_MIP_LINEAR);
-            b.setMag(Value.LINEAR_MIP_LINEAR);
+            b.setMag(Value.LINEAR);
             b.setWrapS(Value.WRAP);
             b.setWrapT(Value.WRAP);
             rs.mSampler_WRAP_LINEAR_MIP_LINEAR = b.create();
diff --git a/libs/rs/java/Samples/res/drawable/torusmap.png b/libs/rs/java/Samples/res/drawable/torusmap.png
new file mode 100644
index 0000000..1e08f3b
--- /dev/null
+++ b/libs/rs/java/Samples/res/drawable/torusmap.png
Binary files differ
diff --git a/libs/rs/java/Samples/res/raw/torus.a3d b/libs/rs/java/Samples/res/raw/torus.a3d
new file mode 100644
index 0000000..610f095
--- /dev/null
+++ b/libs/rs/java/Samples/res/raw/torus.a3d
Binary files differ
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
index 5a6ff23..8eff455 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
@@ -42,30 +42,40 @@
         mOptionsARGB.inScaled = false;
         mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
         mMode = 0;
-        mMaxModes = 4;
+        mMaxModes = 7;
         initRS();
     }
 
     private Resources mRes;
     private RenderScriptGL mRS;
 
-    private Sampler mSampler;
+    private Sampler mLinearClamp;
+    private Sampler mLinearWrap;
+    private Sampler mMipLinearWrap;
+    private Sampler mNearestClamp;
 
+    private ProgramStore mProgStoreBlendNoneDepth;
     private ProgramStore mProgStoreBlendNone;
     private ProgramStore mProgStoreBlendAlpha;
     private ProgramStore mProgStoreBlendAdd;
 
     private ProgramFragment mProgFragmentTexture;
     private ProgramFragment mProgFragmentColor;
+
     private ProgramVertex mProgVertex;
     private ProgramVertex.MatrixAllocation mPVA;
 
+    private ProgramRaster mCullBack;
+    private ProgramRaster mCullFront;
+
+    private Allocation mTexTorus;
     private Allocation mTexOpaque;
     private Allocation mTexTransparent;
 
     private Allocation mAllocPV;
 
     private Mesh mMbyNMesh;
+    private Mesh mTorus;
 
     Font mFontSans;
     Font mFontSerif;
@@ -89,10 +99,40 @@
         mScript.set_gDisplayMode(mMode);
     }
 
+    private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) {
+
+        Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
+                                           2, Mesh.TriangleMeshBuilder.TEXTURE_0);
+
+        for (int y = 0; y <= hResolution; y++) {
+            final float normalizedY = (float)y / hResolution;
+            final float yOffset = (normalizedY - 0.5f) * height;
+            for (int x = 0; x <= wResolution; x++) {
+                float normalizedX = (float)x / wResolution;
+                float xOffset = (normalizedX - 0.5f) * width;
+                tmb.setTexture(normalizedX, normalizedY);
+                tmb.addVertex(xOffset, yOffset);
+             }
+        }
+
+        for (int y = 0; y < hResolution; y++) {
+            final int curY = y * (wResolution + 1);
+            final int belowY = (y + 1) * (wResolution + 1);
+            for (int x = 0; x < wResolution; x++) {
+                int curV = curY + x;
+                int belowV = belowY + x;
+                tmb.addTriangle(curV, belowV, curV + 1);
+                tmb.addTriangle(belowV, belowV + 1, curV + 1);
+            }
+        }
+
+        return tmb.create(true);
+    }
 
     private void initProgramStore() {
         // Use stock the stock program store object
-        mProgStoreBlendNone = ProgramStore.BlendNone_DepthNoDepth(mRS);
+        mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS);
+        mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NO_DEPTH(mRS);
 
         // Create a custom program store
         ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
@@ -103,8 +143,9 @@
         builder.setDepthMask(false);
         mProgStoreBlendAlpha = builder.create();
 
-        mProgStoreBlendAdd = ProgramStore.BlendAdd_DepthNoDepth(mRS);
+        mProgStoreBlendAdd = ProgramStore.BLEND_ADD_DEPTH_NO_DEPTH(mRS);
 
+        mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth);
         mScript.set_gProgStoreBlendNone(mProgStoreBlendNone);
         mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha);
         mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd);
@@ -112,18 +153,11 @@
 
     private void initProgramFragment() {
 
-        Sampler.Builder bs = new Sampler.Builder(mRS);
-        bs.setMin(Sampler.Value.LINEAR);
-        bs.setMag(Sampler.Value.LINEAR);
-        bs.setWrapS(Sampler.Value.CLAMP);
-        bs.setWrapT(Sampler.Value.CLAMP);
-        mSampler = bs.create();
-
         ProgramFragment.Builder texBuilder = new ProgramFragment.Builder(mRS);
         texBuilder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
                               ProgramFragment.Builder.Format.RGBA, 0);
         mProgFragmentTexture = texBuilder.create();
-        mProgFragmentTexture.bindSampler(mSampler, 0);
+        mProgFragmentTexture.bindSampler(mLinearClamp, 0);
 
         ProgramFragment.Builder colBuilder = new ProgramFragment.Builder(mRS);
         colBuilder.setVaryingColor(false);
@@ -146,22 +180,24 @@
 
     private Allocation loadTextureRGB(int id) {
         final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes,
-                id, Element.RGB_565(mRS), false);
+                id, Element.RGB_565(mRS), true);
         allocation.uploadToTexture(0);
         return allocation;
     }
 
     private Allocation loadTextureARGB(int id) {
         Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB);
-        final Allocation allocation = Allocation.createFromBitmap(mRS, b, Element.RGBA_8888(mRS), false);
+        final Allocation allocation = Allocation.createFromBitmap(mRS, b, Element.RGBA_8888(mRS), true);
         allocation.uploadToTexture(0);
         return allocation;
     }
 
     private void loadImages() {
+        mTexTorus = loadTextureRGB(R.drawable.torusmap);
         mTexOpaque = loadTextureRGB(R.drawable.data);
         mTexTransparent = loadTextureARGB(R.drawable.leaf);
 
+        mScript.set_gTexTorus(mTexTorus);
         mScript.set_gTexOpaque(mTexOpaque);
         mScript.set_gTexTransparent(mTexTransparent);
     }
@@ -185,19 +221,59 @@
         mScript.set_gFontMono(mFontMono);
     }
 
+    private void initMesh() {
+        mMbyNMesh = getMbyNMesh(256, 256, 10, 10);
+        mScript.set_gMbyNMesh(mMbyNMesh);
+
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
+        FileA3D.IndexEntry entry = model.getIndexEntry(0);
+        if(entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+            Log.e("rs", "could not load model");
+        }
+        else {
+            mTorus = (Mesh)entry.getObject();
+            mScript.set_gTorusMesh(mTorus);
+        }
+    }
+
+    private void initSamplers() {
+        Sampler.Builder bs = new Sampler.Builder(mRS);
+        bs.setMin(Sampler.Value.LINEAR);
+        bs.setMag(Sampler.Value.LINEAR);
+        bs.setWrapS(Sampler.Value.WRAP);
+        bs.setWrapT(Sampler.Value.WRAP);
+        mLinearWrap = bs.create();
+
+        mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
+        mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
+        mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
+
+        mScript.set_gLinearClamp(mLinearClamp);
+        mScript.set_gLinearWrap(mLinearWrap);
+        mScript.set_gMipLinearWrap(mMipLinearWrap);
+        mScript.set_gNearestClamp(mNearestClamp);
+    }
+
+    private void initProgramRaster() {
+        mCullBack = ProgramRaster.CULL_BACK(mRS);
+        mCullFront = ProgramRaster.CULL_FRONT(mRS);
+
+        mScript.set_gCullBack(mCullBack);
+        mScript.set_gCullFront(mCullFront);
+    }
+
     private void initRS() {
 
         mScript = new ScriptC_Rsrenderstates(mRS, mRes, R.raw.rsrenderstates, true);
 
+        initSamplers();
         initProgramStore();
         initProgramFragment();
         initProgramVertex();
-
         initFonts();
-
         loadImages();
-
-
+        initMesh();
+        initProgramRaster();
 
         mRS.contextBindRootScript(mScript);
     }
diff --git a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs
index 1526a50..68d9d3c 100644
--- a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs
+++ b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs
@@ -22,14 +22,17 @@
 rs_program_fragment gProgFragmentColor;
 rs_program_fragment gProgFragmentTexture;
 
+rs_program_store gProgStoreBlendNoneDepth;
 rs_program_store gProgStoreBlendNone;
 rs_program_store gProgStoreBlendAlpha;
 rs_program_store gProgStoreBlendAdd;
 
 rs_allocation gTexOpaque;
+rs_allocation gTexTorus;
 rs_allocation gTexTransparent;
 
 rs_mesh gMbyNMesh;
+rs_mesh gTorusMesh;
 
 rs_font gFontSans;
 rs_font gFontSerif;
@@ -40,11 +43,21 @@
 
 int gDisplayMode;
 
+rs_sampler gLinearClamp;
+rs_sampler gLinearWrap;
+rs_sampler gMipLinearWrap;
+rs_sampler gNearestClamp;
+
+rs_program_raster gCullBack;
+rs_program_raster gCullFront;
+
 #pragma rs export_var(gProgVertex, gProgFragmentColor, gProgFragmentTexture)
-#pragma rs export_var(gProgStoreBlendNone, gProgStoreBlendAlpha, gProgStoreBlendAdd)
-#pragma rs export_var(gTexOpaque, gTexTransparent)
-#pragma rs export_var(gMbyNMesh)
+#pragma rs export_var(gProgStoreBlendNoneDepth, gProgStoreBlendNone, gProgStoreBlendAlpha, gProgStoreBlendAdd)
+#pragma rs export_var(gTexOpaque, gTexTorus, gTexTransparent)
+#pragma rs export_var(gMbyNMesh, gTorusMesh)
 #pragma rs export_var(gFontSans, gFontSerif, gFontSerifBold, gFontSerifItalic, gFontSerifBoldItalic, gFontMono)
+#pragma rs export_var(gLinearClamp, gLinearWrap, gMipLinearWrap, gNearestClamp)
+#pragma rs export_var(gCullBack, gCullFront)
 
 //What we are showing
 #pragma rs export_var(gDisplayMode)
@@ -78,9 +91,17 @@
     rsgDrawText("Monospace font sample", 30, yPos);
 }
 
-void displayShaderSamples() {
+void bindProgramVertexOrtho() {
     // Default vertex sahder
     rsgBindProgramVertex(gProgVertex);
+    // Setup the projectioni matrix
+    rs_matrix4x4 proj;
+    rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -1,1);
+    rsgProgramVertexLoadProjectionMatrix(&proj);
+}
+
+void displayShaderSamples() {
+    bindProgramVertexOrtho();
     rs_matrix4x4 matrix;
     rsMatrixLoadIdentity(&matrix);
     rsgProgramVertexLoadModelMatrix(&matrix);
@@ -88,24 +109,31 @@
     // Fragment shader with texture
     rsgBindProgramStore(gProgStoreBlendNone);
     rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
     rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
 
-    rsgDrawQuadTexCoords(0, 0,     0, 0, 0,
-                         0, 256,   0, 0, 1,
-                         256, 256, 0, 1, 1,
-                         256, 0,   0, 1, 0);
+    float startX = 0, startY = 0;
+    float width = 256, height = 256;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1,
+                         startX + width, startY + height, 0, 1, 1,
+                         startX + width, startY, 0, 1, 0);
 
-    rsgDrawQuadTexCoords(200, 0,     0, 0, 0,
-                         200, 128,   0, 0, 1,
-                         328, 128,   0, 1, 1,
-                         328, 0,     0, 1, 0);
+    startX = 200; startY = 0;
+    width = 128; height = 128;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1,
+                         startX + width, startY + height, 0, 1, 1,
+                         startX + width, startY, 0, 1, 0);
 
     rsgBindProgramStore(gProgStoreBlendAlpha);
     rsgBindTexture(gProgFragmentTexture, 0, gTexTransparent);
-    rsgDrawQuadTexCoords(0, 200,   0, 0, 0,
-                         0, 328,   0, 0, 1,
-                         128, 328, 0, 1, 1,
-                         128, 200, 0, 1, 0);
+    startX = 0; startY = 200;
+    width = 128; height = 128;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1,
+                         startX + width, startY + height, 0, 1, 1,
+                         startX + width, startY, 0, 1, 0);
 
     // Fragment program with simple color
     rsgBindProgramFragment(gProgFragmentColor);
@@ -124,7 +152,7 @@
 void displayBlendingSamples() {
     int i;
 
-    rsgBindProgramVertex(gProgVertex);
+    bindProgramVertexOrtho();
     rs_matrix4x4 matrix;
     rsMatrixLoadIdentity(&matrix);
     rsgProgramVertexLoadModelMatrix(&matrix);
@@ -168,11 +196,128 @@
 }
 
 void displayMeshSamples() {
+
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadTranslate(&matrix, 128, 128, 0);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNone);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
+
+    rsgDrawMesh(gMbyNMesh);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("User gen 10 by 10 grid mesh", 10, 250);
+}
+
+void displayTextureSamplers() {
+
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadIdentity(&matrix);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNone);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
+
+    // Linear clamp
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+    float startX = 0, startY = 0;
+    float width = 300, height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.1,
+                         startX + width, startY + height, 0, 1.1, 1.1,
+                         startX + width, startY, 0, 1.1, 0);
+
+    // Linear Wrap
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearWrap);
+    startX = 0; startY = 300;
+    width = 300; height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.1,
+                         startX + width, startY + height, 0, 1.1, 1.1,
+                         startX + width, startY, 0, 1.1, 0);
+
+    // Nearest
+    rsgBindSampler(gProgFragmentTexture, 0, gNearestClamp);
+    startX = 300; startY = 0;
+    width = 300; height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.1,
+                         startX + width, startY + height, 0, 1.1, 1.1,
+                         startX + width, startY, 0, 1.1, 0);
+
+    rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
+    startX = 300; startY = 300;
+    width = 300; height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.5,
+                         startX + width, startY + height, 0, 1.5, 1.5,
+                         startX + width, startY, 0, 1.5, 0);
+
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("Filtering: linear clamp", 10, 290);
+    rsgDrawText("Filtering: linear wrap", 10, 590);
+    rsgDrawText("Filtering: nearest clamp", 310, 290);
+    rsgDrawText("Filtering: miplinear wrap", 310, 590);
+
+}
+
+float gTorusRotation = 0;
+
+void displayCullingSamplers() {
+    rsgBindProgramVertex(gProgVertex);
+    // Setup the projectioni matrix with 60 degree field of view
+    rs_matrix4x4 proj;
+    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
+    rsgProgramVertexLoadProjectionMatrix(&proj);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNoneDepth);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
+
+    // Aplly a rotation to our mesh
+    gTorusRotation += 50.0f * rsGetDt();
+    if(gTorusRotation > 360.0f) {
+        gTorusRotation -= 360.0f;
+    }
+
+    rs_matrix4x4 matrix;
+    // Position our model on the screen
+    rsMatrixLoadTranslate(&matrix, -2.0f, 0.0f, -10.0f);
+    rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+    // Use front face culling
+    rsgBindProgramRaster(gCullFront);
+    rsgDrawMesh(gTorusMesh);
+
+    rsMatrixLoadTranslate(&matrix, 2.0f, 0.0f, -10.0f);
+    rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+    // Use back face culling
+    rsgBindProgramRaster(gCullBack);
+    rsgDrawMesh(gTorusMesh);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("Displaying mesh front/back face culling", 10, rsgGetHeight() - 10);
 }
 
 int root(int launchID) {
 
-    rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
     rsgClearDepth(1.0f);
 
     switch(gDisplayMode) {
@@ -188,6 +333,12 @@
     case 3:
         displayMeshSamples();
         break;
+    case 4:
+        displayTextureSamplers();
+        break;
+    case 5:
+        displayCullingSamplers();
+        break;
     }
 
     return 10;