Bug fixes.  TriangleMesh now ref-counts, implement missing element formats, add missing modes for program vertex.  Add matrix support classes.  Add test app rollo
diff --git a/java/Fountain/src/com/android/fountain/FountainRS.java b/java/Fountain/src/com/android/fountain/FountainRS.java
index ceb94d1..0a0b05a 100644
--- a/java/Fountain/src/com/android/fountain/FountainRS.java
+++ b/java/Fountain/src/com/android/fountain/FountainRS.java
@@ -18,15 +18,12 @@
 
 import java.io.Writer;
 
-import android.renderscript.RSSurfaceView;
 import android.renderscript.RenderScript;
-
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
 import android.util.Log;
 
 public class FountainRS {
diff --git a/java/RenderScript/android/renderscript/Matrix.java b/java/RenderScript/android/renderscript/Matrix.java
new file mode 100644
index 0000000..03222aa
--- /dev/null
+++ b/java/RenderScript/android/renderscript/Matrix.java
@@ -0,0 +1,188 @@
+/*
+ * 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 android.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+class Matrix {
+
+    public Matrix() {
+        mMat = new float[16];
+        loadIdentity();
+    }
+
+    public float get(int i, int j) {
+        return mMat[i*4 + j];
+    }
+
+    public void set(int i, int j, float v) {
+        mMat[i*4 + j] = v;
+    }
+
+    public void loadIdentity() {
+        mMat[0] = 1;
+        mMat[1] = 0;
+        mMat[2] = 0;
+        mMat[3] = 0;
+
+        mMat[4] = 0;
+        mMat[5] = 1;
+        mMat[6] = 0;
+        mMat[7] = 0;
+    
+        mMat[8] = 0;
+        mMat[9] = 0;
+        mMat[10] = 1;
+        mMat[11] = 0;
+
+        mMat[12] = 0;
+        mMat[13] = 0;
+        mMat[14] = 0;
+        mMat[15] = 1;
+    }
+
+    public void load(Matrix src) {
+        mMat = src.mMat;
+    }
+
+    public void loadRotate(float rot, float x, float y, float z) {
+        float c, s;
+        mMat[3] = 0;
+        mMat[7] = 0;
+        mMat[11]= 0;
+        mMat[12]= 0;
+        mMat[13]= 0;
+        mMat[14]= 0;
+        mMat[15]= 1;
+        rot *= (float)(java.lang.Math.PI / 180.0f);
+        c = (float)java.lang.Math.cos(rot);
+        s = (float)java.lang.Math.sin(rot);
+    
+        float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
+        if (!(len != 1)) {
+            float recipLen = 1.f / len;
+            x *= recipLen;
+            y *= recipLen;
+            z *= recipLen;
+        }
+        float nc = 1.0f - c;
+        float xy = x * y;
+        float yz = y * z;
+        float zx = z * x;
+        float xs = x * s;
+        float ys = y * s;
+        float zs = z * s;		
+        mMat[ 0] = x*x*nc +  c;
+        mMat[ 4] =  xy*nc - zs;
+        mMat[ 8] =  zx*nc + ys;
+        mMat[ 1] =  xy*nc + zs;
+        mMat[ 5] = y*y*nc +  c;
+        mMat[ 9] =  yz*nc - xs;
+        mMat[ 2] =  zx*nc - ys;
+        mMat[ 6] =  yz*nc + xs;
+        mMat[10] = z*z*nc +  c;
+    }
+
+    public void loadScale(float x, float y, float z) {
+        loadIdentity();
+        mMat[0] = x;
+        mMat[5] = y;
+        mMat[10] = z;
+    }
+    
+    public void loadTranslate(float x, float y, float z) {
+        loadIdentity();
+        mMat[12] = x;
+        mMat[13] = y;
+        mMat[14] = z;
+    }
+
+    public void loadMultiply(Matrix lhs, Matrix rhs) {
+        for (int i=0 ; i<4 ; i++) {
+            float ri0 = 0;
+            float ri1 = 0;
+            float ri2 = 0;
+            float ri3 = 0;
+            for (int j=0 ; j<4 ; j++) {
+                float rhs_ij = rhs.get(i,j);
+                ri0 += lhs.get(j,0) * rhs_ij;
+                ri1 += lhs.get(j,1) * rhs_ij;
+                ri2 += lhs.get(j,2) * rhs_ij;
+                ri3 += lhs.get(j,3) * rhs_ij;
+            }
+            set(i,0, ri0);
+            set(i,1, ri1);
+            set(i,2, ri2);
+            set(i,3, ri3);
+        }
+    }
+
+    public void loadOrtho(float l, float r, float b, float t, float n, float f) {
+        loadIdentity();
+        mMat[0] = 2 / (r - l);
+        mMat[5] = 2 / (t - b);
+        mMat[10]= -2 / (f - n);
+        mMat[12]= -(r + l) / (r - l);
+        mMat[12]= -(t + b) / (t - b);
+        mMat[12]= -(f + n) / (f - n);
+    }
+
+    public void loadFrustum(float l, float r, float b, float t, float n, float f) {
+        loadIdentity();
+        mMat[0] = 2 * n / (r - l);
+        mMat[5] = 2 * n / (t - b);
+        mMat[8] = (r + l) / (r - l);
+        mMat[9] = (t + b) / (t - b);
+        mMat[10]= -(f + n) / (f - n);
+        mMat[11]= -1;
+        mMat[14]= -2*f*n / (f - n);
+        mMat[15]= 0;
+    }
+
+    public void multiply(Matrix rhs) {
+        Matrix tmp = new Matrix();
+        tmp.loadMultiply(this, rhs);
+        load(tmp);
+    }
+    public void rotate(float rot, float x, float y, float z) {
+        Matrix tmp = new Matrix();
+        tmp.loadRotate(rot, x, y, z);
+        multiply(tmp);
+    }
+    public void scale(float x, float y, float z) {
+        Matrix tmp = new Matrix();
+        tmp.loadScale(x, y, z);
+        multiply(tmp);
+    }
+    public void translate(float x, float y, float z) {
+        Matrix tmp = new Matrix();
+        tmp.loadTranslate(x, y, z);
+        multiply(tmp);
+    }
+
+
+
+    float[] mMat;
+
+}
+
+
+
+
+
diff --git a/java/RenderScript/android/renderscript/ProgramVertexAlloc.java b/java/RenderScript/android/renderscript/ProgramVertexAlloc.java
new file mode 100644
index 0000000..020ddb2
--- /dev/null
+++ b/java/RenderScript/android/renderscript/ProgramVertexAlloc.java
@@ -0,0 +1,112 @@
+/*
+ * 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 android.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+public class ProgramVertexAlloc {
+    public static final int MODELVIEW_OFFSET = 0;
+    public static final int PROJECTION_OFFSET = 16;
+    public static final int TEXTURE_OFFSET = 32;
+
+    Matrix mModel;
+    Matrix mProjection;
+    Matrix mTexture;
+
+    public RenderScript.Allocation mAlloc;
+
+    public ProgramVertexAlloc(RenderScript rs) {
+        mModel = new Matrix();
+        mProjection = new Matrix();
+        mTexture = new Matrix();
+
+        mAlloc = rs.allocationCreatePredefSized(
+            RenderScript.ElementPredefined.USER_FLOAT, 
+            48);
+
+        mAlloc.subData1D(MODELVIEW_OFFSET, 16, mModel.mMat);
+        mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
+        mAlloc.subData1D(TEXTURE_OFFSET, 16, mTexture.mMat);
+    }
+
+    public void loadModelview(Matrix m) {
+        mModel = m;
+        mAlloc.subData1D(MODELVIEW_OFFSET, 16, m.mMat);
+    }
+
+    public void loadProjection(Matrix m) {
+        mProjection = m;
+        mAlloc.subData1D(PROJECTION_OFFSET, 16, m.mMat);
+    }
+
+    public void loadTexture(Matrix m) {
+        mTexture = m;
+        mAlloc.subData1D(TEXTURE_OFFSET, 16, m.mMat);
+    }
+
+    public void setupOrthoWindow(int w, int h) {
+        mProjection.loadOrtho(0,w, h,0, -1,1);
+        mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
+    }
+
+    public void setupOrthoNormalized(int w, int h) {
+        // range -1,1 in the narrow axis.
+        if(w > h) {
+            float aspect = ((float)w) / h;
+            mProjection.loadOrtho(-aspect,aspect,  -1,1,  -1,1);
+        } else {
+            float aspect = ((float)h) / w;
+            mProjection.loadOrtho(-1,1, -aspect,aspect,  -1,1);
+        }
+        mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
+    }
+
+    public void setupProjectionNormalized(int w, int h) {
+        // range -1,1 in the narrow axis at z = 0.
+        Matrix m1 = new Matrix();
+        Matrix m2 = new Matrix();
+
+        if(w > h) {
+            float aspect = ((float)w) / h;
+            m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
+        } else {
+            float aspect = ((float)h) / w;
+            m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
+        }
+
+        m2.loadRotate(180, 0, 1, 0);
+        m1.loadMultiply(m1, m2);
+
+        m2.loadScale(-2, 2, 1);
+        m1.loadMultiply(m1, m2);
+
+        m2.loadTranslate(0, 0, 2);
+        m1.loadMultiply(m1, m2);
+
+        mProjection = m1;
+        mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
+    }
+
+}
+
+
+
+
+
+
diff --git a/java/RenderScript/android/renderscript/RenderScript.java b/java/RenderScript/android/renderscript/RenderScript.java
index faa6527..afb4ae3 100644
--- a/java/RenderScript/android/renderscript/RenderScript.java
+++ b/java/RenderScript/android/renderscript/RenderScript.java
@@ -67,6 +67,7 @@
     native private void nContextBindSampler(int sampler, int slot);
     native private void nContextBindProgramFragmentStore(int pfs);
     native private void nContextBindProgramFragment(int pf);
+    native private void nContextBindProgramVertex(int pf);
 
     native private void nAssignName(int obj, byte[] name);
 
@@ -102,6 +103,7 @@
     native private void nTriangleMeshAddVertex_XYZ (float x, float y, float z);
     native private void nTriangleMeshAddVertex_XY_ST (float x, float y, float s, float t);
     native private void nTriangleMeshAddVertex_XYZ_ST (float x, float y, float z, float s, float t);
+    native private void nTriangleMeshAddVertex_XYZ_ST_NORM (float x, float y, float z, float s, float t, float nx, float ny, float nz);
     native private void nTriangleMeshAddTriangle(int i1, int i2, int i3);
     native private int  nTriangleMeshCreate();
 
@@ -155,6 +157,7 @@
     native private void nProgramVertexSetCameraMode(boolean isOrtho);
     native private void nProgramVertexSetTextureMatrixEnable(boolean enable);
     native private void nProgramVertexSetModelMatrixEnable(boolean enable);
+    native private void nProgramVertexSetProjectionMatrixEnable(boolean enable);
     native private int  nProgramVertexCreate();
 
 
@@ -228,19 +231,19 @@
 
         A_8                (7),
         RGB_565            (8),
-        RGB_888            (12),
+        RGB_888            (11),
         RGBA_5551          (9),
         RGBA_4444          (10),
-        RGBA_8888          (13),
+        RGBA_8888          (12),
 
-        INDEX_16           (16),
-        INDEX_32           (17),
-        XY_F32             (18),
-        XYZ_F32            (19),
-        ST_XY_F32          (20),
-        ST_XYZ_F32         (21),
-        NORM_XYZ_F32       (22),
-        NORM_ST_XYZ_F32    (23);
+        INDEX_16           (13),
+        INDEX_32           (14),
+        XY_F32             (15),
+        XYZ_F32            (16),
+        ST_XY_F32          (17),
+        ST_XYZ_F32         (18),
+        NORM_XYZ_F32       (19),
+        NORM_ST_XYZ_F32    (20);
 
         int mID;
         ElementPredefined(int id) {
@@ -593,6 +596,10 @@
         nTriangleMeshAddVertex_XYZ_ST(x, y, z, s, t);
     }
 
+    public void triangleMeshAddVertex_XYZ_ST_NORM(float x, float y, float z, float s, float t, float nx, float ny, float nz) {
+        nTriangleMeshAddVertex_XYZ_ST_NORM(x, y, z, s, t, nx, ny, nz);
+    }
+
     public void triangleMeshAddTriangle(int i1, int i2, int i3) {
         nTriangleMeshAddTriangle(i1, i2, i3);
     }
@@ -738,6 +745,10 @@
         nProgramVertexSetModelMatrixEnable(enable);
     }
 
+    public void programVertexSetProjectionMatrixEnable(boolean enable) {
+        nProgramVertexSetProjectionMatrixEnable(enable);
+    }
+
     public ProgramVertex programVertexCreate() {
         int id = nProgramVertexCreate();
         return new ProgramVertex(id);
@@ -893,6 +904,10 @@
         nContextBindProgramFragment(pf.mID);
     }
 
+    public void contextBindProgramVertex(ProgramVertex pf) {
+        nContextBindProgramVertex(pf.mID);
+    }
+
 /*
     RsAdapter2D rsAdapter2DCreate ();
     void rsAdapter2DBindAllocation (RsAdapter2D adapt, RsAllocation alloc);
diff --git a/java/Rollo/Android.mk b/java/Rollo/Android.mk
new file mode 100644
index 0000000..1c6dfdf
--- /dev/null
+++ b/java/Rollo/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2008 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 := Rollo
+
+include $(BUILD_PACKAGE)
diff --git a/java/Rollo/AndroidManifest.xml b/java/Rollo/AndroidManifest.xml
new file mode 100644
index 0000000..da160a3
--- /dev/null
+++ b/java/Rollo/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.rollo">
+    <application android:label="Rollo">
+        <activity android:name="Rollo"
+                  android:theme="@android:style/Theme.Black.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/java/Rollo/res/raw/rollo.c b/java/Rollo/res/raw/rollo.c
new file mode 100644
index 0000000..b81c567
--- /dev/null
+++ b/java/Rollo/res/raw/rollo.c
@@ -0,0 +1,13 @@
+#pragma version(1)
+#pragma stateVertex(PV)
+#pragma stateFragment(PF)
+#pragma stateFragmentStore(PFSBackground)
+
+int main(void* con, int ft, int launchID)
+{
+    int x;
+
+    renderTriangleMesh(con, NAMED_MeshCard);
+    return 1;
+}
+
diff --git a/java/Rollo/src/com/android/rollo/Rollo.java b/java/Rollo/src/com/android/rollo/Rollo.java
new file mode 100644
index 0000000..400d801
--- /dev/null
+++ b/java/Rollo/src/com/android/rollo/Rollo.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 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.rollo;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+
+import java.lang.Runtime;
+
+public class Rollo extends Activity {
+    //EventListener mListener = new EventListener();
+
+    private static final String LOG_TAG = "libRS_jni";
+    private static final boolean DEBUG  = false;
+    private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
+
+    private RolloView mView;
+
+    // get the current looper (from your Activity UI thread for instance
+
+
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mView = new RolloView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mView.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mView.onPause();
+
+        Runtime.getRuntime().exit(0);
+    }
+
+
+    static void log(String message) {
+        if (LOG_ENABLED) {
+            Log.v(LOG_TAG, message);
+        }
+    }
+
+
+}
+
diff --git a/java/Rollo/src/com/android/rollo/RolloMesh.java b/java/Rollo/src/com/android/rollo/RolloMesh.java
new file mode 100644
index 0000000..c44a817
--- /dev/null
+++ b/java/Rollo/src/com/android/rollo/RolloMesh.java
@@ -0,0 +1,65 @@
+ /*
+ * 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.rollo;
+
+import java.io.Writer;
+import java.lang.Math;
+
+import android.renderscript.RenderScript;
+
+
+class RolloMesh {
+
+    static RenderScript.TriangleMesh createCard(RenderScript rs) {
+        RenderScript.Element vtx = rs.elementGetPredefined(
+            RenderScript.ElementPredefined.ST_XYZ_F32);
+        RenderScript.Element idx = rs.elementGetPredefined(
+            RenderScript.ElementPredefined.INDEX_16);
+
+        rs.triangleMeshBegin(vtx, idx);
+        rs.triangleMeshAddVertex_XYZ_ST(0, 0, 0,  0, 0);
+        rs.triangleMeshAddVertex_XYZ_ST(0, 1, 0,  0, 1);
+        rs.triangleMeshAddVertex_XYZ_ST(1, 1, 0,  1, 1);
+        rs.triangleMeshAddVertex_XYZ_ST(1, 0, 0,  1, 0);
+
+        rs.triangleMeshAddTriangle(0,1,2);
+        rs.triangleMeshAddTriangle(0,2,3);
+        return rs.triangleMeshCreate();
+    }
+
+    static RenderScript.TriangleMesh createTab(RenderScript rs) {
+        RenderScript.Element vtx = rs.elementGetPredefined(
+            RenderScript.ElementPredefined.ST_XYZ_F32);
+        RenderScript.Element idx = rs.elementGetPredefined(
+            RenderScript.ElementPredefined.INDEX_16);
+
+        rs.triangleMeshBegin(vtx, idx);
+        rs.triangleMeshAddVertex_XYZ_ST(0.0f, 0, 0,  -1.0f, 0);
+        rs.triangleMeshAddVertex_XYZ_ST(0.2f, 1, 0,  -0.8f, 1);
+        rs.triangleMeshAddVertex_XYZ_ST(1.8f, 1, 0,   0.8f, 1);
+        rs.triangleMeshAddVertex_XYZ_ST(2.0f, 0, 0,   1.0f, 0);
+        rs.triangleMeshAddTriangle(0,1,2);
+        rs.triangleMeshAddTriangle(0,2,3);
+        return rs.triangleMeshCreate();
+    }
+
+
+
+}
+
+
diff --git a/java/Rollo/src/com/android/rollo/RolloRS.java b/java/Rollo/src/com/android/rollo/RolloRS.java
new file mode 100644
index 0000000..aa9f338
--- /dev/null
+++ b/java/Rollo/src/com/android/rollo/RolloRS.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2008 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.rollo;
+
+import java.io.Writer;
+
+import android.renderscript.RenderScript;
+import android.renderscript.ProgramVertexAlloc;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class RolloRS {
+
+    public RolloRS() {
+    }
+
+    public void init(RenderScript rs, Resources res, int width, int height) {
+        mRS = rs;
+        mRes = res;
+        initNamed();
+        initRS();
+    }
+
+
+    private Resources mRes;
+    private RenderScript mRS;
+
+
+    private RenderScript.Script mScript;
+
+    private RenderScript.Sampler mSampler;
+    private RenderScript.ProgramFragmentStore mPFSBackground;
+    private RenderScript.ProgramFragmentStore mPFSImages;
+    private RenderScript.ProgramFragment mPFBackground;
+    private RenderScript.ProgramFragment mPFImages;
+    private RenderScript.ProgramVertex mPV;
+    private ProgramVertexAlloc mPVAlloc;
+
+    private RenderScript.Allocation mAllocEnv;
+    private RenderScript.Allocation mAllocPos;
+    private RenderScript.Allocation mAllocState;
+    //private RenderScript.Allocation mAllocPV;
+    private RenderScript.TriangleMesh mMeshCard;
+    private RenderScript.TriangleMesh mMeshTab;
+
+    private float[] mBufferPos;
+    //private float[] mBufferPV;
+
+    private void initNamed() {
+        //mMeshTab = RolloMesh.createTab(mRS);
+        //mMeshTab.setName("MeshTab");
+        mMeshCard = RolloMesh.createCard(mRS);
+        mMeshCard.setName("MeshCard");
+        Log.e("rs", "Done loading strips");
+
+        mRS.samplerBegin();
+        mRS.samplerSet(RenderScript.SamplerParam.FILTER_MIN,
+                       RenderScript.SamplerValue.LINEAR_MIP_LINEAR);
+        mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_S,
+                       RenderScript.SamplerValue.CLAMP);
+        mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_T,
+                       RenderScript.SamplerValue.CLAMP);
+        mSampler = mRS.samplerCreate();
+
+
+        mRS.programFragmentBegin(null, null);
+        mRS.programFragmentSetTexEnable(0, true);
+        //mRS.programFragmentSetEnvMode(0, RS_TEX_ENV_MODE_REPLACE);
+        mPFImages = mRS.programFragmentCreate();
+        mPFImages.setName("PF");
+        mPFImages.bindSampler(mSampler, 0);
+
+        mRS.programFragmentStoreBegin(null, null);
+        mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.ALWAYS);
+        mRS.programFragmentStoreDitherEnable(true);
+        mPFSBackground = mRS.programFragmentStoreCreate();
+        mPFSBackground.setName("PFSBackground");
+
+        /*
+        mRS.programFragmentStoreBegin(null, null);
+        mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.EQUAL);
+        mRS.programFragmentStoreDitherEnable(false);
+        mRS.programFragmentStoreDepthMask(false);
+        mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.ONE, 
+                                          RenderScript.BlendDstFunc.ONE);
+        mPFSImages = mRS.programFragmentStoreCreate();
+        mPFSImages.setName("PFSImages");
+*/
+
+
+        mPVAlloc = new ProgramVertexAlloc(mRS);
+        mRS.programVertexBegin(null, null);
+        mRS.programVertexSetCameraMode(true);
+        mRS.programVertexSetTextureMatrixEnable(true);
+        mRS.programVertexSetModelMatrixEnable(true);
+        mRS.programVertexSetProjectionMatrixEnable(true);
+        mPV = mRS.programVertexCreate();
+        mPV.setName("PV");
+        mPV.bindAllocation(0, mPVAlloc.mAlloc);
+
+        mPVAlloc.setupProjectionNormalized(320, 480);
+        //mPVAlloc.setupOrthoNormalized(320, 480);
+        mRS.contextBindProgramVertex(mPV);
+
+
+        Log.e("rs", "Done loading named");
+    }
+
+
+    private void initRS() {
+        mRS.scriptCBegin();
+        mRS.scriptCSetClearColor(0.0f, 0.7f, 0.0f, 1.0f);
+        mRS.scriptCSetScript(mRes, R.raw.rollo);
+        mRS.scriptCSetRoot(true);
+        mScript = mRS.scriptCCreate();
+
+
+        mRS.contextBindRootScript(mScript);
+    }
+}
+
+
+
diff --git a/java/Rollo/src/com/android/rollo/RolloView.java b/java/Rollo/src/com/android/rollo/RolloView.java
new file mode 100644
index 0000000..9a30aed
--- /dev/null
+++ b/java/Rollo/src/com/android/rollo/RolloView.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 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.rollo;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class RolloView extends RSSurfaceView {
+
+    public RolloView(Context context) {
+        super(context);
+
+        //setFocusable(true);
+    }
+
+    private RenderScript mRS;
+    private RolloRS mRender;
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
+
+        mRS = createRenderScript();
+        mRender = new RolloRS();
+        mRender.init(mRS, getResources(), w, h);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event)
+    {
+        // break point at here
+        // this method doesn't work when 'extends View' include 'extends ScrollView'.
+        return super.onKeyDown(keyCode, event);
+    }
+
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev)
+    {
+        boolean ret = true;
+        int act = ev.getAction();
+        if (act == ev.ACTION_UP) {
+            ret = false;
+        }
+        //mRender.newTouchPosition((int)ev.getX(), (int)ev.getY());
+        return ret;
+    }
+}
+
+
diff --git a/jni/RenderScript_jni.cpp b/jni/RenderScript_jni.cpp
index ce62d81..7a3a7af 100644
--- a/jni/RenderScript_jni.cpp
+++ b/jni/RenderScript_jni.cpp
@@ -411,6 +411,15 @@
 }
 
 static void
+nTriangleMeshAddVertex_XYZ_ST_NORM(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z, jfloat s, jfloat t, jfloat nx, jfloat ny, jfloat nz)
+{
+    float v[] = {nx, ny, nz, s, t, x, y, z};
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t);
+    rsTriangleMeshAddVertex(v);
+}
+
+static void
 nTriangleMeshAddTriangle(JNIEnv *_env, jobject _this, jint i1, jint i2, jint i3)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
@@ -805,6 +814,14 @@
     rsProgramVertexSetModelMatrixEnable(enable);
 }
 
+static void
+nProgramVertexSetProjectionMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramVertexSetProjectionMatrixEnable, con(%p), enable(%i)", con, enable);
+    rsProgramVertexSetProjectionMatrixEnable(enable);
+}
+
 static jint
 nProgramVertexCreate(JNIEnv *_env, jobject _this)
 {
@@ -850,6 +867,14 @@
     rsContextBindProgramFragment((RsProgramFragment)pf);
 }
 
+static void
+nContextBindProgramVertex(JNIEnv *_env, jobject _this, jint pf)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf);
+    rsContextBindProgramVertex((RsProgramVertex)pf);
+}
+
 // ---------------------------------------------------------------------------
 
 static void
@@ -929,6 +954,7 @@
 {"nTriangleMeshAddVertex_XYZ",     "(FFF)V",                               (void*)nTriangleMeshAddVertex_XYZ },
 {"nTriangleMeshAddVertex_XY_ST",   "(FFFF)V",                              (void*)nTriangleMeshAddVertex_XY_ST },
 {"nTriangleMeshAddVertex_XYZ_ST",  "(FFFFF)V",                             (void*)nTriangleMeshAddVertex_XYZ_ST },
+{"nTriangleMeshAddVertex_XYZ_ST_NORM",  "(FFFFFFFF)V",                     (void*)nTriangleMeshAddVertex_XYZ_ST_NORM },
 {"nTriangleMeshAddTriangle",       "(III)V",                               (void*)nTriangleMeshAddTriangle },
 {"nTriangleMeshCreate",            "()I",                                  (void*)nTriangleMeshCreate },
 
@@ -977,11 +1003,13 @@
 {"nProgramVertexSetCameraMode",    "(Z)V",                                 (void*)nProgramVertexSetCameraMode },
 {"nProgramVertexSetTextureMatrixEnable",   "(Z)V",                         (void*)nProgramVertexSetTextureMatrixEnable },
 {"nProgramVertexSetModelMatrixEnable",  "(Z)V",                            (void*)nProgramVertexSetModelMatrixEnable },
+{"nProgramVertexSetProjectionMatrixEnable",  "(Z)V",                       (void*)nProgramVertexSetProjectionMatrixEnable },
 {"nProgramVertexCreate",           "()I",                                  (void*)nProgramVertexCreate },
 
 {"nContextBindRootScript",         "(I)V",                                 (void*)nContextBindRootScript },
 {"nContextBindProgramFragmentStore","(I)V",                                (void*)nContextBindProgramFragmentStore },
 {"nContextBindProgramFragment",    "(I)V",                                 (void*)nContextBindProgramFragment },
+{"nContextBindProgramVertex",      "(I)V",                                 (void*)nContextBindProgramVertex },
 
 {"nSamplerDestroy",                "(I)V",                                 (void*)nSamplerDestroy },
 {"nSamplerBegin",                  "()V",                                  (void*)nSamplerBegin },
diff --git a/rs.spec b/rs.spec
index 74445d3..107096f 100644
--- a/rs.spec
+++ b/rs.spec
@@ -415,3 +415,7 @@
 	param bool enable
 	}
 
+ProgramVertexSetProjectionMatrixEnable {
+	param bool enable
+	}
+
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
index a80e2f7..fc26ab5 100644
--- a/rsProgramVertex.cpp
+++ b/rsProgramVertex.cpp
@@ -47,7 +47,7 @@
 
     glMatrixMode(GL_PROJECTION);
     if (mProjectionEnable) {
-        //glLoadMatrixf(&f[OFFSET_PROJECTION]);
+        glLoadMatrixf(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
     } else {
     }
 
@@ -57,7 +57,6 @@
     } else {
         glLoadIdentity();
     }
-
 }
 
 void ProgramVertex::setConstantType(uint32_t slot, const Type *t)
@@ -126,6 +125,11 @@
     rsc->mStateVertex.mPV->setTransformEnable(enable);
 }
 
+void rsi_ProgramVertexSetProjectionMatrixEnable(Context *rsc, bool enable)
+{
+    rsc->mStateVertex.mPV->setProjectionEnable(enable);
+}
+
 
 
 }
diff --git a/rsProgramVertex.h b/rsProgramVertex.h
index cd46900..677be6e 100644
--- a/rsProgramVertex.h
+++ b/rsProgramVertex.h
@@ -40,6 +40,7 @@
     void setTextureMatrixEnable(bool e) {mTextureMatrixEnable = e;}
     void setProjectionEnabled(bool e) {mProjectionEnable = e;}
     void setTransformEnable(bool e) {mTransformEnable = e;}
+    void setProjectionEnable(bool e) {mProjectionEnable = e;}
 
 protected:
     bool mDirty;
diff --git a/rsTriangleMesh.h b/rsTriangleMesh.h
index 67f964f..4e15d5a 100644
--- a/rsTriangleMesh.h
+++ b/rsTriangleMesh.h
@@ -35,7 +35,7 @@
 
 
 // An element is a group of Components that occupies one cell in a structure.
-class TriangleMesh
+class TriangleMesh : public ObjectBase
 {
 public:
     TriangleMesh();