Add Galaxy wallpaper
diff --git a/java/Galaxy/Android.mk b/java/Galaxy/Android.mk
new file mode 100644
index 0000000..0884e18
--- /dev/null
+++ b/java/Galaxy/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 := GalaxyRS
+
+include $(BUILD_PACKAGE)
diff --git a/java/Galaxy/AndroidManifest.xml b/java/Galaxy/AndroidManifest.xml
new file mode 100644
index 0000000..6da1e0f
--- /dev/null
+++ b/java/Galaxy/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.galaxy.rs">
+
+    <application android:label="GalaxyRS">
+
+        <activity
+            android:screenOrientation="portrait"
+            android:name="Galaxy"
+            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/java/Galaxy/res/drawable-hdpi/flares.png b/java/Galaxy/res/drawable-hdpi/flares.png
new file mode 100644
index 0000000..fbaaafb
--- /dev/null
+++ b/java/Galaxy/res/drawable-hdpi/flares.png
Binary files differ
diff --git a/java/Galaxy/res/drawable-hdpi/light1.png b/java/Galaxy/res/drawable-hdpi/light1.png
new file mode 100644
index 0000000..9d5a795
--- /dev/null
+++ b/java/Galaxy/res/drawable-hdpi/light1.png
Binary files differ
diff --git a/java/Galaxy/res/drawable-hdpi/light2.png b/java/Galaxy/res/drawable-hdpi/light2.png
new file mode 100644
index 0000000..86a6d2e
--- /dev/null
+++ b/java/Galaxy/res/drawable-hdpi/light2.png
Binary files differ
diff --git a/java/Galaxy/res/drawable-hdpi/space.jpg b/java/Galaxy/res/drawable-hdpi/space.jpg
new file mode 100644
index 0000000..b61f6a3
--- /dev/null
+++ b/java/Galaxy/res/drawable-hdpi/space.jpg
Binary files differ
diff --git a/java/Galaxy/res/raw/galaxy.c b/java/Galaxy/res/raw/galaxy.c
new file mode 100644
index 0000000..ab82b58
--- /dev/null
+++ b/java/Galaxy/res/raw/galaxy.c
@@ -0,0 +1,181 @@
+// 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.
+
+#pragma version(1)
+#pragma stateVertex(PVBackground)
+#pragma stateFragment(PFBackground)
+#pragma stateFragmentStore(PFSBackground)
+
+#define RSID_STATE 0
+#define RSID_FRAME_COUNT 0
+#define RSID_WIDTH 1
+#define RSID_HEIGHT 2
+#define RSID_PARTICLES_COUNT 3
+#define RSID_GALAXY_RADIUS 4
+
+#define RSID_PARTICLES 1
+
+#define PARTICLE_STRUCT_FIELDS_COUNT 7
+#define PARTICLE_STRUCT_ANGLE 0
+#define PARTICLE_STRUCT_DISTANCE 1
+#define PARTICLE_STRUCT_SPEED 2
+#define PARTICLE_STRUCT_Z 3
+#define PARTICLE_STRUCT_RADIUS 4
+#define PARTICLE_STRUCT_U1 5
+#define PARTICLE_STRUCT_U2 6
+
+#define RSID_PARTICLES_BUFFER 2
+#define PARTICLE_BUFFER_COMPONENTS_COUNT 6
+
+#define PARTICLES_TEXTURES_COUNT 2
+
+#define ELLIPSE_RATIO 0.86f
+#define ELLIPSE_TWIST 0.02333333333f
+
+void drawSpace(int width, int height) {
+    bindTexture(NAMED_PFBackground, 0, NAMED_TSpace);
+    drawQuadTexCoords(
+            0.0f, 0.0f, 0.0f,
+            0.0f, 1.0f,
+            width, 0.0f, 0.0f,
+            2.0f, 1.0f,
+            width, height, 0.0f,
+            2.0f, 0.0f,
+            0.0f, height, 0.0f,
+            0.0f, 0.0f);
+}
+
+void drawLights(int width, int height) {
+    bindProgramFragment(NAMED_PFBackground);
+    bindProgramFragmentStore(NAMED_PFSLights);
+
+    float x = (width - 512.0f) / 2.0f;
+    float y = (height - 512.0f) / 2.0f;
+
+    bindTexture(NAMED_PFBackground, 0, NAMED_TLight1);
+    drawQuad(x + 512.0f, y         , 0.0f,
+             x         , y         , 0.0f,
+             x         , y + 512.0f, 0.0f,
+             x + 512.0f, y + 512.0f, 0.0f);
+
+    bindTexture(NAMED_PFBackground, 0, NAMED_TLight2);
+    drawQuad(x + 512.0f, y         , 0.0f,
+             x         , y         , 0.0f,
+             x         , y + 512.0f, 0.0f,
+             x + 512.0f, y + 512.0f, 0.0f);
+}
+
+void drawParticle(int index, int bufferIndex, int width, int height, int radius) {
+    float *particle = loadArrayF(RSID_PARTICLES, index);
+
+    float distance = particle[PARTICLE_STRUCT_DISTANCE];
+    float angle = particle[PARTICLE_STRUCT_ANGLE];
+    float speed = particle[PARTICLE_STRUCT_SPEED];
+    float r = particle[PARTICLE_STRUCT_RADIUS];
+
+    int red;
+    int green;
+    int blue;
+
+    if (distance < radius / 3.0f) {
+        red = 220 + (distance / (float) radius) * 35;
+        green = 220;
+        blue = 220;
+    } else {
+        red = 180;
+        green = 180;
+        blue = clamp(140 + (distance / (float) radius) * 115, 140, 255);
+    }
+
+    int color = 0xFF000000 | red | green << 8 | blue << 16;
+
+    float a = angle + speed * (0.5f + (0.5f * radius / distance));
+    float x = distance * sinf(a);
+    float y = distance * cosf(a) * ELLIPSE_RATIO;
+    float z = distance * ELLIPSE_TWIST;
+    float s = cosf(z);
+    float t = sinf(z);
+
+    float sX = t * x + s * y + width / 2.0f;
+    float sY = s * x - t * y + height / 2.0f;
+    float sZ = particle[PARTICLE_STRUCT_Z];
+
+    float u1 = particle[PARTICLE_STRUCT_U1];
+    float u2 = particle[PARTICLE_STRUCT_U2];
+
+    // lower left vertex of the particle's triangle
+    storeI32(RSID_PARTICLES_BUFFER, bufferIndex, color);        // ABGR
+
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 1, sX - r);     // X
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 2, sY + r);     // Y
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 3, sZ);         // Z
+
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 4, u1);         // S
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 5, 1.0f);       // T
+
+    // lower right vertex of the particle's triangle
+    bufferIndex += PARTICLE_BUFFER_COMPONENTS_COUNT;
+    storeI32(RSID_PARTICLES_BUFFER, bufferIndex, color);
+
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 1, sX + r);
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 2, sY + r);
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 3, sZ);
+
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 4, u2);
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 5, 1.0f);
+
+    // upper middle vertex of the particle's triangle
+    bufferIndex += PARTICLE_BUFFER_COMPONENTS_COUNT;
+    storeI32(RSID_PARTICLES_BUFFER, bufferIndex, color);
+
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 1, sX);
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 2, sY - r);
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 3, sZ);
+
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 4, u1 + (u2 - u1) / 2.0f);
+    storeF(RSID_PARTICLES_BUFFER, bufferIndex + 5, 0.0f);
+
+    particle[PARTICLE_STRUCT_ANGLE] = a;
+}
+
+void drawParticles(int width, int height) {
+    bindProgramFragment(NAMED_PFLighting);
+    bindTexture(NAMED_PFLighting, 0, NAMED_TFlares);
+
+    int radius = loadI32(RSID_STATE, RSID_GALAXY_RADIUS);
+    int particlesCount = loadI32(RSID_STATE, RSID_PARTICLES_COUNT);
+    int count = particlesCount * PARTICLE_STRUCT_FIELDS_COUNT;
+
+    int i = 0;
+    int bufferIndex = 0;
+    for ( ; i < count; i += PARTICLE_STRUCT_FIELDS_COUNT) {
+        drawParticle(i, bufferIndex, width, height, radius);
+        // each particle is a triangle (3 vertices) of 6 properties (ABGR, X, Y, Z, S, T)
+        bufferIndex += 3 * PARTICLE_BUFFER_COMPONENTS_COUNT;
+    }
+
+    uploadToBufferObject(NAMED_BParticles);
+    drawSimpleMeshRange(NAMED_MParticles, 0, particlesCount * 3);
+}
+
+int main(int index) {
+    int width = loadI32(RSID_STATE, RSID_WIDTH);
+    int height = loadI32(RSID_STATE, RSID_HEIGHT);
+
+    drawSpace(width, height);
+    drawParticles(width, height);
+    drawLights(width, height);
+
+    return 1;
+}
diff --git a/java/Galaxy/src/com/android/galaxy/rs/Galaxy.java b/java/Galaxy/src/com/android/galaxy/rs/Galaxy.java
new file mode 100644
index 0000000..27d333c
--- /dev/null
+++ b/java/Galaxy/src/com/android/galaxy/rs/Galaxy.java
@@ -0,0 +1,46 @@
+/*
+ * 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.galaxy.rs;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class Galaxy extends Activity {
+    private GalaxyView mView;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mView = new GalaxyView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mView.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mView.onPause();
+
+        Runtime.getRuntime().exit(0);
+    }
+}
\ No newline at end of file
diff --git a/java/Galaxy/src/com/android/galaxy/rs/GalaxyRS.java b/java/Galaxy/src/com/android/galaxy/rs/GalaxyRS.java
new file mode 100644
index 0000000..33de229
--- /dev/null
+++ b/java/Galaxy/src/com/android/galaxy/rs/GalaxyRS.java
@@ -0,0 +1,332 @@
+/*
+ * 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.galaxy.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.ProgramVertex;
+import android.renderscript.Allocation;
+import android.renderscript.Sampler;
+import android.renderscript.Element;
+import android.renderscript.SimpleMesh;
+import android.renderscript.Primitive;
+import static android.renderscript.Sampler.Value.LINEAR;
+import static android.renderscript.Sampler.Value.CLAMP;
+import static android.renderscript.Sampler.Value.WRAP;
+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 static android.util.MathUtils.*;
+
+import java.util.TimeZone;
+
+class GalaxyRS {
+    private static final int GALAXY_RADIUS = 300;
+    private static final int PARTICLES_COUNT = 12000;
+    private static final float GALAXY_HEIGHT = 0.1f;
+
+    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_STATE_PARTICLES_COUNT = 3;
+    private static final int RSID_STATE_GALAXY_RADIUS = 4;
+
+    private static final int TEXTURES_COUNT = 4;
+    private static final int PARTICLES_TEXTURES_COUNT = 2;
+    private static final int RSID_TEXTURE_SPACE = 0;
+    private static final int RSID_TEXTURE_LIGHT1 = 1;
+    private static final int RSID_TEXTURE_LIGHT2 = 2;
+    private static final int RSID_TEXTURE_FLARES = 3;
+
+    private static final int RSID_PARTICLES = 1;
+    private static final int PARTICLE_STRUCT_FIELDS_COUNT = 7;
+    private static final int PARTICLE_STRUCT_ANGLE = 0;
+    private static final int PARTICLE_STRUCT_DISTANCE = 1;
+    private static final int PARTICLE_STRUCT_SPEED = 2;
+    private static final int PARTICLE_STRUCT_Z = 3;
+    private static final int PARTICLE_STRUCT_RADIUS = 4;
+    private static final int PARTICLE_STRUCT_U1 = 5;
+    private static final int PARTICLE_STRUCT_U2 = 6;
+
+    private static final int RSID_PARTICLES_BUFFER = 2;
+
+    private Resources mResources;
+    private RenderScript mRS;
+
+    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
+
+    private final int mWidth;
+    private final int mHeight;
+
+    private ScriptC mScript;
+    private Sampler mSampler;
+    private Sampler mLightSampler;
+    private ProgramFragment mPfBackground;
+    private ProgramFragment mPfLighting;
+    private ProgramStore mPfsBackground;
+    private ProgramStore mPfsLights;
+    private ProgramVertex mPvBackground;
+    private ProgramVertex.MatrixAllocation mPvOrthoAlloc;
+
+    private Allocation[] mTextures;
+
+    private Allocation mState;
+    private Allocation mParticles;
+    private Allocation mParticlesBuffer;
+    private SimpleMesh mParticlesMesh;
+
+    public GalaxyRS(int width, int height) {
+        mWidth = width;
+        mHeight = height;
+        mOptionsARGB.inScaled = false;
+        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
+    }
+
+    public void init(RenderScript rs, Resources res) {
+        mRS = rs;
+        mResources = res;
+        initRS();
+    }
+
+    public void destroy() {
+        mScript.destroy();
+        mSampler.destroy();
+        mLightSampler.destroy();
+        mPfBackground.destroy();
+        mPfsBackground.destroy();
+        mPvBackground.destroy();
+        mPvOrthoAlloc.mAlloc.destroy();
+        for (Allocation a : mTextures) {
+            a.destroy();
+        }
+        mState.destroy();
+        mPfLighting.destroy();
+        mParticles.destroy();
+        mPfsLights.destroy();
+        mParticlesMesh.destroy();
+        mParticlesBuffer.destroy();
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            destroy();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    private void initRS() {
+        createProgramVertex();
+        createProgramFragmentStore();
+        createProgramFragment();
+        createScriptStructures();
+        loadTextures();
+
+        ScriptC.Builder sb = new ScriptC.Builder(mRS);
+        sb.setScript(mResources, R.raw.galaxy);
+        sb.setRoot(true);
+        mScript = sb.create();
+        mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+        mScript.setTimeZone(TimeZone.getDefault().getID());
+
+        mScript.bindAllocation(mState, RSID_STATE);
+        mScript.bindAllocation(mParticles, RSID_PARTICLES);
+        mScript.bindAllocation(mParticlesBuffer, RSID_PARTICLES_BUFFER);
+
+        mRS.contextBindRootScript(mScript);
+    }
+
+    private void createScriptStructures() {
+        createState();
+        createParticles();
+        createParticlesMesh();
+    }
+
+    private void createParticlesMesh() {
+        final Element.Builder elementBuilder = new Element.Builder(mRS);
+        elementBuilder.add(Element.DataType.UNSIGNED, Element.DataKind.RED, true, 8);
+        elementBuilder.add(Element.DataType.UNSIGNED, Element.DataKind.GREEN, true, 8);
+        elementBuilder.add(Element.DataType.UNSIGNED, Element.DataKind.BLUE, true, 8);
+        elementBuilder.add(Element.DataType.UNSIGNED, Element.DataKind.ALPHA, true, 8);
+        elementBuilder.add(Element.DataType.FLOAT, Element.DataKind.X, false, 32);
+        elementBuilder.add(Element.DataType.FLOAT, Element.DataKind.Y, false, 32);
+        elementBuilder.add(Element.DataType.FLOAT, Element.DataKind.Z, false, 32);
+        elementBuilder.add(Element.DataType.FLOAT, Element.DataKind.S, false, 32);
+        elementBuilder.add(Element.DataType.FLOAT, Element.DataKind.T, false, 32);
+        final Element vertexElement = elementBuilder.create();
+
+        final SimpleMesh.Builder meshBuilder = new SimpleMesh.Builder(mRS);
+        final int vertexSlot = meshBuilder.addVertexType(vertexElement, PARTICLES_COUNT * 3);
+        meshBuilder.setPrimitive(Primitive.TRIANGLE);
+        mParticlesMesh = meshBuilder.create();
+        mParticlesMesh.setName("MParticles");
+
+        mParticlesBuffer = mParticlesMesh.createVertexAllocation(vertexSlot);
+        mParticlesBuffer.setName("BParticles");
+        mParticlesMesh.bindVertexAllocation(mParticlesBuffer, 0);
+    }
+
+    private void createParticles() {
+        final float[] particles = new float[PARTICLES_COUNT * PARTICLE_STRUCT_FIELDS_COUNT];
+        mParticles = Allocation.createSized(mRS, USER_FLOAT, particles.length);
+        for (int i = 0; i < particles.length; i += PARTICLE_STRUCT_FIELDS_COUNT) {
+            createParticle(particles, i);
+        }
+        mParticles.data(particles);
+    }
+
+    private void createState() {
+        final int[] data = new int[5];
+
+        mState = Allocation.createSized(mRS, USER_I32, data.length);
+        data[RSID_STATE_FRAMECOUNT] = 0;
+        data[RSID_STATE_WIDTH] = mWidth;
+        data[RSID_STATE_HEIGHT] = mHeight;
+        data[RSID_STATE_PARTICLES_COUNT] = PARTICLES_COUNT;
+        data[RSID_STATE_GALAXY_RADIUS] = GALAXY_RADIUS;
+        mState.data(data);
+    }
+
+    @SuppressWarnings({"PointlessArithmeticExpression"})
+    private void createParticle(float[] particles, int index) {
+        int sprite = random(PARTICLES_TEXTURES_COUNT);
+        float d = abs(randomGauss()) * GALAXY_RADIUS / 2.0f;
+
+        particles[index + PARTICLE_STRUCT_ANGLE] = random(0.0f, (float) (Math.PI * 2.0));
+        particles[index + PARTICLE_STRUCT_DISTANCE] = d;
+        particles[index + PARTICLE_STRUCT_SPEED] = random(0.0015f, 0.0025f);
+        particles[index + PARTICLE_STRUCT_Z] = randomGauss() * GALAXY_HEIGHT *
+                (GALAXY_RADIUS - d) / (float) GALAXY_RADIUS;
+        particles[index + PARTICLE_STRUCT_RADIUS] = random(3.0f, 7.5f);
+        particles[index + PARTICLE_STRUCT_U1] = sprite / (float) PARTICLES_TEXTURES_COUNT;
+        particles[index + PARTICLE_STRUCT_U2] = (sprite + 1) / (float) PARTICLES_TEXTURES_COUNT;
+    }
+
+    private static float randomGauss() {
+        float x1;
+        float x2;
+        float w;
+
+        do {
+            x1 = 2.0f * random(0.0f, 1.0f) - 1.0f;
+            x2 = 2.0f * random(0.0f, 1.0f) - 1.0f;
+            w = x1 * x1 + x2 * x2;
+        } while (w >= 1.0f);
+
+        w = (float) Math.sqrt(-2.0 * log(w) / w);
+        return x1 * w;
+    }
+    
+    private void loadTextures() {
+        mTextures = new Allocation[TEXTURES_COUNT];
+
+        final Allocation[] textures = mTextures;
+        textures[RSID_TEXTURE_SPACE] = loadTexture(R.drawable.space, "TSpace");
+        textures[RSID_TEXTURE_LIGHT1] = loadTextureARGB(R.drawable.light1, "TLight1");
+        textures[RSID_TEXTURE_LIGHT2] = loadTextureARGB(R.drawable.light2, "TLight2");
+        textures[RSID_TEXTURE_FLARES] = loadTextureARGB(R.drawable.flares, "TFlares");
+
+        final int count = textures.length;
+        for (int i = 0; i < count; i++) {
+            final Allocation texture = textures[i];
+            texture.uploadToTexture(0);
+        }
+    }
+
+    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) {
+        Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);
+        final Allocation allocation = Allocation.createFromBitmap(mRS, b, RGBA_8888, false);
+        allocation.setName(name);
+        return allocation;
+    }    
+
+    private void createProgramFragment() {
+        Sampler.Builder sampleBuilder = new Sampler.Builder(mRS);
+        sampleBuilder.setMin(LINEAR);
+        sampleBuilder.setMag(LINEAR);
+        sampleBuilder.setWrapS(WRAP);
+        sampleBuilder.setWrapT(WRAP);
+        mSampler = sampleBuilder.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);
+
+        sampleBuilder = new Sampler.Builder(mRS);
+        sampleBuilder.setMin(LINEAR);
+        sampleBuilder.setMag(LINEAR);
+        sampleBuilder.setWrapS(CLAMP);
+        sampleBuilder.setWrapT(CLAMP);
+        mLightSampler = sampleBuilder.create();
+
+        builder = new ProgramFragment.Builder(mRS, null, null);
+        builder.setTexEnable(true, 0);
+        builder.setTexEnvMode(MODULATE, 0);
+        mPfLighting = builder.create();
+        mPfLighting.setName("PFLighting");
+        mPfLighting.bindSampler(mLightSampler, 0);
+    }
+
+    private void createProgramFragmentStore() {
+        ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null);
+        builder.setDepthFunc(ALWAYS);
+        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+        builder.setDitherEnable(false);
+        builder.setDepthMask(true);
+        mPfsBackground = builder.create();
+        mPfsBackground.setName("PFSBackground");
+        
+        builder = new ProgramStore.Builder(mRS, null, null);
+        builder.setDepthFunc(ALWAYS);
+        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
+        builder.setDitherEnable(false);
+        builder.setDepthMask(true);
+        mPfsLights = builder.create();
+        mPfsLights.setName("PFSLights");
+    }
+
+    private void createProgramVertex() {
+        mPvOrthoAlloc = new ProgramVertex.MatrixAllocation(mRS);
+        //mPvOrthoAlloc.setupProjectionNormalized(mWidth, mHeight);
+        mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);        
+
+        ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS, null, null);
+        builder.setTextureMatrixEnable(true);
+        mPvBackground = builder.create();
+        mPvBackground.bindAllocation(mPvOrthoAlloc);
+        mPvBackground.setName("PVBackground");
+    }
+}
diff --git a/java/Galaxy/src/com/android/galaxy/rs/GalaxyView.java b/java/Galaxy/src/com/android/galaxy/rs/GalaxyView.java
new file mode 100644
index 0000000..341293b
--- /dev/null
+++ b/java/Galaxy/src/com/android/galaxy/rs/GalaxyView.java
@@ -0,0 +1,45 @@
+/*
+ * 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.galaxy.rs;
+
+import android.content.Context;
+import android.view.SurfaceHolder;
+import android.renderscript.RenderScript;
+import android.renderscript.RSSurfaceView;
+
+class GalaxyView extends RSSurfaceView {
+    private GalaxyRS mRender;
+
+    public GalaxyView(Context context) {
+        super(context);
+        setFocusable(true);
+        setFocusableInTouchMode(true);
+    }
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
+
+        RenderScript RS = createRenderScript();
+        mRender = new GalaxyRS(w, h);
+        mRender.init(RS, getResources());
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        if (mRender != null) mRender.destroy();
+    }
+}