Merge change 9606

* changes:
  Add anti-aliasing to Grass RS.
diff --git a/libs/rs/java/Grass/res/drawable-hdpi/aa.png b/libs/rs/java/Grass/res/drawable-hdpi/aa.png
new file mode 100644
index 0000000..34cd891
--- /dev/null
+++ b/libs/rs/java/Grass/res/drawable-hdpi/aa.png
Binary files differ
diff --git a/libs/rs/java/Grass/res/raw/grass.c b/libs/rs/java/Grass/res/raw/grass.c
index 79cf483..f6dae81 100644
--- a/libs/rs/java/Grass/res/raw/grass.c
+++ b/libs/rs/java/Grass/res/raw/grass.c
@@ -24,11 +24,12 @@
 #define RSID_FRAME_COUNT 0
 #define RSID_BLADES_COUNT 1
 
-#define RSID_SKY_TEXTURES 1
+#define RSID_TEXTURES 1
 #define RSID_SKY_TEXTURE_NIGHT 0
 #define RSID_SKY_TEXTURE_SUNRISE 1
 #define RSID_SKY_TEXTURE_NOON 2
 #define RSID_SKY_TEXTURE_SUNSET 3
+#define RSID_GRASS_TEXTURE 4
 
 #define RSID_BLADES 2
 #define BLADE_STRUCT_FIELDS_COUNT 12
@@ -45,6 +46,8 @@
 #define BLADE_STRUCT_S 10
 #define BLADE_STRUCT_B 11
 
+#define TESSELATION 4.0f
+
 #define MIDNIGHT 0.0f
 #define MORNING 0.375f
 #define AFTERNOON 0.6f
@@ -68,23 +71,23 @@
 }
 
 void drawNight() {
-    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_NIGHT));
+    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_NIGHT));
     // NOTE: Hacky way to draw the night sky
     drawRect(WVGA_PORTRAIT_WIDTH - 512.0f, -32.0f, WVGA_PORTRAIT_WIDTH, 1024.0f - 32.0f, 0.0f);
 }
 
 void drawSunrise() {
-    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_SUNRISE));
+    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_SUNRISE));
     drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f);
 }
 
 void drawNoon() {
-    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_NOON));
+    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_NOON));
     drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f);
 }
 
 void drawSunset() {
-    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_SUNSET));
+    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_SUNSET));
     drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f);
 }
 
@@ -125,21 +128,25 @@
     degree += (targetDegree - degree) * 0.3f;
 
     float angle = PI / 2.0f;
-    
+
     float currentX = xpos;
     float currentY = ypos;
-    
-    int i = size;
+
+    int i = size * TESSELATION;
+    float lx = lengthX / TESSELATION;
+    float ly = lengthY / TESSELATION;
+    float ss = 2.0f / i + scale / TESSELATION;
+    float sh = 0.7f / TESSELATION;
 
     for ( ; i > 0; i--) {
-        float nextX = currentX - cosf(angle) * size * lengthX;
-        float nextY = currentY - sinf(angle) * size * lengthY;
+        float nextX = currentX - cosf(angle) * size * lx;
+        float nextY = currentY - sinf(angle) * size * ly;
         angle += degree * hardness;
 
-        drawQuad(nextX + (i - 1) * scale, nextY, 0.0f,
-                 nextX - (i - 1) * scale, nextY, 0.0f,
-                 currentX - i * scale, currentY + 0.7f, 0.0f,
-                 currentX + i * scale, currentY + 0.7f, 0.0f);
+        drawQuad(nextX + (i - 1) * ss, nextY, 0.0f,
+                 nextX - (i - 1) * ss, nextY, 0.0f,
+                 currentX - i * ss, currentY + sh, 0.0f,
+                 currentX + i * ss, currentY + sh, 0.0f);
 
         currentX = nextX;
         currentY = nextY;
@@ -149,7 +156,10 @@
 }
 
 void drawBlades(float now) {
-    bindTexture(NAMED_PFBackground, 0, 0);    
+    // For anti-aliasing
+    bindProgramFragmentStore(NAMED_PFSGrass);
+    bindProgramFragment(NAMED_PFGrass);
+    bindTexture(NAMED_PFGrass, 0, loadI32(RSID_TEXTURES, RSID_GRASS_TEXTURE));
 
     int bladesCount = loadI32(RSID_STATE, RSID_BLADES_COUNT);
     int count = bladesCount * BLADE_STRUCT_FIELDS_COUNT;
@@ -188,7 +198,7 @@
         alpha(1.0f - normf(DUSK, 1.0f, now));
         drawSunset();
     }
-    
+
     drawBlades(now);
 
     frameCount++;
diff --git a/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
index 435b5ce..cf7affc 100644
--- a/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
+++ b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
@@ -24,12 +24,13 @@
 import static android.renderscript.RenderScript.BlendSrcFunc;
 import static android.renderscript.RenderScript.BlendDstFunc;
 import android.renderscript.RenderScript;
-import android.renderscript.Element;
 import android.renderscript.Allocation;
 import android.renderscript.ProgramVertexAlloc;
 import static android.renderscript.Element.*;
 
 import static android.util.MathUtils.*;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 
 import java.util.TimeZone;
 
@@ -39,7 +40,7 @@
     private static final int RSID_STATE_BLADES_COUNT = 1;
 
     private static final int RSID_SKY_TEXTURES = 1;
-    private static final int SKY_TEXTURES_COUNT = 4;
+    private static final int SKY_TEXTURES_COUNT = 5;
     
     private static final int RSID_BLADES = 2;    
     private static final int BLADES_COUNT = 100;
@@ -59,6 +60,7 @@
     
     private Resources mResources;
     private RenderScript mRS;
+    private final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
     
     private final int mWidth;
     private final int mHeight;
@@ -77,19 +79,25 @@
     private ProgramVertexAlloc mPvOrthoAlloc;
 
     @SuppressWarnings({"FieldCanBeLocal"})
-    private Allocation mSkyTexturesIDs;
+    private Allocation mTexturesIDs;
     @SuppressWarnings({"FieldCanBeLocal"})
-    private Allocation[] mSkyTextures;
+    private Allocation[] mTextures;
     @SuppressWarnings({"FieldCanBeLocal"})
-    private int[] mSkyBufferIDs;
+    private int[] mTextureBufferIDs;
     @SuppressWarnings({"FieldCanBeLocal"})
     private Allocation mState;
     @SuppressWarnings({"FieldCanBeLocal"})
     private Allocation mBlades;
+    @SuppressWarnings({"FieldCanBeLocal"})
+    private RenderScript.ProgramFragment mPfGrass;
+    @SuppressWarnings({"FieldCanBeLocal"})
+    private RenderScript.ProgramFragmentStore mPfsGrass;
 
     public GrassRS(int width, int height) {
         mWidth = width;
         mHeight = height;
+        mBitmapOptions.inScaled = false;
+        mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
     }
 
     public void init(RenderScript rs, Resources res) {
@@ -114,7 +122,7 @@
 
         loadSkyTextures();
         mScript.bindAllocation(mState, RSID_STATE);
-        mScript.bindAllocation(mSkyTexturesIDs, RSID_SKY_TEXTURES);
+        mScript.bindAllocation(mTexturesIDs, RSID_SKY_TEXTURES);
         mScript.bindAllocation(mBlades, RSID_BLADES);
 
         mRS.contextBindRootScript(mScript);
@@ -146,23 +154,24 @@
         blades[index + BLADE_STRUCT_LENGTHX] = random(4.5f) + 3.0f;
         blades[index + BLADE_STRUCT_LENGTHY] = random(5.5f) + 2.0f;
         blades[index + BLADE_STRUCT_HARDNESS] = random(1.0f) + 0.2f;
-        blades[index + BLADE_STRUCT_H] = (51.0f + random(5.0f)) / 255.0f;
-        blades[index + BLADE_STRUCT_S] = (200.0f + random(55.0f)) / 255.0f;
-        blades[index + BLADE_STRUCT_B] = (90.0f + random(165.0f)) / 255.0f;
+        blades[index + BLADE_STRUCT_H] = random(0.02f) + 0.2f;
+        blades[index + BLADE_STRUCT_S] = random(0.22f) + 0.78f;
+        blades[index + BLADE_STRUCT_B] = random(0.65f) + 0.35f;
     }
 
     private void loadSkyTextures() {
-        mSkyBufferIDs = new int[SKY_TEXTURES_COUNT];
-        mSkyTextures = new Allocation[SKY_TEXTURES_COUNT];
-        mSkyTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, SKY_TEXTURES_COUNT);
+        mTextureBufferIDs = new int[SKY_TEXTURES_COUNT];
+        mTextures = new Allocation[SKY_TEXTURES_COUNT];
+        mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, SKY_TEXTURES_COUNT);
 
-        final Allocation[] textures = mSkyTextures;
+        final Allocation[] textures = mTextures;
         textures[0] = loadTexture(R.drawable.night, "night");
         textures[1] = loadTexture(R.drawable.sunrise, "sunrise");
         textures[2] = loadTexture(R.drawable.sky, "sky");
         textures[3] = loadTexture(R.drawable.sunset, "sunset");
+        textures[4] = loadTextureARGB(R.drawable.aa, "aa");
 
-        final int[] bufferIds = mSkyBufferIDs;
+        final int[] bufferIds = mTextureBufferIDs;
         final int count = textures.length;
 
         for (int i = 0; i < count; i++) {
@@ -171,12 +180,21 @@
             bufferIds[i] = texture.getID();
         }
 
-        mSkyTexturesIDs.data(bufferIds);
+        mTexturesIDs.data(bufferIds);
     }
 
     private Allocation loadTexture(int id, String name) {
-        Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources, id,
-                Element.RGB_565, false);
+        final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources,
+                id, RGB_565, false);
+        allocation.setName(name);
+        return allocation;
+    }
+    
+    private Allocation loadTextureARGB(int id, String name) {
+        // Forces ARGB 32 bits, because pngcrush sometimes optimize our PNGs to
+        // indexed pictures, which are not well supported
+        final Bitmap b = BitmapFactory.decodeResource(mResources, id, mBitmapOptions);
+        final Allocation allocation = Allocation.createFromBitmap(mRS, b, RGBA_8888, false);
         allocation.setName(name);
         return allocation;
     }
@@ -195,6 +213,13 @@
         mPfBackground = mRS.programFragmentCreate();
         mPfBackground.setName("PFBackground");
         mPfBackground.bindSampler(mSampler, 0);
+
+        mRS.programFragmentBegin(null, null);
+        mRS.programFragmentSetTexEnable(0, true);
+        mRS.programFragmentSetTexEnvMode(0, MODULATE);
+        mPfGrass = mRS.programFragmentCreate();
+        mPfGrass.setName("PFGrass");
+        mPfGrass.bindSampler(mSampler, 0);        
     }
 
     private void createProgramFragmentStore() {
@@ -205,6 +230,14 @@
         mRS.programFragmentStoreDepthMask(false);
         mPfsBackground = mRS.programFragmentStoreCreate();
         mPfsBackground.setName("PFSBackground");
+
+        mRS.programFragmentStoreBegin(null, null);
+        mRS.programFragmentStoreDepthFunc(ALWAYS);
+        mRS.programFragmentStoreBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+        mRS.programFragmentStoreDitherEnable(true);
+        mRS.programFragmentStoreDepthMask(false);
+        mPfsGrass = mRS.programFragmentStoreCreate();
+        mPfsGrass.setName("PFSGrass");        
     }
 
     private void createProgramVertex() {