Add Mandelbrot test to ImageProcessing.

Change-Id: I1d5478d58609394111410fbfd9f48b5018f385b1
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 7b84355..f5d3ee2 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -203,6 +203,9 @@
         case 26:
             mTest = new Convolve5x5(true);
             break;
+        case 27:
+            mTest = new Mandelbrot();
+            break;
         }
 
         mTest.createBaseTest(this, mBitmapIn);
@@ -215,7 +218,7 @@
     }
 
     void setupTests() {
-        mTestNames = new String[27];
+        mTestNames = new String[28];
         mTestNames[0] = "Levels Vec3 Relaxed";
         mTestNames[1] = "Levels Vec4 Relaxed";
         mTestNames[2] = "Levels Vec3 Full";
@@ -243,6 +246,8 @@
         mTestNames[24] = "CrossProcess (using LUT)";
         mTestNames[25] = "Convolve 5x5";
         mTestNames[26] = "Intrinsics Convolve 5x5";
+        mTestNames[27] = "Mandelbrot";
+
         mTestSpinner.setAdapter(new ArrayAdapter<String>(
             this, R.layout.spinner_layout, mTestNames));
     }
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Mandelbrot.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Mandelbrot.java
new file mode 100644
index 0000000..20036e6
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Mandelbrot.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2012 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.rs.image;
+
+import java.lang.Math;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
+import android.renderscript.Type;
+import android.util.Log;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+public class Mandelbrot extends TestBase {
+    private ScriptC_mandelbrot mScript;
+
+    public boolean onBar1Setup(SeekBar b, TextView t) {
+        t.setText("Iterations");
+        b.setProgress(0);
+        return true;
+    }
+
+    public void onBar1Changed(int progress) {
+        int iters = progress * 3 + 50;
+        mScript.set_gMaxIteration(iters);
+    }
+
+    public boolean onBar2Setup(SeekBar b, TextView t) {
+        t.setText("Lower Bound: X");
+        b.setProgress(0);
+        return true;
+    }
+
+    public void onBar2Changed(int progress) {
+        float scaleFactor = mScript.get_scaleFactor();
+        // allow viewport to be moved by 2x scale factor
+        float lowerBoundX = -2.f + ((progress / scaleFactor) / 50.f);
+        mScript.set_lowerBoundX(lowerBoundX);
+    }
+
+    public boolean onBar3Setup(SeekBar b, TextView t) {
+        t.setText("Lower Bound: Y");
+        b.setProgress(0);
+        return true;
+    }
+
+    public void onBar3Changed(int progress) {
+        float scaleFactor = mScript.get_scaleFactor();
+        // allow viewport to be moved by 2x scale factor
+        float lowerBoundY = -2.f + ((progress / scaleFactor) / 50.f);
+        mScript.set_lowerBoundY(lowerBoundY);
+    }
+
+    public boolean onBar4Setup(SeekBar b, TextView t) {
+        t.setText("Scale Factor");
+        b.setProgress(0);
+        return true;
+    }
+
+    public void onBar4Changed(int progress) {
+        float scaleFactor = 4.f - (3.96f * (progress / 100.f));
+        mScript.set_scaleFactor(scaleFactor);
+    }
+
+    public void createTest(android.content.res.Resources res) {
+        int width = mOutPixelsAllocation.getType().getX();
+        int height = mOutPixelsAllocation.getType().getY();
+
+        mScript = new ScriptC_mandelbrot(mRS, res, R.raw.mandelbrot);
+        mScript.set_gDimX(width);
+        mScript.set_gDimY(height);
+        mScript.set_gMaxIteration(50);
+    }
+
+    public void runTest() {
+        mScript.forEach_root(mOutPixelsAllocation);
+        mRS.finish();
+    }
+
+}
+
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/mandelbrot.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/mandelbrot.rs
new file mode 100644
index 0000000..da81d2e
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/mandelbrot.rs
@@ -0,0 +1,56 @@
+// Copyright (C) 2011 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 rs java_package_name(com.android.rs.image)
+
+uint32_t gMaxIteration = 500;
+uint32_t gDimX = 1024;
+uint32_t gDimY = 1024;
+
+float lowerBoundX = -2.f;
+float lowerBoundY = -2.f;
+float scaleFactor = 4.f;
+
+void root(uchar4 *v_out, uint32_t x, uint32_t y) {
+  float2 p;
+  p.x = lowerBoundX + ((float)x / gDimX) * scaleFactor;
+  p.y = lowerBoundY + ((float)y / gDimY) * scaleFactor;
+
+  float2 t = 0;
+  float2 t2 = t * t;
+  int iter = 0;
+  while((t2.x + t2.y < 4.f) && (iter < gMaxIteration)) {
+    float xtemp = t2.x - t2.y + p.x;
+    t.y = 2 * t.x * t.y + p.y;
+    t.x = xtemp;
+    iter++;
+    t2 = t * t;
+  }
+
+  if(iter >= gMaxIteration) {
+    // write a non-transparent black pixel
+    *v_out = (uchar4){0, 0, 0, 0xff};
+  } else {
+    float mi3 = gMaxIteration / 3.;
+    if (iter <= (gMaxIteration / 3))
+      *v_out = (uchar4){0xff * (iter / mi3), 0, 0, 0xff};
+    else if (iter <= (((gMaxIteration / 3) * 2)))
+      *v_out = (uchar4){0xff - (0xff * ((iter - mi3) / mi3)),
+                        (0xff * ((iter - mi3) / mi3)), 0, 0xff};
+    else
+      *v_out = (uchar4){0, 0xff - (0xff * ((iter - (mi3 * 2)) / mi3)),
+                        (0xff * ((iter - (mi3 * 2)) / mi3)), 0xff};
+  }
+}