Add ability to load arrays in RenderScript.
diff --git a/libs/rs/java/Fall/Android.mk b/libs/rs/java/Fall/Android.mk
new file mode 100644
index 0000000..6366f63
--- /dev/null
+++ b/libs/rs/java/Fall/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2009 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.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_PACKAGE_NAME := FallRS
+
+include $(BUILD_PACKAGE)
diff --git a/libs/rs/java/Fall/AndroidManifest.xml b/libs/rs/java/Fall/AndroidManifest.xml
new file mode 100644
index 0000000..f4f96a1
--- /dev/null
+++ b/libs/rs/java/Fall/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.fall.rs">
+
+    <application android:label="FallRS">
+
+        <activity
+            android:name="Fall"
+            android:theme="@android:style/Theme.NoTitleBar">
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+        </activity>
+
+    </application>
+
+</manifest>
diff --git a/libs/rs/java/Fall/res/raw/fall.c b/libs/rs/java/Fall/res/raw/fall.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/rs/java/Fall/res/raw/fall.c
diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/Fall.java b/libs/rs/java/Fall/src/com/android/fall/rs/Fall.java
new file mode 100644
index 0000000..b1d9b1d
--- /dev/null
+++ b/libs/rs/java/Fall/src/com/android/fall/rs/Fall.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.fall.rs;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class Fall extends Activity {
+    private FallView mView;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mView = new FallView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mView.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mView.onPause();
+
+        Runtime.getRuntime().exit(0);
+    }
+}
diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java b/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
new file mode 100644
index 0000000..9b950df
--- /dev/null
+++ b/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2009 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.fall.rs;
+
+import android.content.res.Resources;
+import android.renderscript.RenderScript;
+import android.renderscript.ScriptC;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertexAlloc;
+import android.renderscript.Allocation;
+import android.renderscript.Sampler;
+import static android.renderscript.Sampler.Value.LINEAR;
+import static android.renderscript.Sampler.Value.CLAMP;
+import static android.renderscript.ProgramStore.DepthFunc.*;
+import static android.renderscript.ProgramStore.BlendDstFunc;
+import static android.renderscript.ProgramStore.BlendSrcFunc;
+import static android.renderscript.ProgramFragment.EnvMode.*;
+import static android.renderscript.Element.*;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap;
+
+import java.util.TimeZone;
+
+class FallRS {
+    private static final int MESH_RESOLUTION = 64;
+
+    private static final int RSID_STATE = 0;
+    private static final int RSID_STATE_FRAMECOUNT = 0;
+    private static final int RSID_STATE_WIDTH = 1;
+    private static final int RSID_STATE_HEIGHT = 2;
+
+    private static final int RSID_TEXTURES = 1;
+    private static final int TEXTURES_COUNT = 0;
+
+    private Resources mResources;
+    private RenderScript mRS;
+    private final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
+
+    private final int mWidth;
+    private final int mHeight;
+
+    private ScriptC mScript;
+    private Sampler mSampler;
+    private ProgramFragment mPfBackground;
+    private ProgramStore mPfsBackground;
+    private RenderScript.ProgramVertex mPvBackground;
+    private ProgramVertexAlloc mPvOrthoAlloc;
+
+    private Allocation mTexturesIDs;
+    private Allocation[] mTextures;
+    private int[] mTextureBufferIDs;
+
+    private Allocation mState;
+
+    public FallRS(int width, int height) {
+        mWidth = width;
+        mHeight = height;
+        mBitmapOptions.inScaled = false;
+        mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
+    }
+
+    public void init(RenderScript rs, Resources res) {
+        mRS = rs;
+        mResources = res;
+        initRS();
+    }
+    
+    public void destroy() {
+        mScript.destroy();
+        mSampler.destroy();
+        mPfBackground.destroy();
+        mPfsBackground.destroy();
+        mPvBackground.destroy();
+        mPvOrthoAlloc.mAlloc.destroy();
+        mTexturesIDs.destroy();
+        for (Allocation a : mTextures) {
+            a.destroy();
+        }
+        mState.destroy();
+        mTextureBufferIDs = null;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            destroy();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    private void initRS() {
+        createProgramVertex();
+        createProgramFragmentStore();
+        createProgramFragment();
+        createScriptStructures();
+        createMesh();
+
+        ScriptC.Builder sb = new ScriptC.Builder(mRS);
+        sb.setScript(mResources, R.raw.fall);
+        sb.setRoot(true);
+        mScript = sb.create();
+        mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+        mScript.setTimeZone(TimeZone.getDefault().getID());
+
+        loadSkyTextures();
+        mScript.bindAllocation(mState, RSID_STATE);
+        mScript.bindAllocation(mTexturesIDs, RSID_TEXTURES);
+
+        mRS.contextBindRootScript(mScript);
+    }
+
+    private void createMesh() {
+        
+    }
+
+    private void createScriptStructures() {
+        final int[] data = new int[3];
+        mState = Allocation.createSized(mRS, USER_I32, data.length);
+        data[RSID_STATE_FRAMECOUNT] = 0;
+        data[RSID_STATE_WIDTH] = mWidth;
+        data[RSID_STATE_HEIGHT] = mHeight;
+        mState.data(data);
+    }
+
+    private void loadSkyTextures() {
+        mTextureBufferIDs = new int[TEXTURES_COUNT];
+        mTextures = new Allocation[TEXTURES_COUNT];
+        mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, TEXTURES_COUNT);
+
+        final Allocation[] textures = mTextures;
+        // TOOD: Load textures
+
+        final int[] bufferIds = mTextureBufferIDs;
+        final int count = textures.length;
+
+        for (int i = 0; i < count; i++) {
+            final Allocation texture = textures[i];
+            texture.uploadToTexture(0);
+            bufferIds[i] = texture.getID();
+        }
+
+        mTexturesIDs.data(bufferIds);
+    }
+
+    private Allocation loadTexture(int id, String name) {
+        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;
+    }
+
+    private void createProgramFragment() {
+        Sampler.Builder bs = new Sampler.Builder(mRS);
+        bs.setMin(LINEAR);
+        bs.setMag(LINEAR);
+        bs.setWrapS(CLAMP);
+        bs.setWrapT(CLAMP);
+        mSampler = bs.create();
+
+        ProgramFragment.Builder b;
+        b = new ProgramFragment.Builder(mRS, null, null);
+        b.setTexEnable(true, 0);
+        b.setTexEnvMode(REPLACE, 0);
+        mPfBackground = b.create();
+        mPfBackground.setName("PFBackground");
+        mPfBackground.bindSampler(mSampler, 0);
+    }
+
+    private void createProgramFragmentStore() {
+        ProgramStore.Builder b;
+        b = new ProgramStore.Builder(mRS, null, null);
+
+        b.setDepthFunc(ALWAYS);
+        b.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+        b.setDitherEnable(true);
+        b.setDepthMask(false);
+        mPfsBackground = b.create();
+        mPfsBackground.setName("PFSBackground");
+    }
+
+    private void createProgramVertex() {
+        mPvOrthoAlloc = new ProgramVertexAlloc(mRS);
+        mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
+
+        mRS.programVertexBegin(null, null);
+        mRS.programVertexSetTextureMatrixEnable(true);
+        mPvBackground = mRS.programVertexCreate();
+        mPvBackground.bindAllocation(0, mPvOrthoAlloc.mAlloc);
+        mPvBackground.setName("PVBackground");
+    }
+}
diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java b/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java
new file mode 100644
index 0000000..ebbdba5
--- /dev/null
+++ b/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.fall.rs;
+
+import android.content.Context;
+import android.view.SurfaceHolder;
+import android.renderscript.RenderScript;
+import android.renderscript.RSSurfaceView;
+
+class FallView extends RSSurfaceView {
+    private FallRS mRender;
+
+    public FallView(Context context) {
+        super(context);
+    }
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
+
+        RenderScript RS = createRenderScript();
+        mRender = new FallRS(w, h);
+        mRender.init(RS, getResources());
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        if (mRender != null) mRender.destroy();
+    }
+}
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 e9aa3cc..309c940 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
@@ -18,7 +18,6 @@
 
 import android.content.res.Resources;
 import android.renderscript.Sampler;
-import static android.renderscript.Sampler.Value.*;
 import static android.renderscript.ProgramFragment.EnvMode.*;
 import static android.renderscript.ProgramStore.DepthFunc.*;
 import static android.renderscript.ProgramStore.BlendSrcFunc;
@@ -33,6 +32,7 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.renderscript.ScriptC;
+import static android.renderscript.Sampler.Value.*;
 
 import java.util.TimeZone;
 
@@ -43,8 +43,8 @@
     private static final int RSID_STATE_WIDTH = 2;
     private static final int RSID_STATE_HEIGHT = 3;
 
-    private static final int RSID_SKY_TEXTURES = 1;
-    private static final int SKY_TEXTURES_COUNT = 5;
+    private static final int RSID_TEXTURES = 1;
+    private static final int TEXTURES_COUNT = 5;
 
     private static final int RSID_BLADES = 2;
     private static final int BLADES_COUNT = 100;
@@ -69,32 +69,21 @@
     private final int mWidth;
     private final int mHeight;
 
-    @SuppressWarnings({"FieldCanBeLocal"})
     private ScriptC mScript;
-    @SuppressWarnings({"FieldCanBeLocal"})
     private Sampler mSampler;
-    @SuppressWarnings({"FieldCanBeLocal"})
     private ProgramFragment mPfBackground;
-    @SuppressWarnings({"FieldCanBeLocal"})
     private ProgramStore mPfsBackground;
-    @SuppressWarnings({"FieldCanBeLocal"})
     private RenderScript.ProgramVertex mPvBackground;
-    @SuppressWarnings({"FieldCanBeLocal"})
     private ProgramVertexAlloc mPvOrthoAlloc;
 
-    @SuppressWarnings({"FieldCanBeLocal"})
     private Allocation mTexturesIDs;
-    @SuppressWarnings({"FieldCanBeLocal"})
     private Allocation[] mTextures;
-    @SuppressWarnings({"FieldCanBeLocal"})
     private int[] mTextureBufferIDs;
-    @SuppressWarnings({"FieldCanBeLocal"})
+
     private Allocation mState;
-    @SuppressWarnings({"FieldCanBeLocal"})
     private Allocation mBlades;
-    @SuppressWarnings({"FieldCanBeLocal"})
+
     private ProgramFragment mPfGrass;
-    @SuppressWarnings({"FieldCanBeLocal"})
     private ProgramStore mPfsGrass;
 
     public GrassRS(int width, int height) {
@@ -109,6 +98,33 @@
         mResources = res;
         initRS();
     }
+    
+    public void destroy() {
+        mScript.destroy();
+        mSampler.destroy();
+        mPfBackground.destroy();
+        mPfsBackground.destroy();
+        mPvBackground.destroy();
+        mPvOrthoAlloc.mAlloc.destroy();
+        mTexturesIDs.destroy();
+        for (Allocation a : mTextures) {
+            a.destroy();
+        }
+        mState.destroy();
+        mBlades.destroy();
+        mPfGrass.destroy();
+        mPfsGrass.destroy();
+        mTextureBufferIDs = null;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            destroy();
+        } finally {
+            super.finalize();
+        }
+    }
 
     private void initRS() {
         createProgramVertex();
@@ -125,7 +141,7 @@
 
         loadSkyTextures();
         mScript.bindAllocation(mState, RSID_STATE);
-        mScript.bindAllocation(mTexturesIDs, RSID_SKY_TEXTURES);
+        mScript.bindAllocation(mTexturesIDs, RSID_TEXTURES);
         mScript.bindAllocation(mBlades, RSID_BLADES);
 
         mRS.contextBindRootScript(mScript);
@@ -165,9 +181,9 @@
     }
 
     private void loadSkyTextures() {
-        mTextureBufferIDs = new int[SKY_TEXTURES_COUNT];
-        mTextures = new Allocation[SKY_TEXTURES_COUNT];
-        mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, SKY_TEXTURES_COUNT);
+        mTextureBufferIDs = new int[TEXTURES_COUNT];
+        mTextures = new Allocation[TEXTURES_COUNT];
+        mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, TEXTURES_COUNT);
 
         final Allocation[] textures = mTextures;
         textures[0] = loadTexture(R.drawable.night, "night");
diff --git a/libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java b/libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java
index 44d5b08..c2b9a66 100644
--- a/libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java
+++ b/libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java
@@ -22,6 +22,8 @@
 import android.view.SurfaceHolder;
 
 class GrassView extends RSSurfaceView {
+    private GrassRS mRender;
+
     public GrassView(Context context) {
         super(context);
     }
@@ -30,7 +32,12 @@
         super.surfaceChanged(holder, format, w, h);
 
         RenderScript RS = createRenderScript();
-        GrassRS render = new GrassRS(w, h);
-        render.init(RS, getResources());
+        mRender = new GrassRS(w, h);
+        mRender.init(RS, getResources());
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        if (mRender != null) mRender.destroy();
     }
 }
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 561cde6..8a29be34 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -59,6 +59,22 @@
     return i[offset];
 }
 
+static float* SC_loadArrayF(uint32_t bank)
+{
+    GET_TLS();
+    void *vp = sc->mSlots[bank]->getPtr();
+    float *f = static_cast<float *>(vp);
+    return f;
+}
+
+static int32_t* SC_loadArrayI32(uint32_t bank)
+{
+    GET_TLS();
+    void *vp = sc->mSlots[bank]->getPtr();
+    int32_t *i = static_cast<int32_t *>(vp);
+    return i;
+}
+
 static uint32_t SC_loadU32(uint32_t bank, uint32_t offset)
 {
     GET_TLS();
@@ -678,6 +694,10 @@
     //{ "loadU32", (void *)&SC_loadU32, "unsigned int", "(int, int)" },
     { "loadF", (void *)&SC_loadF,
         "float", "(int, int)" },
+    { "loadArrayF", (void *)&SC_loadArrayF,
+        "float*", "(int)" },
+    { "loadArrayI32", (void *)&SC_loadArrayI32,
+        "int*", "(int)" },
     { "loadVec4", (void *)&SC_loadVec4,
         "void", "(int, int, float *)" },
     { "loadMatrix", (void *)&SC_loadMatrix,