summaryrefslogtreecommitdiff
path: root/java/tests
diff options
context:
space:
mode:
authorYang Ni <yangni@google.com>2015-02-03 16:32:57 -0800
committerYang Ni <yangni@google.com>2015-03-11 20:01:04 +0000
commit5ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948 (patch)
treecb8501e52b07846f410cf21d51e4ac3cd741c421 /java/tests
parent062c287f573ecc06c38ee4295e5627e12c52ac3d (diff)
downloadrs-5ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948.tar.gz
Image Processing using the new Script Group API
Change-Id: I25daf8185d51ca37e124e5e30c4ec482ea9b86a5
Diffstat (limited to 'java/tests')
-rw-r--r--java/tests/ScriptGroupTest/Android.mk32
-rw-r--r--java/tests/ScriptGroupTest/AndroidManifest.xml17
-rw-r--r--java/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067.jpgbin0 -> 1062402 bytes
-rw-r--r--java/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067b.jpgbin0 -> 1205161 bytes
-rw-r--r--java/tests/ScriptGroupTest/res/layout/main.xml140
-rw-r--r--java/tests/ScriptGroupTest/res/layout/spinner_layout.xml23
-rw-r--r--java/tests/ScriptGroupTest/res/values/strings.xml37
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/Filters.java449
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/ScriptGroupTestActivity.java342
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/TestBase.java109
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/colormatrix_f.rs42
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/contrast_f.rs32
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/exposure_f.rs32
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/f4touc4.rs24
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_f.rsh59
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_relaxed_f.rs21
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/greyscale_f.rs24
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/ip.rsh20
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/levels_f.rsh56
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/levels_relaxed_f.rs21
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/shadows_f.rs191
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/uc4tof4.rs23
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vibrance_f.rs58
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_f.rsh58
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_relaxed_f.rs21
-rw-r--r--java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_f.rsh57
26 files changed, 1888 insertions, 0 deletions
diff --git a/java/tests/ScriptGroupTest/Android.mk b/java/tests/ScriptGroupTest/Android.mk
new file mode 100644
index 00000000..3c6269db
--- /dev/null
+++ b/java/tests/ScriptGroupTest/Android.mk
@@ -0,0 +1,32 @@
+#
+# 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_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ $(call all-renderscript-files-under, src)
+#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_RENDERSCRIPT_FLAGS := -target-api 0
+
+LOCAL_PACKAGE_NAME := ScriptGroupTest
+
+include $(BUILD_PACKAGE)
diff --git a/java/tests/ScriptGroupTest/AndroidManifest.xml b/java/tests/ScriptGroupTest/AndroidManifest.xml
new file mode 100644
index 00000000..24f6d6a4
--- /dev/null
+++ b/java/tests/ScriptGroupTest/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.rs.sgtest">
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-sdk android:minSdkVersion="17" />
+ <application android:label="Script Group Test"
+ android:hardwareAccelerated="true">
+ <uses-library android:name="android.test.runner" />
+ <activity android:name="ScriptGroupTestActivity">
+ <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/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067.jpg b/java/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067.jpg
new file mode 100644
index 00000000..05d3ee20
--- /dev/null
+++ b/java/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067.jpg
Binary files differ
diff --git a/java/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067b.jpg b/java/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067b.jpg
new file mode 100644
index 00000000..aed0781e
--- /dev/null
+++ b/java/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067b.jpg
Binary files differ
diff --git a/java/tests/ScriptGroupTest/res/layout/main.xml b/java/tests/ScriptGroupTest/res/layout/main.xml
new file mode 100644
index 00000000..dbb17245
--- /dev/null
+++ b/java/tests/ScriptGroupTest/res/layout/main.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/toplevel">
+ <SurfaceView
+ android:id="@+id/surface"
+ android:layout_width="1dip"
+ android:layout_height="1dip" />
+ <ScrollView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <ImageView
+ android:id="@+id/display"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/benchmark"
+ android:onClick="benchmark"/>
+ <TextView
+ android:id="@+id/benchmarkText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:text="@string/saturation"/>
+ </LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:id="@+id/layoutContainer" android:orientation="horizontal">
+ <RelativeLayout
+ android:layout_width="0dip"
+ android:layout_height="fill_parent"
+ android:layout_weight="0.40">
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:gravity="center"
+ android:text="@string/filter1_label"
+ />
+ </RelativeLayout>
+ <RelativeLayout
+ android:layout_width="0dip"
+ android:layout_height="fill_parent"
+ android:layout_weight="0.60">
+ <Spinner
+ android:id="@+id/filterselection"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+ </RelativeLayout>
+ </LinearLayout>
+
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:id="@+id/layoutContainer" android:orientation="horizontal">
+ <RelativeLayout
+ android:layout_width="0dip"
+ android:layout_height="fill_parent"
+ android:layout_weight="0.40">
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:gravity="center"
+ android:text="@string/filter2_label"
+ />
+ </RelativeLayout>
+ <RelativeLayout
+ android:layout_width="0dip"
+ android:layout_height="fill_parent"
+ android:layout_weight="0.60">
+ <Spinner
+ android:id="@+id/filter2selection"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+ </RelativeLayout>
+ </LinearLayout>
+
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:id="@+id/layoutContainer" android:orientation="horizontal">
+ <RelativeLayout
+ android:layout_width="0dip"
+ android:layout_height="fill_parent"
+ android:layout_weight="0.40">
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:gravity="center"
+ android:text="@string/mode_label"
+ />
+ </RelativeLayout>
+ <RelativeLayout
+ android:layout_width="0dip"
+ android:layout_height="fill_parent"
+ android:layout_weight="0.60">
+ <Spinner
+ android:id="@+id/modeselection"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+ </RelativeLayout>
+ </LinearLayout>
+
+ <Spinner
+ android:id="@+id/spinner1"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/benchmark_all"
+ android:onClick="benchmark_all"/>
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout>
+
diff --git a/java/tests/ScriptGroupTest/res/layout/spinner_layout.xml b/java/tests/ScriptGroupTest/res/layout/spinner_layout.xml
new file mode 100644
index 00000000..8196bbf0
--- /dev/null
+++ b/java/tests/ScriptGroupTest/res/layout/spinner_layout.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- 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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="10dp"
+ android:textSize="16sp"
+/>
diff --git a/java/tests/ScriptGroupTest/res/values/strings.xml b/java/tests/ScriptGroupTest/res/values/strings.xml
new file mode 100644
index 00000000..724d360b
--- /dev/null
+++ b/java/tests/ScriptGroupTest/res/values/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- General -->
+ <skip />
+ <!--slider label -->
+ <string name="blur_description">Blur Radius</string>
+ <string name="in_white">In White</string>
+ <string name="out_white">Out White</string>
+ <string name="in_black">In Black</string>
+ <string name="out_black">Out Black</string>
+ <string name="gamma">Gamma</string>
+ <string name="saturation">Saturation</string>
+ <string name="benchmark">Benchmark</string>
+ <string name="benchmark_all">Benchmark All</string>
+ <string name="filter1_label">Filter 1</string>
+ <string name="filter2_label">Filter 2</string>
+ <string name="mode_label">Mode</string>
+
+</resources>
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/Filters.java b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/Filters.java
new file mode 100644
index 00000000..c4f8a76b
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/Filters.java
@@ -0,0 +1,449 @@
+/*
+ * 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.sgtest;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Sampler;
+import android.renderscript.Script;
+import android.renderscript.Type;
+import android.renderscript.Matrix3f;
+import android.renderscript.Matrix4f;
+import android.renderscript.ScriptGroup;
+import android.renderscript.ScriptGroup2;
+import android.util.Log;
+
+import java.lang.reflect.Constructor;
+import java.lang.Math;
+import java.util.HashMap;
+
+public class Filters extends TestBase {
+
+ interface FilterInterface {
+ public void init();
+ public ScriptGroup2.Closure prepInit(ScriptGroup2.Builder b);
+ public Script.KernelID getKernelID();
+ public ScriptGroup2.Closure asyncLaunch(ScriptGroup2.Builder builder,
+ Object in, Type outputType);
+ public void forEach(Allocation in, Allocation out);
+ }
+
+ abstract class FilterBase implements FilterInterface {
+ public ScriptGroup2.Closure asyncLaunch(ScriptGroup2.Builder builder,
+ Object in, Type outputType) {
+ return builder.addKernel(getKernelID(), outputType, new Object[] { in },
+ new HashMap<Script.FieldID, Object>());
+ }
+ }
+
+ /*
+
+ Template for a subclass that implements Filter.
+
+ class Filter implements Filter {
+ Filter(RenderScript RS) { s = new ScriptC_(RS); }
+
+ void init() {}
+
+ Script.KernelID getKernelID() { return s.getKernelID_(); }
+
+ void forEach(Allocation in, Allocation out) { s.forEach_(in, out); }
+
+ private ScriptC_ s;
+ }
+ */
+
+ class ColorMatrixFilter extends FilterBase {
+ public ColorMatrixFilter(RenderScript RS) { s_mat = new ScriptC_colormatrix_f(RS); }
+
+ public void init() { }
+
+ public ScriptGroup2.Closure prepInit(ScriptGroup2.Builder b) { /* TODO */ return null; }
+
+ public Script.KernelID getKernelID() { return s_mat.getKernelID_colormatrix(); }
+
+ public void forEach(Allocation in, Allocation out) { s_mat.forEach_colormatrix(in, out); }
+
+ private ScriptC_colormatrix_f s_mat;
+ }
+
+ class ContrastFilter extends FilterBase {
+ public ContrastFilter(RenderScript RS) { s = new ScriptC_contrast_f(RS); }
+
+ public void init() {}
+
+ public ScriptGroup2.Closure prepInit(ScriptGroup2.Builder b) { return null; }
+
+ public Script.KernelID getKernelID() { return s.getKernelID_contrast(); }
+
+ public void forEach(Allocation in, Allocation out) { s.forEach_contrast(in, out); }
+
+ private ScriptC_contrast_f s;
+ }
+
+ class ExposureFilter extends FilterBase {
+ public ExposureFilter(RenderScript RS) { s = new ScriptC_exposure_f(RS); }
+
+ public void init() {}
+
+ public ScriptGroup2.Closure prepInit(ScriptGroup2.Builder b) { return null; }
+
+ public Script.KernelID getKernelID() { return s.getKernelID_exposure(); }
+
+ public void forEach(Allocation in, Allocation out) { s.forEach_exposure(in, out); }
+
+ private ScriptC_exposure_f s;
+ }
+
+ class FisheyeFilter extends FilterBase {
+ public FisheyeFilter(RenderScript RS) {
+ mRS = RS;
+ s = new ScriptC_fisheye_approx_relaxed_f(RS);
+ }
+
+ public void init() {
+ // s.set_sampler(Sampler.CLAMP_LINEAR(mRS));
+ }
+
+ public ScriptGroup2.Closure prepInit(ScriptGroup2.Builder b) {
+ return b.addInvoke(s.getInvokeID_init_filter(),
+ new Object[] { new Integer(dimX), new Integer(dimY),
+ new Float(0.5f), new Float(0.5f), new Float(0.5f),
+ Sampler.CLAMP_LINEAR(mRS)},
+ new HashMap<Script.FieldID, Object>());
+ }
+
+ public Script.KernelID getKernelID() { return s.getKernelID_fisheye(); }
+
+ public ScriptGroup2.Closure asyncLaunch(ScriptGroup2.Builder builder,
+ Object in, Type outputType) {
+ HashMap<Script.FieldID, Object> globals = new HashMap<Script.FieldID, Object>();
+ globals.put(s.getFieldID_in_alloc(), in);
+ //globals.put(s.getFieldID_sampler(), Sampler.CLAMP_LINEAR(mRS));
+ return builder.addKernel(getKernelID(), outputType, new Object[0], globals);
+ }
+
+ public void forEach(Allocation in, Allocation out) {
+ s.set_in_alloc(in);
+ s.forEach_fisheye(out);
+ }
+
+ private RenderScript mRS;
+ private ScriptC_fisheye_approx_relaxed_f s;
+ private final int dimX=1067, dimY=1600;
+ }
+
+ class GreyFilter extends FilterBase {
+ public GreyFilter(RenderScript RS) { s = new ScriptC_greyscale_f(RS); }
+
+ public void init() {}
+
+ public ScriptGroup2.Closure prepInit(ScriptGroup2.Builder b) { return null; }
+
+ public Script.KernelID getKernelID() { return s.getKernelID_greyscale(); }
+
+ public void forEach(Allocation in, Allocation out) { s.forEach_greyscale(in, out); }
+
+ private ScriptC_greyscale_f s;
+ }
+
+ class LevelsFilter extends FilterBase {
+ public LevelsFilter(RenderScript RS) { s = new ScriptC_levels_relaxed_f(RS); }
+ private final float mSaturation = 1.0f;
+ private final float mInBlack = 0.0f; // 0-255
+ private final float mOutBlack = 0.0f; // 0-255
+ private final float mInWhite = 255.0f; // 0-255
+ private final float mOutWhite = 255.0f; // 0-255
+ private final float mInWMinInB = mInWhite - mInBlack;
+ private final float mOutWMinOutB = mOutWhite - mOutBlack;
+ private final float mOverInWMinInB = 1.f / mInWMinInB;
+ private Matrix3f mSatMatrix;
+
+ private void setLevels() {
+ s.set_inBlack(mInBlack);
+ s.set_outBlack(mOutBlack);
+ s.set_inWMinInB(mInWMinInB);
+ s.set_outWMinOutB(mOutWMinOutB);
+ s.set_overInWMinInB(mOverInWMinInB);
+ }
+
+ private void setSaturation() {
+ Matrix3f satMatrix = new Matrix3f();
+ float rWeight = 0.299f;
+ float gWeight = 0.587f;
+ float bWeight = 0.114f;
+ float oneMinusS = 1.0f - mSaturation;
+
+ satMatrix.set(0, 0, oneMinusS * rWeight + mSaturation);
+ satMatrix.set(0, 1, oneMinusS * rWeight);
+ satMatrix.set(0, 2, oneMinusS * rWeight);
+ satMatrix.set(1, 0, oneMinusS * gWeight);
+ satMatrix.set(1, 1, oneMinusS * gWeight + mSaturation);
+ satMatrix.set(1, 2, oneMinusS * gWeight);
+ satMatrix.set(2, 0, oneMinusS * bWeight);
+ satMatrix.set(2, 1, oneMinusS * bWeight);
+ satMatrix.set(2, 2, oneMinusS * bWeight + mSaturation);
+ s.set_colorMat(satMatrix);
+
+ mSatMatrix = satMatrix;
+ }
+
+ public void init() {
+ setSaturation();
+ setLevels();
+ }
+
+ public ScriptGroup2.Closure prepInit(ScriptGroup2.Builder b) {
+ return b.addInvoke(s.getInvokeID_initialize(),
+ new Object[] { new Float(mInBlack), new Float(mOutBlack),
+ new Float(mInWMinInB), new Float(mOutWMinOutB),
+ new Float(mOverInWMinInB), mSatMatrix },
+ new HashMap<Script.FieldID, Object>());
+ }
+
+ public Script.KernelID getKernelID() { return s.getKernelID_levels_v4(); }
+
+ public void forEach(Allocation in, Allocation out) { s.forEach_levels_v4(in, out); }
+
+ private ScriptC_levels_relaxed_f s;
+ }
+
+ class ShadowsFilter extends FilterBase {
+ public ShadowsFilter(RenderScript RS) { s = new ScriptC_shadows_f(RS); }
+
+ public void init() { s.invoke_prepareShadows(50.f); }
+
+ public ScriptGroup2.Closure prepInit(ScriptGroup2.Builder b) {
+ cInit = b.addInvoke(s.getInvokeID_prepareShadows(),
+ new Object[] { new Float(50.f) },
+ new HashMap<Script.FieldID, Object>());
+ return cInit;
+ }
+
+ public Script.KernelID getKernelID() { return s.getKernelID_shadowsKernel(); }
+
+ public void forEach(Allocation in, Allocation out) { s.forEach_shadowsKernel(in, out); }
+
+ private ScriptC_shadows_f s;
+ private ScriptGroup2.Closure cInit;
+ }
+
+ class VibranceFilter extends FilterBase {
+ public VibranceFilter(RenderScript RS) { s = new ScriptC_vibrance_f(RS); }
+
+ public void init() {}
+
+ public ScriptGroup2.Closure prepInit(ScriptGroup2.Builder b) { return null; }
+
+ public Script.KernelID getKernelID() { return s.getKernelID_vibranceKernel(); }
+
+ public void forEach(Allocation in, Allocation out) { s.forEach_vibranceKernel(in, out); }
+
+ private ScriptC_vibrance_f s;
+ }
+
+ class VignetteFilter extends FilterBase {
+ public VignetteFilter(RenderScript RS) { s = new ScriptC_vignette_approx_relaxed_f(RS); }
+ private final float center_x = 0.5f;
+ private final float center_y = 0.5f;
+ private final float scale = 0.5f;
+ private final float shade = 0.5f;
+ private final float slope = 20.0f;
+ private ScriptGroup2.Closure cInit;
+
+ public void init() {
+ s.invoke_init_vignette(
+ mInPixelsAllocation.getType().getX(),
+ mInPixelsAllocation.getType().getY(), center_x,
+ center_y, scale, shade, slope);
+ }
+
+ public ScriptGroup2.Closure prepInit(ScriptGroup2.Builder b) {
+ cInit = b.addInvoke(s.getInvokeID_init_vignette(),
+ new Object[] {
+ new Integer(mInPixelsAllocation.getType().getX()),
+ new Integer(mInPixelsAllocation.getType().getY()),
+ new Float(center_x),
+ new Float(center_y),
+ new Float(scale), new Float(shade), new Float(slope) },
+ new HashMap<Script.FieldID, Object>());
+ return cInit;
+ }
+
+ public Script.KernelID getKernelID() { return s.getKernelID_vignette(); }
+
+ public void forEach(Allocation in, Allocation out) { s.forEach_vignette(in, out); }
+
+ private ScriptC_vignette_approx_relaxed_f s;
+ }
+
+ public final static Class[] mFilterClasses = {
+ ColorMatrixFilter.class,
+ ContrastFilter.class,
+ ExposureFilter.class,
+ FisheyeFilter.class,
+ GreyFilter.class,
+ LevelsFilter.class,
+ ShadowsFilter.class,
+ VibranceFilter.class,
+ VignetteFilter.class
+ };
+ private FilterInterface[] mFilters;
+ private int[] mIndices;
+
+ ScriptC_uc4tof4 s_uc2f;
+ ScriptC_f4touc4 s_f2uc;
+
+ private Allocation[] mScratchPixelsAllocation = new Allocation[2];
+ private ScriptGroup mGroup;
+ private ScriptGroup2 mGroup2;
+
+ private int mWidth;
+ private int mHeight;
+ private int mMode;
+
+ public static final int EMULATED = 0;
+ public static final int NATIVE2 = 1;
+ public static final int NATIVE1 = 2;
+ public static final int MANUAL = 3;
+
+ public Filters(int mode, int[] filter) {
+ mMode = mode;
+ mIndices = new int[filter.length];
+ System.arraycopy(filter, 0, mIndices, 0, filter.length);
+ mFilters = new FilterInterface[filter.length+2];
+ }
+
+ public void createTest(android.content.res.Resources res) {
+ s_uc2f = new ScriptC_uc4tof4(mRS);
+ s_f2uc = new ScriptC_f4touc4(mRS);
+ for (int i = 0; i < mIndices.length; i++) {
+ try {
+ /*
+ Constructor[] constructors = mFilterClasses[mIndices[i]].getConstructors();
+ for (Constructor ctr : constructors) {
+ Log.i("Filters", "constructor " + ctr);
+ }
+ */
+ Constructor constructor =
+ // mFilterClasses[i].getConstructor(new Class[]{ RenderScript.class });
+ //mFilterClasses[i].getConstructor(RenderScript.class);
+ mFilterClasses[mIndices[i]].getConstructors()[0];
+ try {
+ mFilters[i] = (FilterInterface)constructor.newInstance(this, mRS);
+ } catch (Exception e) {
+ Log.e("Filters", "newInstance caught " + e);
+ System.exit(-2);
+ }
+ mFilters[i].init();
+ } catch (Exception e) {
+ Log.e("Filters", "getConstructor caught " + e + " for " +
+ mFilterClasses[mIndices[i]].getName());
+ System.exit(-1);
+ }
+
+ }
+
+ mWidth = mInPixelsAllocation.getType().getX();
+ mHeight = mInPixelsAllocation.getType().getY();
+
+ Type.Builder tb = new Type.Builder(mRS, Element.F32_4(mRS));
+ tb.setX(mWidth);
+ tb.setY(mHeight);
+ Type connect = tb.create();
+
+ switch (mMode) {
+ case NATIVE1:
+ ScriptGroup.Builder b = new ScriptGroup.Builder(mRS);
+ b.addKernel(s_uc2f.getKernelID_uc4tof4());
+ b.addKernel(mFilters[0].getKernelID());
+ b.addConnection(connect, s_uc2f.getKernelID_uc4tof4(),
+ mFilters[0].getKernelID());
+
+ for (int i = 0; i < mIndices.length; i++) {
+ b.addKernel(mFilters[i].getKernelID());
+ b.addConnection(connect, mFilters[i-1].getKernelID(),
+ mFilters[i].getKernelID());
+ }
+
+ b.addKernel(s_f2uc.getKernelID_f4touc4());
+ b.addConnection(mOutPixelsAllocation.getType(),
+ mFilters[0].getKernelID(), s_f2uc.getKernelID_f4touc4());
+
+ mGroup = b.create();
+ break;
+ case NATIVE2: {
+ ScriptGroup2.Builder b2 = new ScriptGroup2.Builder(mRS);
+
+ for (int i = 0; i < mIndices.length; i++) {
+ mFilters[i].prepInit(b2);
+ }
+
+ ScriptGroup2.UnboundValue in = b2.addInput();
+
+ HashMap<Script.FieldID, Object> emptyMap =
+ new HashMap<Script.FieldID, Object>();
+
+ ScriptGroup2.Closure c = b2.addKernel(s_uc2f.getKernelID_uc4tof4(),
+ connect, new Object[]{ in }, emptyMap);
+
+ for (int i = 0; i < mIndices.length; i++) {
+// c = b2.addKernel(mFilters[i].getKernelID(), connect,
+// new Object[]{ c.getReturn() }, emptyMap);
+ c = mFilters[i].asyncLaunch(b2, c.getReturn(), connect);
+ }
+
+ c = b2.addKernel(s_f2uc.getKernelID_f4touc4(),
+ mOutPixelsAllocation.getType(),
+ new Object[]{ c.getReturn() }, emptyMap);
+
+ mGroup2 = b2.create(c.getReturn());
+ }
+ break;
+ case EMULATED:
+ mScratchPixelsAllocation[0] = Allocation.createTyped(mRS, connect);
+ mScratchPixelsAllocation[1] = Allocation.createTyped(mRS, connect);
+ break;
+ }
+ }
+
+ public void runTest() {
+ switch (mMode) {
+ case NATIVE1:
+ // mGroup.setInput(mFilters[0].getKernelID(), mInPixelsAllocation);
+ mGroup.setInput(s_uc2f.getKernelID_uc4tof4(), mInPixelsAllocation);
+ // mGroup.setOutput(mFilters[mIndices.length - 1].getKernelID(), mOutPixelsAllocation);
+ mGroup.setOutput(s_f2uc.getKernelID_f4touc4(), mOutPixelsAllocation);
+ mGroup.execute();
+ break;
+ case NATIVE2:
+ mOutPixelsAllocation = (Allocation)mGroup2.execute(mInPixelsAllocation)[0];
+ break;
+ case EMULATED:
+ s_uc2f.forEach_uc4tof4(mInPixelsAllocation, mScratchPixelsAllocation[0]);
+ for (int i = 0; i < mIndices.length; i++) {
+ mFilters[i].forEach(mScratchPixelsAllocation[i % 2],
+ mScratchPixelsAllocation[(i+1) % 2]);
+ }
+ s_f2uc.forEach_f4touc4(mScratchPixelsAllocation[mIndices.length % 2],
+ mOutPixelsAllocation);
+ break;
+ }
+ }
+
+}
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/ScriptGroupTestActivity.java b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/ScriptGroupTestActivity.java
new file mode 100644
index 00000000..db32d658
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/ScriptGroupTestActivity.java
@@ -0,0 +1,342 @@
+/*
+ * 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.sgtest;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.view.SurfaceView;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.view.View;
+import android.util.Log;
+import android.renderscript.ScriptC;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Script;
+
+import android.os.Environment;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class ScriptGroupTestActivity extends Activity
+ implements SeekBar.OnSeekBarChangeListener {
+ private final String TAG = "Img";
+ public final String RESULT_FILE = "image_processing_result.csv";
+
+ RenderScript mRS;
+ Allocation mInPixelsAllocation;
+ Allocation mOutPixelsAllocation;
+
+ Bitmap mBitmapOut;
+
+ private Spinner mSpinner;
+
+ private TextView mBenchmarkResult;
+ private Spinner mModeSpinner;
+ private Spinner mTestSpinner1;
+ private Spinner mTestSpinner2;
+
+ private ImageView mDisplayView;
+
+ private boolean mDoingBenchmark;
+
+ private TestBase mTest;
+ private int mRunCount;
+
+ public void updateDisplay() {
+ mHandler.sendMessage(Message.obtain());
+ }
+
+ private Handler mHandler = new Handler() {
+ // Allow the filter to complete without blocking the UI
+ // thread. When the message arrives that the op is complete
+ // we will either mark completion or start a new filter if
+ // more work is ready. Either way, display the result.
+ @Override
+ public void handleMessage(Message msg) {
+ boolean doTest = false;
+ synchronized(this) {
+ if (mRS == null) {
+ return;
+ }
+ mTest.updateBitmap(mBitmapOut);
+ mDisplayView.invalidate();
+ if (mRunCount > 0) {
+ mRunCount--;
+ if (mRunCount > 0) {
+ doTest = true;
+ }
+ }
+
+ if (doTest) {
+ mTest.runTestSendMessage();
+ }
+ }
+ }
+
+ };
+
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ }
+
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+
+ void changeTest(int pos1, int pos2, int mode) {
+ if (mTest != null) {
+ mTest.destroy();
+ }
+
+ final int[] index = new int[] { pos1, pos2 };
+ mTest = new Filters(mode, index);
+
+ mTest.createBaseTest(this);
+
+ mTest.runTest();
+ updateDisplay();
+ mBenchmarkResult.setText("Result: not run");
+ }
+
+ String getFilterName(int pos) {
+ return Filters.mFilterClasses[pos].getSimpleName();
+ }
+
+ String[] getFilterNames() {
+ ArrayList<String> list = new ArrayList<String>();
+ final int n = Filters.mFilterClasses.length;
+ for (int i = 0; i < n; i++) {
+ list.add(getFilterName(i));
+ }
+ return list.toArray(new String[0]);
+ }
+
+ void setupTests() {
+ String[] names = getFilterNames();
+ mModeSpinner.setAdapter(new ArrayAdapter<String>(
+ this, R.layout.spinner_layout, new String[] {"emulated", "native"}));
+ mTestSpinner1.setAdapter(new ArrayAdapter<String>(
+ this, R.layout.spinner_layout, names));
+ mTestSpinner2.setAdapter(new ArrayAdapter<String>(
+ this, R.layout.spinner_layout, names));
+ }
+
+ private AdapterView.OnItemSelectedListener mModeSpinnerListener =
+ new AdapterView.OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+ changeTest(
+ mTestSpinner1.getSelectedItemPosition(),
+ mTestSpinner2.getSelectedItemPosition(),
+ pos);
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ }
+ };
+
+ private AdapterView.OnItemSelectedListener mTestSpinner1Listener =
+ new AdapterView.OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+ changeTest(pos, mTestSpinner2.getSelectedItemPosition(),
+ mModeSpinner.getSelectedItemPosition());
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ }
+ };
+
+ private AdapterView.OnItemSelectedListener mTestSpinner2Listener =
+ new AdapterView.OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+ changeTest(mTestSpinner1.getSelectedItemPosition(), pos,
+ mModeSpinner.getSelectedItemPosition());
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ }
+ };
+
+ void init() {
+ mRS = RenderScript.create(this);
+ mInPixelsAllocation = Allocation.createFromBitmapResource(
+ mRS, getResources(), R.drawable.img1600x1067);
+ mBitmapOut = Bitmap.createBitmap(mInPixelsAllocation.getType().getX(),
+ mInPixelsAllocation.getType().getY(),
+ Bitmap.Config.ARGB_8888);
+ mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut);
+
+ mDisplayView = (ImageView) findViewById(R.id.display);
+ mDisplayView.setImageBitmap(mBitmapOut);
+
+ mModeSpinner = (Spinner) findViewById(R.id.modeselection);
+ mModeSpinner.setOnItemSelectedListener(mModeSpinnerListener);
+ mTestSpinner1 = (Spinner) findViewById(R.id.filterselection);
+ mTestSpinner1.setOnItemSelectedListener(mTestSpinner1Listener);
+ mTestSpinner2 = (Spinner) findViewById(R.id.filter2selection);
+ mTestSpinner2.setOnItemSelectedListener(mTestSpinner2Listener);
+
+ mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
+ mBenchmarkResult.setText("Result: not run");
+
+ setupTests();
+ changeTest(0, 0, 0);
+ }
+
+ void cleanup() {
+ synchronized(this) {
+ RenderScript rs = mRS;
+ mRS = null;
+ while(mDoingBenchmark) {
+ try {
+ Thread.sleep(1, 0);
+ } catch(InterruptedException e) {
+ }
+
+ }
+ rs.destroy();
+ }
+
+ mInPixelsAllocation = null;
+ mOutPixelsAllocation = null;
+ mBitmapOut = null;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ init();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ cleanup();
+ }
+
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ if (null == mRS) {
+ init();
+ }
+ }
+
+ // button hook
+ public void benchmark(View v) {
+ float t = getBenchmark();
+ //long javaTime = javaFilter();
+ //mBenchmarkResult.setText("RS: " + t + " ms Java: " + javaTime + " ms");
+ mBenchmarkResult.setText("Result: " + t + " ms");
+ Log.v(TAG, "getBenchmark: Renderscript frame time core ms " + t);
+ }
+
+ public void benchmark_all(View v) {
+ // write result into a file
+ File externalStorage = Environment.getExternalStorageDirectory();
+ if (!externalStorage.canWrite()) {
+ Log.v(TAG, "sdcard is not writable");
+ return;
+ }
+ File resultFile = new File(externalStorage, RESULT_FILE);
+ resultFile.setWritable(true, false);
+ try {
+ BufferedWriter rsWriter = new BufferedWriter(new FileWriter(resultFile));
+ Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath());
+ final int n = Filters.mFilterClasses.length;
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < n; j++) {
+ for (int k = 0; k < 2; k++) {
+ changeTest(i, j, k);
+ float t = getBenchmark();
+ String tn = getFilterName(i) + "-" + getFilterName(j);
+ if (k == 0) {
+ tn += " (emulated)";
+ } else {
+ tn += " (native)";
+ }
+ String s = new String("" + tn.toString() + ", " + t);
+ rsWriter.write(s + "\n");
+ Log.v(TAG, "Test " + s + "ms\n");
+ }
+ }
+ }
+ rsWriter.close();
+ } catch (IOException e) {
+ Log.v(TAG, "Unable to write result file " + e.getMessage());
+ }
+ changeTest(0, 0, 0);
+ Log.v(TAG, "result file:"+resultFile.getAbsolutePath());
+ }
+
+
+
+ // For benchmark test
+ public float getBenchmark() {
+ if (mRS == null) {
+ return 0;
+ }
+ mDoingBenchmark = true;
+
+ mTest.setupBenchmark();
+ long result = 0;
+
+ //Log.v(TAG, "Warming");
+ long t = java.lang.System.currentTimeMillis() + 250;
+ do {
+ mTest.runTest();
+ mTest.finish();
+ } while (t > java.lang.System.currentTimeMillis());
+
+ //Log.v(TAG, "Benchmarking");
+ int ct = 0;
+ t = java.lang.System.currentTimeMillis();
+ do {
+ mTest.runTest();
+ mTest.finish();
+ ct++;
+ } while ((t+1000) > java.lang.System.currentTimeMillis());
+ t = java.lang.System.currentTimeMillis() - t;
+ float ft = (float)t;
+ ft /= ct;
+
+ mTest.exitBenchmark();
+ mDoingBenchmark = false;
+
+ return ft;
+ }
+}
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/TestBase.java b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/TestBase.java
new file mode 100644
index 00000000..86f225c5
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/TestBase.java
@@ -0,0 +1,109 @@
+/*
+ * 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.sgtest;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.graphics.Bitmap;
+import android.renderscript.ScriptC;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Script;
+import android.view.SurfaceView;
+import android.view.SurfaceHolder;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import android.view.View;
+import android.util.Log;
+import java.lang.Math;
+import android.widget.Spinner;
+
+public class TestBase {
+ protected final String TAG = "Img";
+
+ protected RenderScript mRS;
+ protected Allocation mInPixelsAllocation;
+ // protected Allocation mInPixelsAllocation2;
+ protected Allocation mOutPixelsAllocation;
+ protected ScriptGroupTestActivity act;
+
+ private class MessageProcessor extends RenderScript.RSMessageHandler {
+ ScriptGroupTestActivity mAct;
+
+ MessageProcessor(ScriptGroupTestActivity act) {
+ mAct = act;
+ }
+
+ public void run() {
+ mAct.updateDisplay();
+ }
+ }
+
+ public boolean onSpinnerSetup(Spinner s) {
+ s.setVisibility(View.INVISIBLE);
+ return false;
+ }
+
+ public final void createBaseTest(ScriptGroupTestActivity ipact) {
+ act = ipact;
+ mRS = ipact.mRS;
+ mRS.setMessageHandler(new MessageProcessor(act));
+
+ mInPixelsAllocation = ipact.mInPixelsAllocation;
+ // mInPixelsAllocation2 = ipact.mInPixelsAllocation2;
+ mOutPixelsAllocation = ipact.mOutPixelsAllocation;
+
+ createTest(act.getResources());
+ }
+
+ // Must override
+ public void createTest(android.content.res.Resources res) {
+ }
+
+ // Must override
+ public void runTest() {
+ }
+
+ final public void runTestSendMessage() {
+ runTest();
+ mRS.sendMessage(0, null);
+ }
+
+ public void finish() {
+ mRS.finish();
+ }
+
+ public void destroy() {
+ mRS.setMessageHandler(null);
+ }
+
+ public void updateBitmap(Bitmap b) {
+ mOutPixelsAllocation.copyTo(b);
+ }
+
+ // Override to configure specific benchmark config.
+ public void setupBenchmark() {
+ }
+
+ // Override to reset after benchmark.
+ public void exitBenchmark() {
+ }
+}
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/colormatrix_f.rs b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/colormatrix_f.rs
new file mode 100644
index 00000000..2efa9e39
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/colormatrix_f.rs
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+// #pragma rs_fp_relaxed
+
+static rs_matrix4x4 Mat = {
+ {
+1.0f, 0, 0, 0,
+0.2f, 0.9f, 0.2f, 0,
+0, 0, 1.0f, 0,
+0, 0, 0, 1.0f,
+ }
+};
+
+/*
+void init() {
+ rsMatrixLoadIdentity(&Mat);
+}
+*/
+
+void setMatrix(rs_matrix4x4 m) {
+ Mat = m;
+}
+
+float4 RS_KERNEL colormatrix(float4 in) {
+ return rsMatrixMultiply(&Mat, in);
+}
+
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/contrast_f.rs b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/contrast_f.rs
new file mode 100644
index 00000000..ab85f1ed
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/contrast_f.rs
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+// #pragma rs_fp_relaxed
+
+static float brightM = 1.4142136f;
+static float brightC = -50.948268f;
+
+/*
+void setBright(float v) {
+ brightM = pow(2.f, v / 100.f);
+ brightC = 127.f - brightM * 127.f;
+}
+*/
+
+float4 RS_KERNEL contrast(float4 in) {
+ return in * brightM + brightC;
+}
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/exposure_f.rs b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/exposure_f.rs
new file mode 100644
index 00000000..e242c5f1
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/exposure_f.rs
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+// #pragma rs_fp_relaxed
+
+static float bright = 1.2439024f;
+
+/*
+void setBright(float v) {
+ bright = 255.f / (255.f - v);
+}
+*/
+
+float4 RS_KERNEL exposure(float4 in)
+{
+ return in * bright;
+}
+
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/f4touc4.rs b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/f4touc4.rs
new file mode 100644
index 00000000..4538e06d
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/f4touc4.rs
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+uchar4 RS_KERNEL f4touc4(float4 in) {
+ float4 f = clamp(in, 0.f, 255.f);
+ return convert_uchar4(f);
+}
+
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_f.rsh b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_f.rsh
new file mode 100644
index 00000000..055c0c4b
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_f.rsh
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+rs_allocation in_alloc;
+static rs_sampler sampler;
+
+static float2 center, neg_center, inv_dimensions, axis_scale;
+static float alpha, radius2, factor;
+
+void init_filter(uint32_t dim_x, uint32_t dim_y, float center_x, float center_y, float k,
+ rs_sampler sam) {
+ sampler = sam;
+ center.x = center_x;
+ center.y = center_y;
+ neg_center = -center;
+ inv_dimensions.x = 1.f / (float)dim_x;
+ inv_dimensions.y = 1.f / (float)dim_y;
+ alpha = k * 2.0f + 0.75f;
+
+ axis_scale = (float2)1.f;
+ if (dim_x > dim_y)
+ axis_scale.y = (float)dim_y / (float)dim_x;
+ else
+ axis_scale.x = (float)dim_x / (float)dim_y;
+
+ const float bound2 = 0.25f * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
+ const float bound = sqrt(bound2);
+ const float radius = 1.15f * bound;
+ radius2 = radius*radius;
+ const float max_radian = M_PI_2 - atan(alpha / bound * sqrt(radius2 - bound2));
+ factor = bound / max_radian;
+}
+
+float4 __attribute__((kernel)) fisheye(uint32_t x, uint32_t y) {
+ // Convert x and y to floating point coordinates with center as origin
+ const float2 inCoord = {(float)x, (float)y};
+ const float2 coord = mad(inCoord, inv_dimensions, neg_center);
+ const float2 scaledCoord = axis_scale * coord;
+ const float dist2 = scaledCoord.x*scaledCoord.x + scaledCoord.y*scaledCoord.y;
+ const float inv_dist = half_rsqrt(dist2);
+ const float radian = M_PI_2 - atan((alpha * half_sqrt(radius2 - dist2)) * inv_dist);
+ const float scalar = radian * factor * inv_dist;
+ const float2 new_coord = mad(coord, scalar, center);
+ const float4 fout = rsSample(in_alloc, sampler, new_coord);
+ return fout;
+}
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_relaxed_f.rs b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_relaxed_f.rs
new file mode 100644
index 00000000..27a5eb25
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/fisheye_approx_relaxed_f.rs
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+#include "fisheye_approx_f.rsh"
+
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/greyscale_f.rs b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/greyscale_f.rs
new file mode 100644
index 00000000..c42e1865
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/greyscale_f.rs
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+// #pragma rs_fp_relaxed
+
+const static float4 gMonoMult = {0.299f, 0.587f, 0.114f, 0.0f};
+
+float4 RS_KERNEL greyscale(float4 in) {
+ return dot(in, gMonoMult);
+}
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/ip.rsh b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/ip.rsh
new file mode 100644
index 00000000..eb3e84d5
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/ip.rsh
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2013 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.sgtest)
+
+
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/levels_f.rsh b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/levels_f.rsh
new file mode 100644
index 00000000..270e977d
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/levels_f.rsh
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+float inBlack;
+float outBlack;
+float inWMinInB;
+float outWMinOutB;
+float overInWMinInB;
+rs_matrix3x3 colorMat;
+/*
+uchar4 __attribute__((kernel)) root(uchar4 in) {
+ uchar4 out;
+ float3 pixel = convert_float4(in).rgb;
+ pixel = rsMatrixMultiply(&colorMat, pixel);
+ pixel = clamp(pixel, 0.f, 255.f);
+ pixel = (pixel - inBlack) * overInWMinInB;
+ pixel = pixel * outWMinOutB + outBlack;
+ pixel = clamp(pixel, 0.f, 255.f);
+ out.xyz = convert_uchar3(pixel);
+ out.w = 0xff;
+ return out;
+}
+*/
+
+void initialize(float inBlack_, float outBlack_, float inWMinInB_, float outWMinOutB_,
+ float overInWMinInB_, rs_matrix3x3 colorMat_) {
+ inBlack = inBlack_;
+ outBlack = outBlack_;
+ inWMinInB = inWMinInB_;
+ outWMinOutB = outWMinOutB_;
+ overInWMinInB = overInWMinInB_;
+ colorMat = colorMat_;
+}
+
+float4 __attribute__((kernel)) levels_v4(float4 in) {
+ float4 pixel;
+ pixel.rgb = rsMatrixMultiply(&colorMat, in.rgb);
+ pixel = clamp(pixel, 0.f, 255.f);
+ pixel = (pixel - inBlack) * overInWMinInB;
+ pixel = pixel * outWMinOutB + outBlack;
+ return pixel;
+}
+
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/levels_relaxed_f.rs b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/levels_relaxed_f.rs
new file mode 100644
index 00000000..14af0735
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/levels_relaxed_f.rs
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+#include "levels_f.rsh"
+
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/shadows_f.rs b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/shadows_f.rs
new file mode 100644
index 00000000..4ae6cea1
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/shadows_f.rs
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+static float shadowFilterMap[] = {
+ -0.00591f, 0.0001f,
+ 1.16488f, 0.01668f,
+ -0.18027f, -0.06791f,
+ -0.12625f, 0.09001f,
+ 0.15065f, -0.03897f
+};
+
+static float poly[] = {
+ 0.f, 0.f,
+ 0.f, 0.f,
+ 0.f
+};
+
+static const int ABITS = 4;
+static const int HSCALE = 256;
+static const int k1=255 << ABITS;
+static const int k2=HSCALE << ABITS;
+
+static float fastevalPoly(float *poly,int n, float x){
+
+ float f =x;
+ float sum = poly[0]+poly[1]*f;
+ int i;
+ for (i = 2; i < n; i++) {
+ f*=x;
+ sum += poly[i]*f;
+ }
+ return sum;
+}
+
+static ushort3 rgb2hsv( float4 rgb)
+{
+ int iMin,iMax,chroma;
+
+ int ri = rgb.r;
+ int gi = rgb.g;
+ int bi = rgb.b;
+ short rv,rs,rh;
+
+ if (ri > gi) {
+ iMax = max (ri, bi);
+ iMin = min (gi, bi);
+ } else {
+ iMax = max (gi, bi);
+ iMin = min (ri, bi);
+ }
+
+ chroma = iMax - iMin;
+ // set value
+ rv = (short)( iMax << ABITS);
+
+ // set saturation
+ if (rv == 0)
+ rs = 0;
+ else
+ rs = (short)((k1*chroma)/iMax);
+
+ // set hue
+ if (rs == 0)
+ rh = 0;
+ else {
+ if ( ri == iMax ) {
+ rh = (short)( (k2*(6*chroma+gi - bi))/(6*chroma));
+ if (rh >= k2) rh -= k2;
+ } else if (gi == iMax)
+ rh = (short)( (k2*(2*chroma+bi - ri ))/(6*chroma));
+ else // (bi == iMax )
+ rh = (short)( (k2*(4*chroma+ri - gi ))/(6*chroma));
+ }
+
+ ushort3 out;
+ out.x = rv;
+ out.y = rs;
+ out.z = rh;
+ return out;
+}
+
+static float4 hsv2rgb(ushort3 hsv)
+{
+ int ABITS = 4;
+ int HSCALE = 256;
+ int m;
+ int H,X,ih,is,iv;
+ int k1=255<<ABITS;
+ int k2=HSCALE<<ABITS;
+ int k3=1<<(ABITS-1);
+ int rr=0;
+ int rg=0;
+ int rb=0;
+ short cv = hsv.x;
+ short cs = hsv.y;
+ short ch = hsv.z;
+
+ // set chroma and min component value m
+ //chroma = ( cv * cs )/k1;
+ //m = cv - chroma;
+ m = ((int)cv*(k1 - (int)cs ))/k1;
+
+ // chroma == 0 <-> cs == 0 --> m=cv
+ if (cs == 0) {
+ rb = ( rg = ( rr =( cv >> ABITS) ));
+ } else {
+ ih=(int)ch;
+ is=(int)cs;
+ iv=(int)cv;
+
+ H = (6*ih)/k2;
+ X = ((iv*is)/k2)*(k2- abs(6*ih- 2*(H>>1)*k2 - k2)) ;
+
+ // removing additional bits --> unit8
+ X=( (X+iv*(k1 - is ))/k1 + k3 ) >> ABITS;
+ m=m >> ABITS;
+
+ // ( chroma + m ) --> cv ;
+ cv=(short) (cv >> ABITS);
+ switch (H) {
+ case 0:
+ rr = cv;
+ rg = X;
+ rb = m;
+ break;
+ case 1:
+ rr = X;
+ rg = cv;
+ rb = m;
+ break;
+ case 2:
+ rr = m;
+ rg = cv;
+ rb = X;
+ break;
+ case 3:
+ rr = m;
+ rg = X;
+ rb = cv;
+ break;
+ case 4:
+ rr = X;
+ rg = m;
+ rb = cv;
+ break;
+ case 5:
+ rr = cv;
+ rg = m ;
+ rb = X;
+ break;
+ }
+ }
+
+ float4 rgb;
+
+ rgb.r = rr;
+ rgb.g = rg;
+ rgb.b = rb;
+
+ return rgb;
+}
+
+void prepareShadows(float scale) {
+ float s = (scale>=0) ? scale : scale / 5.f;
+ for (int i = 0; i < 5; i++) {
+ poly[i] = fastevalPoly(shadowFilterMap+i*2,2 , s);
+ }
+}
+
+float4 RS_KERNEL shadowsKernel(float4 in) {
+ ushort3 hsv = rgb2hsv(in);
+ float v = (fastevalPoly(poly, 5, hsv.x * (1.f / 4080.f)) * 4080.f);
+ hsv.x = (unsigned short) clamp(v, 0.f, 4080.f);
+ return hsv2rgb(hsv);
+}
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/uc4tof4.rs b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/uc4tof4.rs
new file mode 100644
index 00000000..5d08194c
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/uc4tof4.rs
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+float4 RS_KERNEL uc4tof4(uchar4 in) {
+ return convert_float4(in);
+}
+
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vibrance_f.rs b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vibrance_f.rs
new file mode 100644
index 00000000..663652cc
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vibrance_f.rs
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+// #pragma rs_fp_relaxed
+
+float vibrance = 50.0f;
+
+static const float Rf = 0.2999f;
+static const float Gf = 0.587f;
+static const float Bf = 0.114f;
+
+static const float Vib = 0.5f;
+
+float4 RS_KERNEL vibranceKernel(float4 in) {
+ int r = in.r;
+ int g = in.g;
+ int b = in.b;
+ float red = (r-max(g, b)) * (1.f / 256.f);
+ float S = (float)(Vib/(1+native_exp(-red*3)))+1;
+ float MS = 1.0f - S;
+ float Rt = Rf * MS;
+ float Gt = Gf * MS;
+ float Bt = Bf * MS;
+ int t = (r + g) >> 1;
+
+ float R = r;
+ float G = g;
+ float B = b;
+
+ float Rc = R * (Rt + S) + G * Gt + B * Bt;
+ float Gc = R * Rt + G * (Gt + S) + B * Bt;
+ float Bc = R * Rt + G * Gt + B * (Bt + S);
+
+ float4 o;
+ o.r = Rc;
+ o.g = Gc;
+ o.b = Bc;
+ o.a = 0xffffffff;
+ return o;
+}
+
+void prepareVibrance() {
+ // Vib = vibrance/100.f;
+}
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_f.rsh b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_f.rsh
new file mode 100644
index 00000000..32e879fc
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_f.rsh
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+static float2 neg_center, axis_scale, inv_dimensions;
+static float sloped_neg_range, sloped_inv_max_dist, shade, opp_shade;
+
+void init_vignette(uint32_t dim_x, uint32_t dim_y, float center_x, float center_y,
+ float desired_scale, float desired_shade, float desired_slope) {
+
+ neg_center.x = -center_x;
+ neg_center.y = -center_y;
+ inv_dimensions.x = 1.f / (float)dim_x;
+ inv_dimensions.y = 1.f / (float)dim_y;
+
+ axis_scale = (float2)1.f;
+ if (dim_x > dim_y)
+ axis_scale.y = (float)dim_y / (float)dim_x;
+ else
+ axis_scale.x = (float)dim_x / (float)dim_y;
+
+ const float max_dist = 0.5f * length(axis_scale);
+ sloped_inv_max_dist = desired_slope * 1.f/max_dist;
+
+ // Range needs to be between 1.3 to 0.6. When scale is zero then range is
+ // 1.3 which means no vignette at all because the luminousity difference is
+ // less than 1/256. Expect input scale to be between 0.0 and 1.0.
+ const float neg_range = 0.7f*sqrt(desired_scale) - 1.3f;
+ sloped_neg_range = exp(neg_range * desired_slope);
+
+ shade = desired_shade;
+ opp_shade = 1.f - desired_shade;
+}
+
+float4 __attribute__((kernel)) vignette(float4 in, uint32_t x, uint32_t y) {
+ // Convert x and y to floating point coordinates with center as origin
+ const float2 inCoord = {(float)x, (float)y};
+ const float2 coord = mad(inCoord, inv_dimensions, neg_center);
+ const float sloped_dist_ratio = fast_length(axis_scale * coord) * sloped_inv_max_dist;
+ const float lumen = opp_shade + shade * half_recip(1.f + sloped_neg_range * native_exp(sloped_dist_ratio));
+ float4 fout;
+ fout.rgb = in.rgb * lumen;
+ fout.w = in.w;
+ return fout;
+}
+
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_relaxed_f.rs b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_relaxed_f.rs
new file mode 100644
index 00000000..b3e09568
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_approx_relaxed_f.rs
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+#include "ip.rsh"
+#pragma rs_fp_relaxed
+
+#include "vignette_approx_f.rsh"
+
diff --git a/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_f.rsh b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_f.rsh
new file mode 100644
index 00000000..f7831fdf
--- /dev/null
+++ b/java/tests/ScriptGroupTest/src/com/android/rs/sgtest/vignette_f.rsh
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+static float2 neg_center, axis_scale, inv_dimensions;
+static float sloped_neg_range, sloped_inv_max_dist, shade, opp_shade;
+
+void init_vignette(uint32_t dim_x, uint32_t dim_y, float center_x, float center_y,
+ float desired_scale, float desired_shade, float desired_slope) {
+
+ neg_center.x = -center_x;
+ neg_center.y = -center_y;
+ inv_dimensions.x = 1.f / (float)dim_x;
+ inv_dimensions.y = 1.f / (float)dim_y;
+
+ axis_scale = (float2)1.f;
+ if (dim_x > dim_y)
+ axis_scale.y = (float)dim_y / (float)dim_x;
+ else
+ axis_scale.x = (float)dim_x / (float)dim_y;
+
+ const float max_dist = 0.5f * length(axis_scale);
+ sloped_inv_max_dist = desired_slope * 1.f/max_dist;
+
+ // Range needs to be between 1.3 to 0.6. When scale is zero then range is
+ // 1.3 which means no vignette at all because the luminousity difference is
+ // less than 1/256. Expect input scale to be between 0.0 and 1.0.
+ const float neg_range = 0.7f*sqrt(desired_scale) - 1.3f;
+ sloped_neg_range = exp(neg_range * desired_slope);
+
+ shade = desired_shade;
+ opp_shade = 1.f - desired_shade;
+}
+
+float4 __attribute__((kernel)) root(float4 in, uint32_t x, uint32_t y) {
+ // Convert x and y to floating point coordinates with center as origin
+ const float2 inCoord = {(float)x, (float)y};
+ const float2 coord = mad(inCoord, inv_dimensions, neg_center);
+ const float sloped_dist_ratio = length(axis_scale * coord) * sloped_inv_max_dist;
+ const float lumen = opp_shade + shade / ( 1.0f + sloped_neg_range * exp(sloped_dist_ratio) );
+ float4 fout;
+ fout.rgb = in.rgb * lumen;
+ fout.w = in.w;
+}
+