diff options
author | Yang Ni <yangni@google.com> | 2015-02-03 16:32:57 -0800 |
---|---|---|
committer | Yang Ni <yangni@google.com> | 2015-03-11 20:01:04 +0000 |
commit | 5ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948 (patch) | |
tree | cb8501e52b07846f410cf21d51e4ac3cd741c421 /java/tests | |
parent | 062c287f573ecc06c38ee4295e5627e12c52ac3d (diff) | |
download | rs-5ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948.tar.gz |
Image Processing using the new Script Group API
Change-Id: I25daf8185d51ca37e124e5e30c4ec482ea9b86a5
Diffstat (limited to 'java/tests')
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 Binary files differnew file mode 100644 index 00000000..05d3ee20 --- /dev/null +++ b/java/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067.jpg diff --git a/java/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067b.jpg b/java/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067b.jpg Binary files differnew file mode 100644 index 00000000..aed0781e --- /dev/null +++ b/java/tests/ScriptGroupTest/res/drawable-nodpi/img1600x1067b.jpg 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; +} + |