Use mip mapping for the "many" visualization to get rid of jaggies.
diff --git a/res/raw/many.rs b/res/raw/many.rs
index f7a7551..502a243 100644
--- a/res/raw/many.rs
+++ b/res/raw/many.rs
@@ -15,7 +15,6 @@
 #pragma version(1)
 #pragma stateVertex(PVBackground)
 #pragma stateRaster(parent)
-#pragma stateFragment(PFBackground)
 #pragma stateStore(PFSBackground)
 
 #define RSID_POINTS 1
@@ -39,8 +38,10 @@
     matrixScale(mat1, scale, scale, scale);
     vpLoadModelMatrix(mat1);
 
+    bindProgramFragment(NAMED_PFBackgroundMip);
+
     // draw the background image (416x233)
-    bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_background);
+    bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_background);
     drawQuadTexCoords(
             -208.0f, -33.0f, 600.0f,        // space
                 0.09375f, 0.9551f,        // texture
@@ -53,9 +54,9 @@
 
     // draw the peak indicator light (56x58)
     if (State->mPeak > 0) {
-        bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_peak_on);
+        bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_peak_on);
     } else {
-        bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_peak_off);
+        bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_peak_off);
     }
     drawQuadTexCoords(
             140.0f, 70.0f, 600.0f,         // space
@@ -77,7 +78,7 @@
     matrixRotate(mat1, State->mAngle - 90.f, 0.f, 0.f, 1.f);
     matrixScale(mat1, scale, scale, scale);
     vpLoadModelMatrix(mat1);
-    bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_needle);
+    bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_needle);
     drawQuadTexCoords(
             -44.0f, -102.0f+57.f, 600.0f,         // space
                 .15625f, 0.755859375f,  // texture
@@ -96,7 +97,7 @@
     vpLoadModelMatrix(mat1);
 
     // erase the part of the needle we don't want to show
-    bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_black);
+    bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_black);
     drawQuad(-100.f, -55.f, 600.f,
              -100.f, -105.f, 600.f,
               100.f, -105.f, 600.f,
@@ -104,7 +105,7 @@
 
 
     // draw the frame (472x290)
-    bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_frame);
+    bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_frame);
     drawQuadTexCoords(
             -236.0f, -60.0f, 600.0f,           // space
                 0.0390625f, 0.783203125f,    // texture
@@ -211,7 +212,8 @@
     }
 
     uploadToBufferObject(NAMED_PointBuffer);
-    bindTexture(NAMED_PFBackground, 0, NAMED_Tlinetexture);
+    bindProgramFragment(NAMED_PFBackgroundNoMip);
+    bindTexture(NAMED_PFBackgroundNoMip, 0, NAMED_Tlinetexture);
     drawSimpleMesh(NAMED_CubeMesh);
 }
 
@@ -241,6 +243,7 @@
     matrixRotate(ident, State->mTilt, 1.f, 0.f, 0.f);
     matrixRotate(ident, autorotation + State->mRotate, 0.f, 1.f, 0.f);
     autorotation += .3;
+    while (autorotation > 360.f) autorotation -= 360.f;
 
     // draw the reflections
     matrixTranslate(ident, 0.f, -1.f, 0.f);
@@ -248,7 +251,8 @@
     drawVizLayer(ident);
 
     // draw the reflecting plane
-    bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_album);
+    bindProgramFragment(NAMED_PFBackgroundMip);
+    bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_album);
     drawQuadTexCoords(
             -1500.0f, -60.0f, 1500.0f,           // space
                 0.f, 1.f,    // texture
@@ -259,7 +263,6 @@
             -1500.0f, -60.0f, -1500.0f,           // space
                 0.f, 0.f);   // texture
 
-
     // draw the visualizer
     matrixScale(ident, 1.f, -1.f, 1.f);
     matrixTranslate(ident, 0.f, 1.f, 0.f);
diff --git a/src/com/android/musicvis/vis5/Visualization5RS.java b/src/com/android/musicvis/vis5/Visualization5RS.java
index 76f98df..b5ef2a3 100644
--- a/src/com/android/musicvis/vis5/Visualization5RS.java
+++ b/src/com/android/musicvis/vis5/Visualization5RS.java
@@ -17,8 +17,6 @@
 package com.android.musicvis.vis5;
 
 import static android.renderscript.ProgramFragment.EnvMode.REPLACE;
-import static android.renderscript.Sampler.Value.LINEAR;
-import static android.renderscript.Sampler.Value.WRAP;
 
 import com.android.musicvis.R;
 import com.android.musicvis.RenderScriptScene;
@@ -38,6 +36,7 @@
 import android.renderscript.Element.Builder;
 import android.renderscript.ProgramStore.BlendDstFunc;
 import android.renderscript.ProgramStore.BlendSrcFunc;
+import android.renderscript.Sampler.Value;
 import android.util.Log;
 import android.view.MotionEvent;
 
@@ -72,8 +71,10 @@
     private Allocation mState;
 
     private ProgramStore mPfsBackground;
-    private ProgramFragment mPfBackground;
-    private Sampler mSampler;
+    private ProgramFragment mPfBackgroundMip;
+    private ProgramFragment mPfBackgroundNoMip;
+    private Sampler mSamplerMip;
+    private Sampler mSamplerNoMip;
     private Allocation[] mTextures;
     
     private ProgramVertex mPVBackground;
@@ -173,19 +174,19 @@
         mPVAlloc.setupProjectionNormalized(mWidth, mHeight);
 
         mTextures = new Allocation[8];
-        mTextures[0] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.background, Element.RGBA_8888(mRS), false);
+        mTextures[0] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.background, Element.RGBA_8888(mRS), true);
         mTextures[0].setName("Tvumeter_background");
-        mTextures[1] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.frame, Element.RGBA_8888(mRS), false);
+        mTextures[1] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.frame, Element.RGBA_8888(mRS), true);
         mTextures[1].setName("Tvumeter_frame");
-        mTextures[2] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.peak_on, Element.RGBA_8888(mRS), false);
+        mTextures[2] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.peak_on, Element.RGBA_8888(mRS), true);
         mTextures[2].setName("Tvumeter_peak_on");
-        mTextures[3] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.peak_off, Element.RGBA_8888(mRS), false);
+        mTextures[3] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.peak_off, Element.RGBA_8888(mRS), true);
         mTextures[3].setName("Tvumeter_peak_off");
-        mTextures[4] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.needle, Element.RGBA_8888(mRS), false);
+        mTextures[4] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.needle, Element.RGBA_8888(mRS), true);
         mTextures[4].setName("Tvumeter_needle");
         mTextures[5] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.black, Element.RGB_565(mRS), false);
         mTextures[5].setName("Tvumeter_black");
-        mTextures[6] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.albumart, Element.RGBA_8888(mRS), false);
+        mTextures[6] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.albumart, Element.RGBA_8888(mRS), true);
         mTextures[6].setName("Tvumeter_album");
         mTextures[7] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.fire, Element.RGB_565(mRS), false);
         mTextures[7].setName("Tlinetexture");
@@ -194,21 +195,41 @@
         for (int i = 0; i < count; i++) {
             mTextures[i].uploadToTexture(0);
         }
-        
-        Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
-        samplerBuilder.setMin(LINEAR);
-        samplerBuilder.setMag(LINEAR);
-        samplerBuilder.setWrapS(WRAP);
-        samplerBuilder.setWrapT(WRAP);
-        mSampler = samplerBuilder.create();
+
+        {
+            Sampler.Builder builder = new Sampler.Builder(mRS);
+            builder.setMin(Value.LINEAR);
+            builder.setMag(Value.LINEAR);
+            builder.setWrapS(Value.WRAP);
+            builder.setWrapT(Value.WRAP);
+            mSamplerNoMip = builder.create();
+        }
+
+        {
+            Sampler.Builder builder = new Sampler.Builder(mRS);
+            builder.setMin(Value.LINEAR_MIP_LINEAR);
+            builder.setMag(Value.LINEAR);
+            builder.setWrapS(Value.WRAP);
+            builder.setWrapT(Value.WRAP);
+            mSamplerMip = builder.create();
+        }
 
         {
             ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null);
             builder.setTexEnable(true, 0);
             builder.setTexEnvMode(REPLACE, 0);
-            mPfBackground = builder.create();
-            mPfBackground.setName("PFBackground");
-            mPfBackground.bindSampler(mSampler, 0);
+            mPfBackgroundNoMip = builder.create();
+            mPfBackgroundNoMip.setName("PFBackgroundNoMip");
+            mPfBackgroundNoMip.bindSampler(mSamplerNoMip, 0);
+        }
+        
+        {
+            ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null);
+            builder.setTexEnable(true, 0);
+            builder.setTexEnvMode(REPLACE, 0);
+            mPfBackgroundMip = builder.create();
+            mPfBackgroundMip.setName("PFBackgroundMip");
+            mPfBackgroundMip.bindSampler(mSamplerMip, 0);
         }
 
         {